Compare commits

..
18 Commits
Author SHA1 Message Date
kichikuou 2c9079c875 Version 2.17.1 2026-01-10 16:13:16 +09:00
kichikuou 54b8d6c993 android/README.md: Add Obtainium installation instructions 2026-01-10 14:57:43 +09:00
kichikuou f2fe6b9724 SACT: Ctrl key cancels SACT.Wait and SACT.TimerWait
This fixes an issue where the roulette in Rance 5D could not be fast
forwarded using the Ctrl key.
2026-01-09 16:16:13 +09:00
kichikuou 38dc9a7b0b Refactor sacttimer.c 2026-01-09 13:14:48 +09:00
kichikuou d2ac3889b5 QE/LE: Handle for paths with subdirectories correctly
This resolves issues where saving to and loading from paths with
subdirectories (e.g., "Save\file.asd") would fail.

The original problems were:
 1. Writing failure: A path mismatch between directory creation in
    commandQE and file writing in fc_open.
 2. Loading failure: fc_search could not handle paths containing
    directory separators, preventing saved files in subdirectories from
    being found.

This commit addresses these issues with the following changes:
 - fc_open now automatically creates parent directories when writing a
   file.
 - fc_search is updated to support two modes:
     - It performs a case-insensitive search for simple filenames
       (preserving original behavior).
     - It performs a case-sensitive existence check for full paths.

Fixes #74.
2026-01-09 08:31:40 +09:00
kichikuou 0342141358 Add is_available function to CD-ROM devices
Now `SI 2` command returns zero if no audio track is available.
2025-11-28 10:45:24 +09:00
kichikuou 8806bc9545 Version 2.17.0 2025-11-09 22:27:45 +09:00
kichikuou 5e62405f17 Move patch/ to misc/patch/ 2025-11-09 22:26:15 +09:00
kichikuou 714c7d44b5 Android: Update SDL to 2.32.10 2025-11-09 22:08:54 +09:00
kichikuou 0f6d4e2343 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.
2025-11-09 11:47:13 +09:00
kichikuou f1536a801a QE/LE: Handle backslashes in filenames
Rance 5D uses filename `Save\\Rance5dSystem.asd`. This caused issues:

- On Windows, saving would fail if the `Save` directory did not exist.
- On other platforms, files were created with literal backslashes in
  their names.

This change addresses these problems by:

- In commandQE, normalizing backslashes to forward slashes in the path
  and ensuring that the target directory exists by calling mkdir_p().
- In commandLE, first attempting to load files with normalized forward
  slashes. If that fails, it retries with the original path (containing
  backslashes) for compatibility with older saves.
