mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-12 09:08:23 +03:00
Add Streamer Mode with -censor option
This introduces "Streamer Mode" to mosaic specified NSFW images, making the game suitable for streaming or public viewing. This feature is enabled via the '-censor <file>' command-line option, which takes a file containing a list of image numbers to be filtered.
This commit is contained in:
@@ -60,6 +60,14 @@ and examine or modify game variables. There are two ways to use the debugger:
|
||||
launch the debugger with a console interface. Type `help` to see a list of
|
||||
available commands.
|
||||
|
||||
### Streamer Mode
|
||||
|
||||
xsystem35 introduces a "Streamer Mode" to make playing games with NSFW content
|
||||
safer for streaming or public viewing. When enabled with the `-censor <file>`
|
||||
option, images specified in the provided file will be automatically mosaiced.
|
||||
|
||||
The `misc/censor/` directory contains example censor list files for some games.
|
||||
|
||||
## Installation
|
||||
|
||||
Prebuilt packages for Windows and Android can be downloaded from the
|
||||
|
||||
@@ -49,6 +49,11 @@ finds System 3.x game files (*.ALD) from the current directory.
|
||||
Suppress text hook on specified scenario pages. _list_ is a comma-separated
|
||||
list of page numbers. Used to suppress system messages, etc.
|
||||
|
||||
*-censor* _file_::
|
||||
Enable Streamer Mode, which mosaics specific images to make them safe for
|
||||
streaming. The _file_ is a text file containing a list of image numbers
|
||||
to censor, one per line. Lines starting with '#' are treated as comments.
|
||||
|
||||
*-renderer* _name_::
|
||||
Use the SDL rendering driver named _name_.
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Censor Lists for Streamer Mode
|
||||
|
||||
This directory contains sample censor lists for various games, intended for use
|
||||
with xsystem35's Streamer Mode.
|
||||
|
||||
## Usage
|
||||
|
||||
To use a censor list, specify its path with the `-censor` command-line option
|
||||
or in your `.xsys35rc` file. For example:
|
||||
|
||||
```bash
|
||||
xsystem35 -censor misc/censor/kichikuou.txt
|
||||
```
|
||||
|
||||
The list files contain image numbers (integers), one per line. Lines starting
|
||||
with `#` are treated as comments.
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions of censor lists for other games! If you have created
|
||||
a censor list that you'd like to share, please open a Pull Request.
|
||||
@@ -0,0 +1,164 @@
|
||||
# Censor list for 鬼畜王ランス (Kichikuou Rance)
|
||||
27
|
||||
70
|
||||
93
|
||||
101
|
||||
102
|
||||
103
|
||||
106
|
||||
107
|
||||
108
|
||||
109
|
||||
110
|
||||
111
|
||||
112
|
||||
113
|
||||
114
|
||||
115
|
||||
116
|
||||
117
|
||||
118
|
||||
119
|
||||
120
|
||||
121
|
||||
123
|
||||
124
|
||||
125
|
||||
126
|
||||
127
|
||||
128
|
||||
129
|
||||
130
|
||||
131
|
||||
132
|
||||
133
|
||||
134
|
||||
136
|
||||
137
|
||||
138
|
||||
139
|
||||
140
|
||||
141
|
||||
142
|
||||
143
|
||||
144
|
||||
145
|
||||
146
|
||||
147
|
||||
148
|
||||
149
|
||||
150
|
||||
151
|
||||
152
|
||||
153
|
||||
154
|
||||
155
|
||||
156
|
||||
157
|
||||
158
|
||||
160
|
||||
161
|
||||
162
|
||||
163
|
||||
164
|
||||
165
|
||||
166
|
||||
167
|
||||
168
|
||||
169
|
||||
171
|
||||
172
|
||||
174
|
||||
175
|
||||
176
|
||||
177
|
||||
178
|
||||
179
|
||||
180
|
||||
181
|
||||
182
|
||||
183
|
||||
184
|
||||
185
|
||||
186
|
||||
187
|
||||
188
|
||||
189
|
||||
190
|
||||
191
|
||||
193
|
||||
195
|
||||
196
|
||||
197
|
||||
198
|
||||
199
|
||||
200
|
||||
201
|
||||
203
|
||||
204
|
||||
205
|
||||
206
|
||||
207
|
||||
208
|
||||
209
|
||||
210
|
||||
214
|
||||
215
|
||||
216
|
||||
217
|
||||
218
|
||||
219
|
||||
221
|
||||
222
|
||||
224
|
||||
225
|
||||
226
|
||||
227
|
||||
228
|
||||
229
|
||||
230
|
||||
231
|
||||
232
|
||||
233
|
||||
234
|
||||
235
|
||||
239
|
||||
299
|
||||
300
|
||||
361
|
||||
362
|
||||
363
|
||||
375
|
||||
376
|
||||
377
|
||||
393
|
||||
422
|
||||
461
|
||||
466
|
||||
500
|
||||
501
|
||||
502
|
||||
503
|
||||
504
|
||||
505
|
||||
506
|
||||
507
|
||||
508
|
||||
509
|
||||
510
|
||||
511
|
||||
512
|
||||
513
|
||||
514
|
||||
515
|
||||
517
|
||||
844
|
||||
845
|
||||
846
|
||||
847
|
||||
848
|
||||
851
|
||||
852
|
||||
853
|
||||
854
|
||||
855
|
||||
+16
@@ -130,3 +130,19 @@ void *cache_foreach(cacher *id, int key) {
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void cache_clear(cacher *id) {
|
||||
cacheinfo *ic = id->top->next;
|
||||
cacheinfo *next;
|
||||
|
||||
while (ic != NULL) {
|
||||
next = ic->next;
|
||||
if (ic->data) {
|
||||
totalsize -= ic->size;
|
||||
id->free_(ic->data);
|
||||
}
|
||||
free(ic);
|
||||
ic = next;
|
||||
}
|
||||
id->top->next = NULL;
|
||||
}
|
||||
|
||||
@@ -46,5 +46,6 @@ typedef struct _cacher cacher;
|
||||
extern cacher *cache_new(void *delcallback);
|
||||
extern void cache_insert(cacher *id, int key, void *data, int size, int *in_use);
|
||||
extern void *cache_foreach(cacher *id, int key);
|
||||
extern void cache_clear(cacher *id);
|
||||
|
||||
#endif /* !__CASHE__ */
|
||||
|
||||
@@ -21,9 +21,14 @@
|
||||
*/
|
||||
/* $Id: cg.c,v 1.12 2001/09/16 15:59:11 chikama Exp $ */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "nact.h"
|
||||
@@ -41,6 +46,9 @@
|
||||
#include "filecheck.h"
|
||||
#include "cache.h"
|
||||
|
||||
static int *censor_list; // sorted list of cg numbers
|
||||
static int censor_list_size;
|
||||
|
||||
/* VSPのパレット展開バンク */
|
||||
int cg_vspPB;
|
||||
/* cg,palette 展開フラグ (funciotn flag) */
|
||||
@@ -50,6 +58,8 @@ int *cg_loadCountVar;
|
||||
/* Brightness (PD command) */
|
||||
int cg_brightness;
|
||||
|
||||
#define MOSAIC_SIZE 16
|
||||
|
||||
#define GCMD_EXTRACTCG(c) ((c) & 0x01)
|
||||
#define GCMD_SET_PALETTE(c) ((c) & 0x02)
|
||||
#define GCMD_LOAD_PALETTE(c) ((c) & 0x04)
|
||||
@@ -69,6 +79,46 @@ static void clear_display_loc();
|
||||
static void display_cg(cgdata *cg, int x, int y, int sprite_color, bool alpha_blend);
|
||||
static cgdata *loader(int no);
|
||||
|
||||
static int compare_integers(const void *a, const void *b) {
|
||||
int int_a = *(const int *)a;
|
||||
int int_b = *(const int *)b;
|
||||
return (int_a > int_b) - (int_a < int_b);
|
||||
}
|
||||
|
||||
static bool is_censored_cg(int no) {
|
||||
no += 1; // CG numbers are 1-based.
|
||||
if (!censor_list)
|
||||
return false;
|
||||
return bsearch(&no, censor_list, censor_list_size, sizeof(int), compare_integers) != NULL;
|
||||
}
|
||||
|
||||
static void cg_mosaic(cgdata *cg) {
|
||||
Uint32 format;
|
||||
switch (cg->depth) {
|
||||
case 8:
|
||||
format = SDL_PIXELFORMAT_INDEX8;
|
||||
break;
|
||||
case 16:
|
||||
format = SDL_PIXELFORMAT_RGB565;
|
||||
break;
|
||||
case 24:
|
||||
format = SDL_PIXELFORMAT_RGB24;
|
||||
break;
|
||||
default:
|
||||
SYSERROR("Unsupported cg depth %d", cg->depth);
|
||||
}
|
||||
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormatFrom(
|
||||
cg->pic, cg->width, cg->height, cg->depth, cg->width * (cg->depth / 8), format);
|
||||
SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(
|
||||
0, (cg->width + MOSAIC_SIZE - 1) / MOSAIC_SIZE, (cg->height + MOSAIC_SIZE - 1) / MOSAIC_SIZE, cg->depth, format);
|
||||
if (sf->format->palette)
|
||||
SDL_SetSurfacePalette(tmp, sf->format->palette);
|
||||
// NOTE: SDL_BlitScaled() does not support 8-bit surfaces.
|
||||
SDL_SoftStretch(sf, NULL, tmp, NULL);
|
||||
SDL_SoftStretch(tmp, NULL, sf, NULL);
|
||||
SDL_FreeSurface(tmp);
|
||||
SDL_FreeSurface(sf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Identify cg format
|
||||
@@ -230,8 +280,12 @@ static cgdata *loader(int no) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* insert to cache */
|
||||
|
||||
if (cg) {
|
||||
if (is_censored_cg(no)) {
|
||||
cg_mosaic(cg);
|
||||
}
|
||||
/* insert to cache */
|
||||
int size = cg->width * cg->height * (cg->depth / 8);
|
||||
cache_insert(cacheid, no, cg, size, NULL);
|
||||
}
|
||||
@@ -536,6 +590,10 @@ SDL_Surface *cg_load_as_sdlsurface(int no) {
|
||||
ald_freedata(dfile);
|
||||
if (!cg) return NULL;
|
||||
|
||||
if (is_censored_cg(no)) {
|
||||
cg_mosaic(cg);
|
||||
}
|
||||
|
||||
SDL_Surface *pic = type == ALCG_PMS16
|
||||
? SDL_CreateRGBSurfaceWithFormatFrom(cg->pic, cg->width, cg->height, 16, cg->width * 2, SDL_PIXELFORMAT_RGB565)
|
||||
: SDL_CreateRGBSurfaceWithFormatFrom(cg->pic, cg->width, cg->height, 24, cg->width * 3, SDL_PIXELFORMAT_RGB24);
|
||||
@@ -562,3 +620,60 @@ SDL_Surface *cg_load_as_sdlsurface(int no) {
|
||||
cgdata_free(cg);
|
||||
return sf;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
void load_censor_list(const char *path) {
|
||||
if (cacheid)
|
||||
cache_clear(cacheid);
|
||||
if (censor_list) {
|
||||
free(censor_list);
|
||||
censor_list = NULL;
|
||||
censor_list_size = 0;
|
||||
}
|
||||
if (!path || !*path)
|
||||
return;
|
||||
|
||||
FILE *fp = fopen(path, "r");
|
||||
if (!fp) {
|
||||
SYSERROR("failed to open censor list file %s", path);
|
||||
return;
|
||||
}
|
||||
|
||||
char line[256];
|
||||
int count = 0, cap = 256;
|
||||
censor_list = malloc(cap * sizeof(int));
|
||||
int line_no = 0;
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
line_no++;
|
||||
char *p = line;
|
||||
char *comment = strchr(p, '#');
|
||||
if (comment)
|
||||
*comment = '\0';
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
continue;
|
||||
|
||||
if (count >= cap) {
|
||||
cap *= 2;
|
||||
censor_list = realloc(censor_list, cap * sizeof(int));
|
||||
}
|
||||
char *endptr;
|
||||
censor_list[count++] = (int)strtol(p, &endptr, 10);
|
||||
|
||||
while (*endptr && isspace((unsigned char)*endptr))
|
||||
endptr++;
|
||||
if (*endptr != '\0')
|
||||
WARNING("invalid line %d in %s", line_no, path);
|
||||
}
|
||||
censor_list_size = count;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (censor_list_size > 0) {
|
||||
qsort(censor_list, censor_list_size, sizeof(int), compare_integers);
|
||||
} else {
|
||||
free(censor_list);
|
||||
censor_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ extern void cg_get_info(int no, SDL_Rect *info);
|
||||
extern void cg_clear_display_loc();
|
||||
extern void cgdata_free(cgdata *cg);
|
||||
extern struct SDL_Surface *cg_load_as_sdlsurface(int no);
|
||||
extern void load_censor_list(const char *path);
|
||||
|
||||
extern int cg_vspPB;
|
||||
extern int cg_fflg;
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "randMT.h"
|
||||
#include "ags.h"
|
||||
#include "font.h"
|
||||
#include "cg.h"
|
||||
#include "gfx.h"
|
||||
#include "event.h"
|
||||
#include "menu.h"
|
||||
@@ -114,6 +115,7 @@ static void sys35_usage(bool verbose) {
|
||||
puts(" -playlist file : load CD playlist from 'file'");
|
||||
puts(" -texthook mode : text hook mode. 'none' (default), 'print' or 'copy'");
|
||||
puts(" -texthook_suppress list : suppress text hook on specified pages");
|
||||
puts(" -censor file : mosaic images listed in 'file'");
|
||||
|
||||
puts(" -M? : select output midi methos");
|
||||
#ifdef ENABLE_MIDI_SDLMIXER
|
||||
@@ -254,6 +256,10 @@ static void sys35_ParseOption(int *argc, char **argv) {
|
||||
if (argv[i + 1] != NULL) {
|
||||
texthook_set_suppression_list(argv[i + 1]);
|
||||
}
|
||||
} else if (0 == strcmp(argv[i], "-censor")) {
|
||||
if (argv[i + 1] != NULL) {
|
||||
load_censor_list(argv[i + 1]);
|
||||
}
|
||||
} else if (0 == strncmp(argv[i], "-M", 2)) {
|
||||
int subdev = 0;
|
||||
if (argv[i][3] != '\0') {
|
||||
@@ -399,6 +405,12 @@ static void check_profile() {
|
||||
if (param) {
|
||||
texthook_set_suppression_list(param);
|
||||
}
|
||||
|
||||
/* Censor list for streamer mode */
|
||||
param = get_profile("censor");
|
||||
if (param) {
|
||||
load_censor_list(param);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
|
||||
@@ -105,6 +105,13 @@
|
||||
|
||||
#texthook_suppress: 7,11,15,16,17,18,23,24,32,33,197
|
||||
|
||||
# Censor list for Streamer Mode.
|
||||
# This mosaics images listed in the specified file, making them safe for
|
||||
# streaming or public viewing. The file should contain one image number
|
||||
# per line, with '#' treated as comments.
|
||||
|
||||
#censor: censor_list.txt
|
||||
|
||||
# Enables the ZB command (change the font weight). It is disabled by default
|
||||
# because it makes the text too bold with our default fonts.
|
||||
# This option is experimental and may be removed in the future. See
|
||||
|
||||
Reference in New Issue
Block a user