2025-11-06 11:05:23 +09:00
kichikuou ab372b7873 Unify old and new command implementations
Consolidate logic for parsing string arguments by introducing a
parameter to handle different terminators.
2025-11-06 09:39:51 +09:00
kichikuou 2c02f40dc4 Move uppercase commands from cmd2F.c to cmd<first_letter>.c 2025-11-06 09:39:46 +09:00
kichikuou a395366cf8 Version 2.16.1 2025-08-28 13:00:30 +09:00
kichikuou e416fc20d3 CI: Disable portmidi on mingw32
mingw-w64-i686-portmidi is no longer provided.
2025-08-28 12:47:02 +09:00
kichikuou 7d03fc6757 sactlog: Hold log text in UTF-8 2025-08-28 12:24:49 +09:00
kichikuou e3b8c90611 sactlog: Draw text using gfx_drawString()
This fixes #71. It was a regression by commit ec071d4.
2025-08-28 11:41:51 +09:00
kichikuou 361ca89016 Windows: #undef min / max in portab.h 2025-06-20 08:11:35 +09:00
49 changed files with 751 additions and 487 deletions
+3 -2
View File
@@ -15,7 +15,9 @@ jobs:
- sys: ucrt64
package: "xsystem35-64bit"
cmake_args: ""
deps: "cjson:p"
deps: >-
cjson:p
portmidi:p
defaults:
run:
shell: msys2 {0}
@@ -31,7 +33,6 @@ jobs:
SDL2_ttf:p
SDL2_mixer:p
libwebp:p
portmidi:p
${{ matrix.deps }}
- name: Checkout
+20 -7
View File
@@ -1,31 +1,44 @@
# Changelog
## 2.16.0 - 2024-06-13
## 2.17.1 - 2026-01-10
- Fixed an issue where Rance 5D could not save files on non-Windows systems.
- Improved fast-forward behavior using the Ctrl key in Rance 5D.
- The `SI 2` command now returns 0 if a playlist file is not provided.
## 2.17.0 - 2025-11-09
- Added "Streamer Mode" to mosaic specified (NSFW) images. This is enabled via the `-censor <file>` command-line option.
- Windows: Fixed an issue where Rance 5D could not save files if the `Save` directory did not exist.
## 2.16.1 - 2025-08-28
- Fixed text rendering issue in SACT log (#71)
- Windows: The 32-bit version no longer supports the portmidi MIDI backend
## 2.16.0 - 2025-06-13
- Fixed map tile color issue in Graymerca (#67)
- Windows: Implemented number input dialog for the `NI` command (#68)
- Android: Added "Clear Save Files" launcher menu command
## 2.15.1 - 2024-05-14
## 2.15.1 - 2025-05-14
- Fixed a text rendering issue in Rance 5D (#66)
## 2.15.0 - 2024-04-21
## 2.15.0 - 2025-04-21
- Fixed color palette bug introduced in v2.14.2.
- Fixed uncancellable message waiting mode.
- Android: "Install from ZIP" button is moved to the top-right option menu.
- Android: Improved extraction logic of track numbers from audio file names.
## 2.14.3 - 2024-04-01
## 2.14.3 - 2025-04-01
- Fixed build for big endian architectures.
## 2.14.2 - 2024-03-09
## 2.14.2 - 2025-03-09
- Android: Back button to exit the game (#50)
- Improved touch input usability in ママトト (#64)
## 2.14.1 - 2024-02-07
## 2.14.1 - 2025-02-07
- Fixed font selection and text decoration not working in selection menus.
- Fixed a graphic issue in DALK intro.
## 2.14.0 - 2024-01-09
## 2.14.0 - 2025-01-09
- New supported games: 俺の下であがけ and 楽園行.
- Windows: On Windows 10 version 1903 or above, now xsystem35 can handle
Japanese filenames correctly even if the system locale is not Japanese.
+1 -1
View File
@@ -5,7 +5,7 @@ set(CMAKE_C_STANDARD 99)
enable_testing()
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
set(XSYSTEM35_VERSION "2.16.0")
set(XSYSTEM35_VERSION "2.17.1")
include(CheckSymbolExists)
include(FetchContent)
+8
View File
@@ -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
+8
View File
@@ -6,6 +6,14 @@ Minimum supported Android version: 5.0
You can download prebuilt APKs
[here](https://github.com/kichikuou/xsystem35-sdl2/releases).
### Installing with Obtainium
Alternatively, you can install `xsystem35-sdl2` using [Obtainium](https://github.com/ImranR98/Obtainium). Obtainium will detect new releases and allow you to update the app directly.
1. Install Obtainium on your Android device.
2. Click the badge below to add the app to Obtainium:
[<img src="https://raw.githubusercontent.com/ImranR98/Obtainium/main/assets/graphics/badge_obtainium.png" alt="Get it on Obtainium" height="60">](https://apps.obtainium.imranr.dev/redirect?r=obtainium://app/%7B%22id%22%3A%22io.github.kichikuou.xsystem35%22%2C%22url%22%3A%22https%3A%2F%2Fgithub.com%2Fkichikuou%2Fxsystem35-sdl2%22%2C%22author%22%3A%22kichikuou%22%2C%22name%22%3A%22xsystem35%22%2C%22categories%22%3A%5B%22games%22%5D%7D)
## Usage
### Basic Usage
1. Create a ZIP file containing all the game files and BGM files (see
+2 -2
View File
@@ -16,8 +16,8 @@ android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 34
versionCode 35
versionName "2.16.0" + gitRevision()
versionCode 36
versionName "2.17.1" + gitRevision()
externalNativeBuild {
cmake {
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
+2 -2
View File
@@ -7,8 +7,8 @@ set(PROJECT_ROOT_DIR ../../..)
include(FetchContent)
FetchContent_Declare(
SDL
URL https://github.com/libsdl-org/SDL/releases/download/release-2.32.4/SDL2-2.32.4.tar.gz
URL_HASH SHA1=4fb68f43891ca4def414cc7cf0f3b2a053cb6aaf
URL https://github.com/libsdl-org/SDL/releases/download/release-2.32.10/SDL2-2.32.10.tar.gz
URL_HASH SHA1=ce98fa93e31836a751feca374ab28a0770b63c16
)
FetchContent_Declare(
SDL_ttf
@@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 32;
private static final int SDL_MICRO_VERSION = 4;
private static final int SDL_MICRO_VERSION = 10;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
+5
View File
@@ -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_.
+21
View File
@@ -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.
+164
View File
@@ -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
+7 -7
View File
@@ -1613,10 +1613,10 @@ static void TimerWait() {
int wTimerID = getCaliValue();
int wCount = getCaliValue();
while (wCount > stimer_get(wTimerID) && !nact->is_quit) {
sys_keywait(10, KEYWAIT_NONCANCELABLE);
}
int msec = (wCount - stimer_get(wTimerID)) * 10;
if (msec > 0)
sys_keywait(msec, KEYWAIT_CTRL_CANCELABLE);
TRACE("SACT.TimerWait %d,%d:", wTimerID, wCount);
}
@@ -1627,9 +1627,9 @@ static void TimerWait() {
*/
static void Wait() {
int wCount = getCaliValue();
sys_keywait(wCount*10, KEYWAIT_NONCANCELABLE);
sys_keywait(wCount * 10, KEYWAIT_CTRL_CANCELABLE);
TRACE("SACT.Wait %d:", wCount);
}
+1 -4
View File
@@ -249,9 +249,6 @@ struct _sact {
SDL_Rect updaterect; // 更新が必要なspriteの領域の和
// sact timer
stimer_t timer[65536];
// DnDに関するもの
sprite_t *draggedsp; // drag中のスプライト
bool dropped; // スプライトがドロップされたかどうか
@@ -281,7 +278,7 @@ struct _sact {
// バックログ
bool logging;
List *log;
List *log; // UTF-8 strings
};
typedef struct _sact sact_t;
+17 -19
View File
@@ -36,12 +36,13 @@
#include "nact.h"
#include "sact.h"
#include "sprite.h"
#include "drawtext.h"
#include "utfsjis.h"
#include "gfx.h"
#include "ags.h"
#include "font.h"
#define LOGMSG_LINES 6
static const char *logmsg_utf8[LOGMSG_LINES] = {
static char *logmsg[LOGMSG_LINES] = {
"\n",
"※バックログ操作方法※",
"[ESC]またはマウス右クリックでゲームに戻る",
@@ -56,7 +57,7 @@ static const char *logmsg_utf8[LOGMSG_LINES] = {
PageUP/Downで1ページ送り
*/
#define FONTSIZEINDEX 10
#define INDEX_FONTSIZE 10
#define FONTSIZE 20
#define LOGLINENUM (main_surface->h / FONTSIZE)
static int curline;
@@ -68,6 +69,10 @@ static void draw_log() {
char pinfo[256];
List *node;
#ifdef __EMSCRIPTEN__
load_mincho_font();
#endif
SDL_Surface *hline = SDL_CreateRGBSurfaceWithFormat(0, main_surface->w, 3, 32, SDL_PIXELFORMAT_RGB888);
SDL_FillRect(hline, NULL, SDL_MapRGB(hline->format, 255, 255, 255));
SDL_SetSurfaceBlendMode(hline, SDL_BLENDMODE_BLEND);
@@ -80,8 +85,8 @@ static void draw_log() {
// ページ位置情報
len = snprintf(pinfo, sizeof(pinfo) -1, "%d/%d", curline, list_length(sact.log));
dt_setfont(FONT_GOTHIC, FONTSIZEINDEX);
dt_drawtext_col(main_surface, main_surface->w - FONTSIZEINDEX *len /2, 0, pinfo, 255, 255, 255);
ags_setFont(FONT_GOTHIC, INDEX_FONTSIZE);
gfx_drawString(main_surface->w - INDEX_FONTSIZE * len / 2, 0, pinfo, 255);
// 表示始め位置
node = list_nth(sact.log, list_length(sact.log) - curline);
@@ -93,11 +98,11 @@ static void draw_log() {
SDL_BlitSurface(hline, NULL, main_surface, &(SDL_Rect){0, y + FONTSIZE/2, main_surface->w, 3});
} else {
if (cur < 6) {
dt_setfont(FONT_MINCHO, FONTSIZE);
ags_setFont(FONT_MINCHO, FONTSIZE);
} else {
dt_setfont(FONT_GOTHIC, FONTSIZE);
ags_setFont(FONT_GOTHIC, FONTSIZE);
}
dt_drawtext_col(main_surface, 0, y, str, 255, 255, 255);
gfx_drawString(0, y, str, 255);
}
y += FONTSIZE;
cur--;
@@ -113,13 +118,7 @@ bool sblog_start(void) {
if (sact.version < 120)
return false;
static char *logmsg[LOGMSG_LINES];
if (!logmsg[0]) {
for (int i = 0; i < LOGMSG_LINES; i++)
logmsg[i] = fromUTF8(logmsg_utf8[i]);
}
// 説明文章を追加
// Append instruction text
for (int i = 0; i < LOGMSG_LINES; i++)
sact.log = list_append(sact.log, logmsg[i]);
@@ -138,10 +137,9 @@ void sblog_end(void) {
SDL_FreeSurface(back);
// 説明文章を削除
// Remove instruction text
for (i = 0; i < LOGMSG_LINES; i++) {
node = list_last(sact.log);
sact.log = list_remove(sact.log, node->data);
sact.log = list_remove(sact.log, logmsg[i]);
}
}
+20 -21
View File
@@ -22,36 +22,35 @@
/* $Id: sacttimer.c,v 1.1 2003/04/22 16:29:52 chikama Exp $ */
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include "portab.h"
#include "sact.h"
#include "sacttimer.h"
#include "system.h"
#define MAX_TIMER 10
#define TICKS_PER_CENTISECOND 10
uint32_t ticks_base[MAX_TIMER];
/*
sact timer subsystem 初期化
*/
void stimer_init(void) {
stimer_reset(0, 0);
memset(ticks_base, 0, sizeof(ticks_base));
}
// 指定IDのタイマーのリセット
void stimer_reset(int id, int val) {
gettimeofday(&(sact.timer[id].tv_base), NULL);
sact.timer[id].val = val;
if (id < 0 || id >= MAX_TIMER) {
WARNING("Invalid timer ID: %d", id);
return;
}
ticks_base[id] = sys_get_ticks() - (val * TICKS_PER_CENTISECOND);
}
// 指定IDのタイマーの取得
int stimer_get(int id) {
long sec, usec, usec2;
struct timeval tv;
struct timeval tv_base = sact.timer[id].tv_base;
int division = 10;
gettimeofday(&tv, NULL);
sec = tv.tv_sec - tv_base.tv_sec;
usec = tv.tv_usec - tv_base.tv_usec;
usec2 = sec * (1000l/division)+ usec / 1000l /division;
return sact.timer[id].val + usec2;
if (id < 0 || id >= MAX_TIMER) {
WARNING("Invalid timer ID: %d", id);
return 0;
}
uint32_t ticks = sys_get_ticks();
uint32_t diff = ticks - ticks_base[id];
return diff / TICKS_PER_CENTISECOND;
}
-10
View File
@@ -24,16 +24,6 @@
#ifndef __SACTTIMER_H__
#define __SACTTIMER_H__
#include <sys/time.h>
#include <unistd.h>
struct _stimer {
int val;
struct timeval tv_base;
};
typedef struct _stimer stimer_t;
void stimer_init(void);
void stimer_reset(int id, int val);
int stimer_get(int id);
-2
View File
@@ -98,8 +98,6 @@ static int move_cb(sprite_t *sp, agsevent_t *e) {
// 新しい場所のupdate
sp_updateme(sp);
update++;
} else {
usleep(1);
}
return update;
+1 -1
View File
@@ -533,7 +533,7 @@ static void append_to_log(char *msg) {
static void sactlog_newline() {
if (sact.logging) {
if (sact.msgbuf2[0] == '\0') return;
sact.log = list_append(sact.log, strdup(sact.msgbuf2));
sact.log = list_append(sact.log, toUTF8(sact.msgbuf2));
sact.msgbuf2[0] = '\0';
}
}
+16
View File
@@ -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;
}
+1
View File
@@ -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__ */
+5
View File
@@ -63,6 +63,10 @@ static bool cdrom_bgm_getPlayingInfo(cd_time *info) {
return true;
}
static bool cdrom_bgm_is_available(void) {
return true;
}
cdromdevice_t cdrom_bgm = {
.init = cdrom_bgm_init,
.exit = cdrom_bgm_exit,
@@ -70,4 +74,5 @@ cdromdevice_t cdrom_bgm = {
.start = cdrom_bgm_start,
.stop = cdrom_bgm_stop,
.getpos = cdrom_bgm_getPlayingInfo,
.is_available = cdrom_bgm_is_available,
};
+5
View File
@@ -62,6 +62,10 @@ static bool cdrom_getPlayingInfo(cd_time *info) {
return true;
}
static bool cdrom_is_available(void) {
return EM_ASM_INT({ return xsystem35.cdPlayer.hasAudioTrack(); });
}
cdromdevice_t cdrom_emscripten = {
.init = cdrom_init,
.exit = cdrom_exit,
@@ -69,4 +73,5 @@ cdromdevice_t cdrom_emscripten = {
.start = cdrom_start,
.stop = cdrom_stop,
.getpos = cdrom_getPlayingInfo,
.is_available = cdrom_is_available,
};
+1
View File
@@ -38,6 +38,7 @@ typedef struct {
bool (*start)(int trk, int loop);
void (*stop)(void);
bool (*getpos)(cd_time *);
bool (*is_available)(void);
} cdromdevice_t;
extern cdromdevice_t cdrom_bgm;
+5
View File
@@ -164,6 +164,10 @@ static bool cdrom_getPlayingInfo (cd_time *inf) {
return true;
}
static bool cdrom_is_available(void) {
return enabled;
}
cdromdevice_t cdrom_mp3 = {
.init = cdrom_init,
.exit = cdrom_exit,
@@ -171,4 +175,5 @@ cdromdevice_t cdrom_mp3 = {
.start = cdrom_start,
.stop = cdrom_stop,
.getpos = cdrom_getPlayingInfo,
.is_available = cdrom_is_available,
};
+116 -1
View File
@@ -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;
}
}
+1
View File
@@ -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;
+1 -286
View File
@@ -24,7 +24,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "portab.h"
#include "xsystem35.h"
#include "scenario.h"
@@ -33,7 +32,6 @@
#include "input.h"
#include "msgskip.h"
#include "selection.h"
#include "message.h"
#include "music.h"
#include "utfsjis.h"
#include "hankaku.h"
@@ -41,8 +39,8 @@
#include "gfx.h"
#include "ald_manager.h"
#include "LittleEndian.h"
#include "hacks.h"
#include "filecheck.h"
#include "cmd_check.h"
/* 選択 Window OPEN 時 callback */
static int cb_sel_init_page = 0;
@@ -52,11 +50,6 @@ static const char REGREADSTRING_RESULT[] = "*regReadString*";
static SDL_Rect clip_window;
extern INPUTSTRING_PARAM mi_param;
extern void commandH();
extern void commandHH();
typedef struct {
int page;
int index;
@@ -65,72 +58,6 @@ typedef struct {
#define FCTBL_MAX 1024
static fncall_table fnctbl[FCTBL_MAX];
void commands2F00() {
/* テキストカラーをスタックからポップして設定する */
sl_popState(STACK_TEXTCOLOR);
TRACE("TOC:");
}
void commands2F01() {
/* テキストフォントサイズをスタックからポップして設定する */
sl_popState(STACK_TEXTSIZE);
TRACE("TOS:");
}
void commands2F02() {
/* 現在のテキストカラーをスタックにプッシュする */
int type = getCaliValue();
switch (type) {
case 0: sl_pushTextColor(type, nact->msg.MsgFontColor); break;
case 1: sl_pushTextColor(type, nact->sel.MsgFontColor); break;
default: WARNING("TPC: unknown type %d", type); break;
}
TRACE("TPC %d", exp);
}
void commands2F03() {
/* 現在のテキストフォントサイズをスタックにプッシュする */
int type = getCaliValue();
switch (type) {
case 0: sl_pushTextSize(type, nact->msg.MsgFontSize); break;
case 1: sl_pushTextSize(type, nact->sel.MsgFontSize); break;
default: WARNING("TPS: unknown type %d", type); break;
}
TRACE("TPS %d", exp);
}
void commands2F04() {
/* テキスト表示位置をスタックからポップして設定する */
sl_popState(STACK_TEXTLOC);
TRACE("TOP:");
}
void commands2F05() {
/* 現在のテキスト表示位置をスタックにプッシュする */
SDL_Point loc;
msg_getMessageLocation(&loc);
sl_pushTextLoc(loc.x, loc.y);
TRACE("TPP:");
}
void commands2F08() {
/* アンチエイリアシング付きテキスト描画のフラグ設定 */
int exp = getCaliValue();
ags_setAntialiasedStringMode(exp == 1);
TRACE("TAA %d:", exp);
}
void commands2F09() {
/* アンチエイリアシング付きテキスト描画のフラグ取得 */
int *var = getCaliVariable();
*var = ags_getAntialiasedStringMode() ? 1 : 0;
TRACE("TAB %d:", *var);
}
void commands2F0A() {
/* Wavデータを読み込む */
int eCh = getCaliValue();
@@ -331,162 +258,6 @@ void commands2F21() {
sys_addMsg(str);
}
void commands2F23() {
int x = getCaliValue();
int y = getCaliValue();
const char *vFileName = sl_getString(0);
char *fname_utf8 = toUTF8(vFileName);
sysVar[0] = cg_load_with_filename(fname_utf8, x, y);
free(fname_utf8);
TRACE("LC(new) %d, %d, %s:", x, y, vFileName);
}
void commands2F24() {
int type = sl_getc();
const char *file_name = sl_getString(0);
int var, cnt;
struct VarRef vref;
char *fname_utf8 = toUTF8(file_name);
switch (type) {
case 0:
getCaliArray(&vref);
var = vref.var;
cnt = getCaliValue();
sysVar[0] = load_vars_from_file(fname_utf8, &vref, cnt);
break;
case 1:
var = getCaliValue();
cnt = getCaliValue();
sysVar[0] = load_strs_from_file(fname_utf8, var, cnt);
break;
default:
var = getCaliValue();
cnt = getCaliValue();
WARNING("Unknown LE command type %d", type);
break;
}
free(fname_utf8);
TRACE("LE(new) %d, %s, %d, %d:", type, file_name, var, cnt);
}
void commands2F25() {
int file_name = getCaliValue();
const char *title = sl_getString(0);
const char *filter = sl_getString(0);
TRACE_UNIMPLEMENTED("LXG %d, %s, %s:", file_name, title, filter);
}
void commands2F26() {
int dst_no = getCaliValue();
int max_len = getCaliValue();
const char *title = sl_getString(0);
char *t1, *t2, *t3;
t1 = toUTF8(title);
t2 = toUTF8(svar_get(dst_no));
mi_param.title = t1;
mi_param.oldstring = t2;
mi_param.max = max_len;
menu_inputstring(&mi_param);
if (mi_param.newstring == NULL) {
svar_set(dst_no, NULL);
free(t1); free(t2);
return;
}
t3 = fromUTF8(mi_param.newstring);
svar_set(dst_no, t3);
free(t1);
free(t2);
free(t3);
TRACE("MI(new) %d, %d, %s:", dst_no, max_len, title);
}
void commands2F27() {
int num = getCaliValue();
const char *string = sl_getString(0);
svar_set(num, string);
TRACE("MS(new) %d, %s:", num, string);
}
void commands2F28() {
const char *title = sl_getString(0);
if (nact->game_title_utf8)
free(nact->game_title_utf8);
nact->game_title_utf8 = toUTF8(title);
ags_setWindowTitle(nact->game_title_utf8);
enable_hack_by_title(nact->game_title_utf8);
TRACE("MT(new) %s:",title);
}
/* defined in cmdn.c */
extern INPUTNUM_PARAM ni_param;
void commands2F29() {
const char *title = sl_getString(0);
char *t;
if (ni_param.title != NULL) {
free(ni_param.title);
}
t = toUTF8(title);
ni_param.title = t;
TRACE("NT(new) %s:", title);
}
void commands2F2A() {
int type = sl_getc();
const char *file_name = sl_getString(0);
int var, cnt;
struct VarRef vref;
char *fname_utf8 = toUTF8(file_name);
switch(type) {
case 0:
getCaliArray(&vref);
var = vref.var;
cnt = getCaliValue();
sysVar[0] = save_vars_to_file(fname_utf8, &vref, cnt);
break;
case 1:
var = getCaliValue();
cnt = getCaliValue();
sysVar[0] = save_strs_to_file(fname_utf8, var, cnt);
break;
default:
var = getCaliValue();
cnt = getCaliValue();
WARNING("Unknown QE command");
break;
}
free(fname_utf8);
TRACE("QE(new) %d, %s, %d, %d:", type, file_name, var, cnt);
}
void commands2F2B() {
int type = sl_getc();
const char *work_dir = sl_getString(0);
const char *file_name = sl_getString(0);
TRACE_UNIMPLEMENTED("UP(new) %d, %s, %s:", type, work_dir, file_name);
}
void commands2F2D() {
int eCh = getCaliValue();
int eTime = getCaliValue();
@@ -712,17 +483,6 @@ void commands2F43() {
TRACE("grDrawFillCircle %d, %d, %d, %d:", eX, eY, eLength, eColor);
}
void commands2F44() {
int num1 = getCaliValue();
int fig = getCaliValue();
int num2 = getCaliValue();
char buf[256];
svar_set(num1, format_number(num2, fig, buf));
TRACE("MHH %d, %d, %d:", num1, fig, num2);
}
void commands2F45() {
int fPage = sl_getw();
int fIndex = sl_getaddr();
@@ -790,43 +550,6 @@ void commands2F4C() {
eX, eY, eSrcX, eSrcY, eWidth, eHeight);
}
void commands2F4D() {
int eNum = getCaliValue();
const char *sText = sl_getString(0);
TRACE_UNIMPLEMENTED("LXWT %d, %s:", eNum, sText);
}
void commands2F4E() {
int eNum = getCaliValue();
int eTextNum = getCaliValue();
TRACE_UNIMPLEMENTED("LXWS %d, %d:", eNum, eTextNum);
}
void commands2F4F() {
int eNum = getCaliValue();
int eType = getCaliValue();
TRACE_UNIMPLEMENTED("LXWE %d, %d:", eNum, eType);
}
void commands2F50() {
int eFile = getCaliValue();
int nFlg = sl_getc();
int eNum = getCaliValue();
TRACE_UNIMPLEMENTED("LXWH %d, %d, %d:", eFile, nFlg, eNum);
}
void commands2F51() {
int eFile = getCaliValue();
int nFlg = sl_getc();
int eNum = getCaliValue();
TRACE_UNIMPLEMENTED("LXWHH %d, %d, %d:", eFile, nFlg, eNum);
}
void commands2F52() {
int eNum = getCaliValue();
if (eNum <= 0) return;
@@ -882,14 +605,6 @@ void commands2F55() {
}
}
void commands2F56() {
int file_name = getCaliValue();
const char *title = sl_getString(0);
const char *folder = sl_getString(0);
TRACE_UNIMPLEMENTED("LXF %d, %s, %s:", file_name, title, folder);
}
void commands2F57() {
const char *sTitle = sl_getString(0);
int eStrVar = getCaliValue();
+32 -32
View File
@@ -249,25 +249,25 @@ void exec_command(void) {
/* 小文字コマンド */
switch(sl_getc()) {
case 0x00:
commands2F00(); break;
commandTOC(); break;
case 0x01:
commands2F01(); break;
commandTOS(); break;
case 0x02:
commands2F02(); break;
commandTPC(); break;
case 0x03:
commands2F03(); break;
commandTPS(); break;
case 0x04:
commands2F04(); break;
commandTOP(); break;
case 0x05:
commands2F05(); break;
commandTPP(); break;
case 0x06:
commandsINC(); break;
case 0x07:
commandsDEC(); break;
case 0x08:
commands2F08(); break;
commandTAA(); break;
case 0x09:
commands2F09(); break;
commandTAB(); break;
case 0x0a:
commands2F0A(); break;
case 0x0b:
@@ -319,23 +319,23 @@ void exec_command(void) {
case 0x22:
commandHH(); break;
case 0x23:
commands2F23(); break;
commandLC(0); break;
case 0x24:
commands2F24(); break;
commandLE(0); break;
case 0x25:
commands2F25(); break;
commandLXG(0); break;
case 0x26:
commands2F26(); break;
commandMI(0); break;
case 0x27:
commands2F27(); break;
commandMS(0); break;
case 0x28:
commands2F28(); break;
commandMT(0); break;
case 0x29:
commands2F29(); break;
commandNT(0); break;
case 0x2a:
commands2F2A(); break;
commandQE(0); break;
case 0x2b:
commands2F2B(); break;
commandUP(); break;
case 0x2c:
commandF(); break;
case 0x2d:
@@ -385,7 +385,7 @@ void exec_command(void) {
case 0x43:
commands2F43(); break;
case 0x44:
commands2F44(); break;
commandMHH(); break;
case 0x45:
commands2F45(); break;
case 0x46:
@@ -403,15 +403,15 @@ void exec_command(void) {
case 0x4c:
commands2F4C(); break;
case 0x4d:
commands2F4D(); break;
commandLXWT(); break;
case 0x4e:
commands2F4E(); break;
commandLXWS(); break;
case 0x4f:
commands2F4F(); break;
commandLXWE(); break;
case 0x50:
commands2F50(); break;
commandLXWH(); break;
case 0x51:
commands2F51(); break;
commandLXWHH(); break;
case 0x52:
commands2F52(); break;
case 0x53:
@@ -421,7 +421,7 @@ void exec_command(void) {
case 0x55:
commands2F55(); break;
case 0x56:
commands2F56(); break;
commandLXF(); break;
case 0x57:
commands2F57(); break;
case 0x58:
@@ -731,7 +731,7 @@ void exec_command(void) {
case 'L':
switch(sl_getc()) {
case 'C':
commandLC(); break;
commandLC(':'); break;
case 'D':
commandLD(); break;
case 'P':
@@ -739,7 +739,7 @@ void exec_command(void) {
case 'T':
commandLT(); break;
case 'E':
commandLE(); break;
commandLE(':'); break;
case 'L':
commandLL(); break;
case 'H':
@@ -761,7 +761,7 @@ void exec_command(void) {
case 'X':
switch(sl_getc()) {
case 'G':
commandLXG(); break;
commandLXG(':'); break;
case 'O':
commandLXO(); break;
case 'C':
@@ -803,7 +803,7 @@ void exec_command(void) {
case 'H':
commandMH(); break;
case 'I':
commandMI(); break;
commandMI(':'); break;
case 'J':
commandMJ(); break;
case 'L':
@@ -815,9 +815,9 @@ void exec_command(void) {
case 'P':
commandMP(); break;
case 'S':
commandMS(); break;
commandMS(':'); break;
case 'T':
commandMT(); break;
commandMT(':'); break;
case 'V':
commandMV(); break;
case 'Z':
@@ -871,7 +871,7 @@ void exec_command(void) {
case 'O':
commandNO(); break;
case 'T':
commandNT(); break;
commandNT(':'); break;
case 'D':
switch(sl_getc()) {
case 'C':
@@ -943,7 +943,7 @@ void exec_command(void) {
case 'D':
commandQD(); break;
case 'E':
commandQE(); break;
commandQE(':'); break;
case 'P':
commandQP(); break;
default:
+24 -32
View File
@@ -116,9 +116,9 @@ extern void commandKR();
extern void commandKW();
/* defined by cmdl.c */
extern void commandLC();
extern void commandLC(char terminator);
extern void commandLD();
extern void commandLE();
extern void commandLE(char terminator);
extern void commandLHD();
extern void commandLHG();
extern void commandLHM();
@@ -127,7 +127,7 @@ extern void commandLHW();
extern void commandLL();
extern void commandLP();
extern void commandLT();
extern void commandLXG();
extern void commandLXG(char terminator);
extern void commandLXO();
extern void commandLXC();
extern void commandLXL();
@@ -136,6 +136,12 @@ extern void commandLXP();
extern void commandLXR();
extern void commandLXW();
extern void commandLXX();
extern void commandLXWT();
extern void commandLXWS();
extern void commandLXWE();
extern void commandLXWH();
extern void commandLXWHH();
extern void commandLXF();
/* defined by cmdm.c */
extern void commandMA();
@@ -145,14 +151,15 @@ extern void commandME();
extern void commandMF();
extern void commandMG();
extern void commandMH();
extern void commandMI();
extern void commandMHH();
extern void commandMI(char terminator);
extern void commandMJ();
extern void commandML();
extern void commandMM();
extern void commandMN();
extern void commandMP();
extern void commandMS();
extern void commandMT();
extern void commandMS(char terminator);
extern void commandMT(char terminator);
extern void commandMV();
extern void commandMZ0();
@@ -175,7 +182,7 @@ extern void commandNI();
extern void commandNP();
extern void commandNR();
extern void commandNO();
extern void commandNT();
extern void commandNT(char terminator);
extern void commandND_ADD();
extern void commandND_SUB();
extern void commandND_MUL();
@@ -205,7 +212,7 @@ extern void commandPW();
/* defined by cmdq.c */
extern void commandQC();
extern void commandQD();
extern void commandQE();
extern void commandQE(char terminator);
extern void commandQP();
/* defined by cmds.c */
@@ -227,6 +234,14 @@ extern void commandSI();
/* defined by cmdt.c */
extern void commandT();
extern void commandTOC();
extern void commandTOS();
extern void commandTPC();
extern void commandTPS();
extern void commandTOP();
extern void commandTPP();
extern void commandTAA();
extern void commandTAB();
/* defined by cmdu.c */
extern void commandUC();
@@ -237,6 +252,7 @@ extern void commandUG();
extern void commandUP0();
extern void commandUP1();
extern void commandUP3();
extern void commandUP();
/* defined by cmdv.c */
extern void commandVC();
@@ -308,14 +324,6 @@ extern void commandZR();
extern void commandZU();
/* define in cmd2F.c */
extern void commands2F00();
extern void commands2F01();
extern void commands2F02();
extern void commands2F03();
extern void commands2F04();
extern void commands2F05();
extern void commands2F08();
extern void commands2F09();
extern void commands2F0A();
extern void commands2F0B();
extern void commands2F0C();
@@ -340,15 +348,6 @@ extern void commands2F1E();
extern void commands2F1F();
extern void commands2F20();
extern void commands2F21();
extern void commands2F23();
extern void commands2F24();
extern void commands2F25();
extern void commands2F26();
extern void commands2F27();
extern void commands2F28();
extern void commands2F29();
extern void commands2F2A();
extern void commands2F2B();
extern void commands2F2D();
extern void commands2F2E();
extern void commands2F2F();
@@ -372,7 +371,6 @@ extern void commands2F40();
extern void commands2F41();
extern void commands2F42();
extern void commands2F43();
extern void commands2F44();
extern void commands2F45();
extern void commands2F46();
extern void commands2F47();
@@ -381,16 +379,10 @@ extern void commands2F49();
extern void commands2F4A();
extern void commands2F4B();
extern void commands2F4C();
extern void commands2F4D();
extern void commands2F4E();
extern void commands2F4F();
extern void commands2F50();
extern void commands2F51();
extern void commands2F52();
extern void commands2F53();
extern void commands2F54();
extern void commands2F55();
extern void commands2F56();
extern void commands2F57();
extern void commands2F58();
extern void commands2F59();
+72 -10
View File
@@ -36,6 +36,7 @@
#include "savedata.h"
#include "utfsjis.h"
#include "cg.h"
#include "cmd_check.h"
void commandLD() {
/* 変数領域などのデータをロードする。(全ロード)*/
@@ -106,24 +107,38 @@ void commandLT() {
TRACE("LT %d,%p",num, var);
}
void commandLE() {
void commandLE(char terminator) {
int type = sl_getc();
const char *filename = sl_getString(':');
const char *filename = sl_getString(terminator);
char *fname_utf8 = toUTF8(filename);
char *fallback_fname = NULL;
if (strchr(fname_utf8, '\\')) {
fallback_fname = strdup(fname_utf8);
for (char *p = fname_utf8; *p; p++) {
if (*p == '\\')
*p = '/';
}
}
int var, cnt;
struct VarRef vref;
char *fname_utf8 = toUTF8(filename);
switch (type) {
case 0:
getCaliArray(&vref);
var = vref.var;
cnt = getCaliValue();
sysVar[0] = load_vars_from_file(fname_utf8, &vref, cnt);
// For compatibility; the QE command in v2.16.1 and earlier did not
// convert backslashes to slashes.
if (sysVar[0] == SAVE_LOADERR && fallback_fname)
sysVar[0] = load_vars_from_file(fallback_fname, &vref, cnt);
break;
case 1:
var = getCaliValue();
cnt = getCaliValue();
sysVar[0] = load_strs_from_file(fname_utf8, var, cnt);
if (sysVar[0] == SAVE_LOADERR && fallback_fname)
sysVar[0] = load_strs_from_file(fallback_fname, var, cnt);
break;
default:
var = getCaliValue();
@@ -131,6 +146,8 @@ void commandLE() {
WARNING("Unknown LE command %d", type);
break;
}
if (fallback_fname)
free(fallback_fname);
free(fname_utf8);
TRACE("LE %d,%s,%d,%d:",type, filename, var, cnt);
@@ -254,11 +271,11 @@ void commandLHW() {
TRACE("LHW %d,%d:",p1,no);
}
void commandLC() {
void commandLC(char terminator) {
int x = getCaliValue();
int y = getCaliValue();
const char *filename = sl_getString(':');
const char *filename = sl_getString(terminator);
char *fname_utf8 = toUTF8(filename);
sysVar[0] = cg_load_with_filename(fname_utf8, x, y);
free(fname_utf8);
@@ -266,11 +283,11 @@ void commandLC() {
TRACE("LC %d,%d,%s:", x, y, filename);
}
void commandLXG() {
void commandLXG(char terminator) {
/* ファイルを選択する */
int file_name = getCaliValue();
const char *title = sl_getString(':');
const char *filter = sl_getString(':');
const char *title = sl_getString(terminator);
const char *filter = sl_getString(terminator);
TRACE_UNIMPLEMENTED("LXG %d,%s,%s:", file_name, title, filter);
}
@@ -376,3 +393,48 @@ void commandLXX() {
TRACE("LXX %d,%d,%d:", type, num, *var);
}
void commandLXWT() {
int eNum = getCaliValue();
const char *sText = sl_getString(0);
TRACE_UNIMPLEMENTED("LXWT %d, %s:", eNum, sText);
}
void commandLXWS() {
int eNum = getCaliValue();
int eTextNum = getCaliValue();
TRACE_UNIMPLEMENTED("LXWS %d, %d:", eNum, eTextNum);
}
void commandLXWE() {
int eNum = getCaliValue();
int eType = getCaliValue();
TRACE_UNIMPLEMENTED("LXWE %d, %d:", eNum, eType);
}
void commandLXWH() {
int eFile = getCaliValue();
int nFlg = sl_getc();
int eNum = getCaliValue();
TRACE_UNIMPLEMENTED("LXWH %d, %d, %d:", eFile, nFlg, eNum);
}
void commandLXWHH() {
int eFile = getCaliValue();
int nFlg = sl_getc();
int eNum = getCaliValue();
TRACE_UNIMPLEMENTED("LXWHH %d, %d, %d:", eFile, nFlg, eNum);
}
void commandLXF() {
int file_name = getCaliValue();
const char *title = sl_getString(0);
const char *folder = sl_getString(0);
TRACE_UNIMPLEMENTED("LXF %d, %s, %s:", file_name, title, folder);
}
+20 -8
View File
@@ -34,15 +34,16 @@
#include "message.h"
#include "hankaku.h"
#include "hacks.h"
#include "cmd_check.h"
/* MI 用パラメータ */
INPUTSTRING_PARAM mi_param;
static INPUTSTRING_PARAM mi_param;
void commandMS() {
void commandMS(char terminator) {
/* Xコマンドで表示される文字列領域に文字列を入れる */
int num = getCaliValue();
const char *str = sl_getString(':');
const char *str = sl_getString(terminator);
svar_set(num, str);
TRACE("MS %d,%s:",num,str);
}
@@ -90,11 +91,11 @@ void commandMP() {
free(str);
}
void commandMI() { /* T2 */
void commandMI(char terminator) {
/* ユーザーによる文字列の入力 */
int dst_no = getCaliValue();
int max_len = getCaliValue();
const char *title = sl_getString(':');
const char *title = sl_getString(terminator);
char *t1, *t2, *t3;
t1 = toUTF8(title);
@@ -147,9 +148,9 @@ void commandMC() {
TRACE("MC %d,%d:",num1,num2);
}
void commandMT() {
void commandMT(char terminator) {
/* ウインドウのタイトル文字列を設定する */
const char *str = sl_getString(':');
const char *str = sl_getString(terminator);
if (nact->game_title_utf8)
free(nact->game_title_utf8);
@@ -186,6 +187,17 @@ void commandMH() {
TRACE("MH %d,%d,%d:",num1,fig,num2);
}
void commandMHH() {
int num1 = getCaliValue();
int fig = getCaliValue();
int num2 = getCaliValue();
char buf[256];
svar_set(num1, format_number(num2, fig, buf));
TRACE("MHH %d, %d, %d:", num1, fig, num2);
}
void commandMV() {
/* シナリオバージョンをシステムへ通知する */
int version = getCaliValue();
+4 -3
View File
@@ -30,9 +30,10 @@
#include "xsystem35.h"
#include "scenario.h"
#include "menu.h"
#include "cmd_check.h"
/* NI/NT 用パラメータ */
INPUTNUM_PARAM ni_param;
static INPUTNUM_PARAM ni_param;
void commandNB() {
/* var1 から始まるcount個の変数へ
@@ -376,9 +377,9 @@ void commandNI() { /* From Panyo */
TRACE("NI %p,%d,%d,%d:", var, def, _min, _max);
}
void commandNT() { /* From Panyo */
void commandNT(char terminator) {
/* NIコマンドで表示するタイトルを設定する。*/
const char *str = sl_getString(':');
const char *str = sl_getString(terminator);
free(ni_param.title);
ni_param.title = toUTF8(str);
+11 -4
View File
@@ -29,6 +29,8 @@
#include "scenario.h"
#include "savedata.h"
#include "utfsjis.h"
#include "filecheck.h"
#include "cmd_check.h"
void commandQD() {
/* 変数領域などのデータをセーブする。(全セーブ)*/
@@ -79,13 +81,18 @@ void commandQC() {
TRACE("QC %d,%d:",num1,num2);
}
void commandQE() {
void commandQE(char terminator) {
int type = sl_getc();
const char *filename = sl_getString(':');
const char *filename = sl_getString(terminator);
char *fname_utf8 = toUTF8(filename);
for (char *p = fname_utf8; *p; p++) {
if (*p == '\\') {
*p = '/';
}
}
int var, cnt;
struct VarRef vref;
char *fname_utf8 = toUTF8(filename);
switch (type) {
case 0:
getCaliArray(&vref);
+66
View File
@@ -35,3 +35,69 @@ void commandT() {
TRACE("T %d,%d:",x,y);
}
void commandTOC() {
/* テキストカラーをスタックからポップして設定する */
sl_popState(STACK_TEXTCOLOR);
TRACE("TOC:");
}
void commandTOS() {
/* テキストフォントサイズをスタックからポップして設定する */
sl_popState(STACK_TEXTSIZE);
TRACE("TOS:");
}
void commandTPC() {
/* 現在のテキストカラーをスタックにプッシュする */
int type = getCaliValue();
switch (type) {
case 0: sl_pushTextColor(type, nact->msg.MsgFontColor); break;
case 1: sl_pushTextColor(type, nact->sel.MsgFontColor); break;
default: WARNING("TPC: unknown type %d", type); break;
}
TRACE("TPC %d", exp);
}
void commandTPS() {
/* 現在のテキストフォントサイズをスタックにプッシュする */
int type = getCaliValue();
switch (type) {
case 0: sl_pushTextSize(type, nact->msg.MsgFontSize); break;
case 1: sl_pushTextSize(type, nact->sel.MsgFontSize); break;
default: WARNING("TPS: unknown type %d", type); break;
}
TRACE("TPS %d", exp);
}
void commandTOP() {
/* テキスト表示位置をスタックからポップして設定する */
sl_popState(STACK_TEXTLOC);
TRACE("TOP:");
}
void commandTPP() {
/* 現在のテキスト表示位置をスタックにプッシュする */
SDL_Point loc;
msg_getMessageLocation(&loc);
sl_pushTextLoc(loc.x, loc.y);
TRACE("TPP:");
}
void commandTAA() {
/* アンチエイリアシング付きテキスト描画のフラグ設定 */
int exp = getCaliValue();
ags_setAntialiasedStringMode(exp == 1);
TRACE("TAA %d:", exp);
}
void commandTAB() {
/* アンチエイリアシング付きテキスト描画のフラグ取得 */
int *var = getCaliVariable();
*var = ags_getAntialiasedStringMode() ? 1 : 0;
TRACE("TAB %d:", *var);
}
+8
View File
@@ -122,3 +122,11 @@ void commandUP3() {
TRACE_UNIMPLEMENTED("UP3 %s,%s:",str1,str2);
}
void commandUP() {
int type = sl_getc();
const char *work_dir = sl_getString(0);
const char *file_name = sl_getString(0);
TRACE_UNIMPLEMENTED("UP(new) %d, %s, %s:", type, work_dir, file_name);
}
+47 -20
View File
@@ -67,28 +67,28 @@ static int make_dir(const char *path)
#endif
// Adapted from http://stackoverflow.com/a/2336245/119527
static int mkdir_p(const char *path)
int mkdir_p(const char *path_utf8)
{
const size_t len = strlen(path);
char _path[PATH_MAX];
const size_t len = strlen(path_utf8);
char path[PATH_MAX];
char *p;
errno = 0;
// Copy string so its mutable
if (len > sizeof(_path)-1) {
if (len > sizeof(path)-1) {
errno = ENAMETOOLONG;
return -1;
}
strcpy(_path, path);
strcpy(path, path_utf8);
// Iterate the string
for (p = _path + 1; *p; p++) {
for (p = path + 1; *p; p++) {
if (*p == '/') {
// Temporarily truncate
*p = '\0';
if (make_dir(_path) != 0) {
if (make_dir(path) != 0) {
if (errno != EEXIST)
return -1;
}
@@ -97,7 +97,7 @@ static int mkdir_p(const char *path)
}
}
if (make_dir(_path) != 0) {
if (make_dir(path) != 0) {
if (errno != EEXIST)
return -1;
}
@@ -139,6 +139,15 @@ bool fc_exists(const char *fname_utf8)
FILE *fc_open(const char *fname_utf8, char type) {
char *path = fc_get_path(fname_utf8);
if (type == 'w') {
// Ensure the directory exists
char *p = strrchr(path, '/');
if (p) {
*p = '\0';
mkdir_p(path);
*p = '/';
}
}
FILE *fp = fopen_utf8(path, type);
if (!fp && type == 'r') {
fp = fopen_utf8(fname_utf8, type);
@@ -150,20 +159,32 @@ FILE *fc_open(const char *fname_utf8, char type) {
#else // !_WIN32
static char *fc_search(const char *fname_utf8, const char *dir) {
DIR *d = opendir(dir);
if (d == NULL)
return NULL;
// If path contains no directory separator, do case-insensitive search.
if (strchr(fname_utf8, '/') == NULL) {
DIR *d = opendir(dir);
if (d == NULL)
return NULL;
char *found = NULL;
struct dirent *entry;
while ((entry = readdir(d)) != NULL) {
if (strcasecmp(fname_utf8, entry->d_name) == 0) {
found = get_fullpath(dir, entry->d_name);
break;
char *found = NULL;
struct dirent *entry;
while ((entry = readdir(d)) != NULL) {
if (strcasecmp(fname_utf8, entry->d_name) == 0) {
found = get_fullpath(dir, entry->d_name);
break;
}
}
closedir(d);
return found;
} else {
// If path contains directory separator, do case-sensitive existence check.
char *fullpath = get_fullpath(dir, fname_utf8);
if (access(fullpath, F_OK) == 0) {
return fullpath;
} else {
free(fullpath);
return NULL;
}
}
closedir(d);
return found;
}
char *fc_get_path(const char *fname_utf8) {
@@ -195,7 +216,13 @@ FILE *fc_open(const char *fname_utf8, char type) {
FILE *fp;
if (type == 'w') {
fc_backup_oldfile(fullpath);
// Ensure the directory exists
char *p = strrchr(fullpath, '/');
if (p) {
*p = '\0';
mkdir_p(fullpath);
*p = '/';
}
fp = fopen(fullpath, "wb");
} else {
fp = fopen(fullpath, "rb");
+1
View File
@@ -31,5 +31,6 @@ char *fc_get_path(const char *fname_utf8);
bool fc_exists(const char *fname_utf8);
FILE *fc_open(const char *fname_utf8, char type);
void fc_backup_oldfile(const char *filename);
int mkdir_p(const char *path_utf8);
#endif /* !__FILECHECK_H__ */
+1
View File
@@ -112,6 +112,7 @@ int sys_keywait(int msec, unsigned flags) {
key = sys_getInputInfo();
cancel_yield(); // We just yielded!
if ((flags & KEYWAIT_CANCELABLE) && key) break;
if ((flags & KEYWAIT_CTRL_CANCELABLE) && RawKeyInfo[KEY_CTRL]) break;
}
return key;
+4 -3
View File
@@ -38,9 +38,10 @@ struct SDL_Point;
#define SYS35KEY_ESC 64
#define SYS35KEY_TAB 128
#define KEYWAIT_NONCANCELABLE 0
#define KEYWAIT_CANCELABLE 1
#define KEYWAIT_SKIPPABLE 2
#define KEYWAIT_NONCANCELABLE 0
#define KEYWAIT_CANCELABLE 1
#define KEYWAIT_SKIPPABLE 2
#define KEYWAIT_CTRL_CANCELABLE 4
// System3.x key codes (IG command, etc.)
// These are originated from Windows virtual key codes (VK_*).
-2
View File
@@ -21,8 +21,6 @@
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#undef max
#undef min
#else // _WIN32
#include <errno.h>
#include <fcntl.h>
+1 -1
View File
@@ -113,5 +113,5 @@ int muscd_get_maxtrack(void) {
}
bool muscd_is_available(void) {
return prv.cddev;
return prv.cddev && prv.cddev->is_available();
}
+9
View File
@@ -28,6 +28,15 @@
#include <stdint.h>
#include "config.h"
#ifdef _WIN32
# ifdef min
# undef min
# endif
# ifdef max
# undef max
# endif
# define NOMINMAX
#endif
#define min(x,y) ((x) < (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y))
-2
View File
@@ -17,8 +17,6 @@
*
*/
#include <windows.h>
#undef min
#undef max
#include <stdio.h>
#include <signal.h>
#include "win/console.h"
-2
View File
@@ -18,8 +18,6 @@
*/
#include <windows.h>
#include <commctrl.h>
#undef min
#undef max
#include <SDL_syswm.h>
#include "menu.h"
#include "gfx_private.h"
-2
View File
@@ -17,8 +17,6 @@
*
*/
#include <windows.h>
#undef min
#undef max
#include <time.h>
#include <SDL_syswm.h>
#include "system.h"
+12
View File
@@ -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
+7
View File
@@ -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