Compare commits

..
14 Commits
Author SHA1 Message Date
kichikuou 0a37920c95 Version 2.5.1 2022-07-31 16:07:25 +09:00
kichikuou fa44889047 Fix a bug in sdl_setPalette()
It called SDL_SetPaletteColors() with wrong arguments when `first` was
not zero. PP command was affected by this.
2022-07-31 13:53:37 +09:00
kichikuou cee18a572e Implement palette shift effect (CD 1001)
Used in Toushin Toshi 2.
2022-07-31 12:44:30 +09:00
kichikuou 652d284628 Debugger: Check out-of-bounds array access
This prevents the debugger from SEGVing when trying to access a
variable.
2022-07-30 18:14:35 +09:00
kichikuou d2661e97f1 sdl_effect: Implement EFFECT_CIRCLE_WIPE_{IN,OUT} 2022-07-23 10:57:59 +09:00
kichikuou 0e9afe7c0a Implement grDrawFillCircle 2022-07-23 09:18:58 +09:00
kichikuou fbe8af5f7b Fix command line option name in README.md 2022-07-17 22:22:36 +09:00
kichikuou 0c1f8f8450 Version 2.5.0 2022-07-17 21:26:48 +09:00
kichikuou 078525e2c2 Reduce console message spam 2022-07-16 21:15:55 +09:00
kichikuou d4a4022894 Enable ARM Neon support in stb_image 2022-07-16 17:46:26 +09:00
kichikuou dc89c92139 Switch JPEG decoder to stb_image
To enable JPEG support on Android without complicating CMake files.
2022-07-16 17:16:44 +09:00
kichikuou 4f351fc767 Improve warning messages 2022-07-16 16:00:24 +09:00
kichikuou 02ef4a1771 Android: Upgrade SDL2_mixer to 2.6.0 2022-07-10 14:42:57 +09:00
kichikuou 4a20d74f1a Do not call sdl_getEvent in sdl_getWheelInfo
This fixes performance regression in Graymerca.
2022-07-02 15:30:18 +09:00
27 changed files with 8123 additions and 250 deletions
-1
View File
@@ -26,7 +26,6 @@ jobs:
SDL2:p
SDL2_ttf:p
SDL2_mixer:p
libjpeg-turbo:p
libwebp:p
cjson:p
nsis:p
-6
View File
@@ -28,7 +28,6 @@ check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
check_symbol_exists(uname "sys/utsname.h" HAVE_UNAME)
if (EMSCRIPTEN)
set(HAVE_JPEG 1)
set(DEFAULT_FONT_PATH /fonts/)
elseif (ANDROID)
set(SDL2MIXER_FOUND 1)
@@ -59,11 +58,6 @@ else()
endif()
endif()
include(FindJPEG)
if (JPEG_FOUND)
set(HAVE_JPEG 1)
endif()
optional_pkg_check_modules(WEBP IMPORTED_TARGET libwebp)
if (WEBP_FOUND)
set(HAVE_WEBP 1)
+3 -3
View File
@@ -41,7 +41,7 @@ examine / modify variables in the game. There are two ways to use the debugger:
- Through [Visual Studio Code](https://code.visualstudio.com/) (recommended):
The [vscode-system3x](https://github.com/kichikuou/vscode-system3x) extension
provides graphical debugging interface for System 3.x.
- Using CUI debugger: Running xsystem35 with `-debugger` option will start the
- Using CUI debugger: Running xsystem35 with `-debug` option will start the
debugger with console interface. Type `help` to see a list of available
commands.
@@ -81,7 +81,7 @@ Run xsystem35 from within the game directory.
[Homebrew](https://brew.sh/index_ja) is needed.
$ brew install cmake pkg-config sdl2 sdl2_mixer sdl2_ttf libjpeg webp cjson
$ brew install cmake pkg-config sdl2 sdl2_mixer sdl2_ttf webp cjson
$ mkdir -p out/debug
$ cd out/debug
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
@@ -91,7 +91,7 @@ Run xsystem35 from within the game directory.
[MSYS2](https://www.msys2.org) is needed.
$ pacman -S cmake mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf mingw-w64-x86_64-SDL2_mixer mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libwebp mingw-w64-x86_64-cjson
$ pacman -S cmake mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf mingw-w64-x86_64-SDL2_mixer mingw-w64-x86_64-libwebp mingw-w64-x86_64-cjson
$ mkdir -p out/debug
$ cd out/debug
$ cmake -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug ../../
+2 -2
View File
@@ -16,8 +16,8 @@ android {
}
minSdkVersion 19
targetSdkVersion 31
versionCode 8
versionName "2.4.0"
versionCode 10
versionName "2.5.1"
externalNativeBuild {
cmake {
arguments "-DANDROID_APP_PLATFORM=android-16", "-DANDROID_STL=c++_static"
+7 -5
View File
@@ -13,11 +13,10 @@ FetchContent_Declare(
URL https://github.com/libsdl-org/SDL_ttf/archive/refs/tags/release-2.0.18.tar.gz
URL_HASH SHA1=6fc5130757b447d46c3da6abd58687e8576de8b8
)
# TODO: Use SDL2_mixer 2.0.5 once released
FetchContent_Declare(
SDL_mixer
GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git
GIT_TAG 6845d9f3cb3f35542f1ec7e74dba6b30bf968959
URL https://github.com/libsdl-org/SDL_mixer/archive/refs/tags/release-2.6.0.tar.gz
URL_HASH SHA1=a2aef03d74ac3dd9cd0004cff1834602a5dafa66
)
# Compilation of SDL and companion libraries
@@ -34,9 +33,12 @@ endif()
FetchContent_GetProperties(SDL_mixer)
if(NOT sdl_mixer_POPULATED)
FetchContent_Populate(SDL_mixer)
SET(SUPPORT_OGG ON CACHE BOOL "Enable OGG support in SDL_mixer" FORCE)
SET(SDL2MIXER_OPUS OFF CACHE BOOL "Enable Opus music" FORCE)
SET(SDL2MIXER_FLAC OFF CACHE BOOL "Enable FLAC music" FORCE)
SET(SDL2MIXER_MOD OFF CACHE BOOL "Support loading MOD music" FORCE)
SET(SDL2MIXER_MIDI OFF CACHE BOOL "Enable MIDI music" FORCE)
SET(SDL2MIXER_SAMPLES OFF CACHE BOOL "Build the SDL2_mixer sample program(s)" FORCE)
add_subdirectory(${sdl_mixer_SOURCE_DIR} ${sdl_mixer_BINARY_DIR})
target_compile_definitions(SDL2_mixer PRIVATE MUSIC_WAV)
endif()
# The main CMakeLists.txt of xsystem35
+1 -2
View File
@@ -1,5 +1,5 @@
#cmakedefine PACKAGE "@PACKAGE@"
#define VERSION "2.4.0"
#define VERSION "2.5.1"
#cmakedefine CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
@@ -25,7 +25,6 @@
#cmakedefine SEQ_DEVICE "@SEQ_DEVICE@"
#cmakedefine HAVE_GETLOGIN @HAVE_GETLOGIN@
#cmakedefine HAVE_JPEG @HAVE_JPEG@
#cmakedefine HAVE_MMAP @HAVE_MMAP@
#cmakedefine HAVE_SIGACTION @HAVE_SIGACTION@
#cmakedefine HAVE_UNAME @HAVE_UNAME@
-5
View File
@@ -102,7 +102,6 @@ target_compile_options(modules PRIVATE -Wno-pointer-sign)
if (EMSCRIPTEN)
set(LIBS
"SHELL:-s USE_ZLIB=1"
"SHELL:-s USE_LIBJPEG=1"
"SHELL:-s USE_SDL=2")
target_compile_options(modules PRIVATE ${LIBS})
target_link_options(modules PRIVATE ${LIBS})
@@ -117,7 +116,3 @@ else()
target_link_libraries(modules PRIVATE PkgConfig::SDL2MIXER)
endif()
endif()
if (HAVE_JPEG AND NOT EMSCRIPTEN)
target_link_libraries(modules PRIVATE JPEG::JPEG)
endif()
-8
View File
@@ -36,11 +36,7 @@
#include "input.h"
#include "ngraph.h"
#include "cg.h"
#ifdef HAVE_JPEG
#include "jpeg.h"
#endif
#ifdef HAVE_JPEG
#define FPS 30
@@ -88,8 +84,6 @@ static void ndd_run(int demonum) {
alk_free(alk);
}
#endif
static void Init() {
int p1 = getCaliValue(); /* ISys3x */
int p2 = getCaliValue(); /* IWinMsg */
@@ -105,9 +99,7 @@ static void Run() {
int p1 = getCaliValue(); // デモ番号 0,1,2
int p2 = getCaliValue();
#ifdef HAVE_JPEG
ndd_run(p1);
#endif
DEBUG_COMMAND("NightDemonDemo.Run %d,%d:\n", p1, p2);
}
+1 -8
View File
@@ -41,13 +41,7 @@ target_sources(xsystem35 PRIVATE
# CG
target_sources(xsystem35 PRIVATE
pms.c vsp.c bmp.c qnt.c)
if (HAVE_JPEG)
target_sources(xsystem35 PRIVATE jpeg.c)
if (NOT EMSCRIPTEN)
target_link_libraries(xsystem35 PRIVATE JPEG::JPEG)
endif()
endif()
pms.c vsp.c bmp.c qnt.c jpeg.c)
if (HAVE_WEBP)
target_sources(xsystem35 PRIVATE webp.c)
target_link_libraries(xsystem35 PRIVATE PkgConfig::WEBP)
@@ -88,7 +82,6 @@ if (EMSCRIPTEN)
set(LIBS
"SHELL:-s USE_ZLIB=1"
"SHELL:-s USE_LIBJPEG=1"
"SHELL:-s USE_SDL=2"
"SHELL:-s USE_SDL_TTF=2")
target_compile_options(xsystem35 PRIVATE ${LIBS})
+14
View File
@@ -301,6 +301,20 @@ void ags_getPixel(int x, int y, Palette *cell) {
sdl_getPixel(x, y, cell);
}
void ags_copyPaletteShift(int sx, int sy, int w, int h, int dx, int dy, BYTE sprite) {
if (!ags_check_param(&sx, &sy, &w, &h)) return;
if (!ags_check_param(&dx, &dy, &w, &h)) return;
for (int y = 0; y < h; y++) {
BYTE *src = GETOFFSET_PIXEL(nact->ags.dib, sx, sy + y);
BYTE *dst = GETOFFSET_PIXEL(nact->ags.dib, dx, dy + y);
for (int x = 0; x < w; x++, src++, dst++) {
if (*src != sprite)
*dst = (*src & 0xf0) | (*dst & 0x0f);
}
}
}
void ags_changeColorArea(int sx, int sy, int w, int h, int dst, int src, int cnt) {
if (nact->ags.world_depth != 8) return;
+1
View File
@@ -161,6 +161,7 @@ extern void ags_copyArea_shadow_withrate(int sx, int sy, int w, int h, int dx, i
extern void ags_wrapColor(int x, int y, int w, int h, int p1, int p2);
extern void ags_getPixel(int x, int y, Palette *cell);
extern void ags_copyPaletteShift(int sx, int sy, int w, int h, int dx, int dy, BYTE sprite);
extern void ags_changeColorArea(int x, int y, int w, int h, int dst, int src, int cnt);
extern void* ags_saveRegion(int x, int y, int w, int h);
+27 -17
View File
@@ -51,25 +51,35 @@ int *getVariable();
static int buf[CALI_DEPTH_MAX]; /* 計算式バッファ */
static int *cali = buf; /* インデックス */
/* 変数番号を返す */
static int *getVar(int c0) {
if ((c0 & 0x40) == 0)
return v_ref(c0 & 0x3f); // 0 - 0x3f
int c1 = sl_getc();
if (c0 != 0xc0)
return v_ref(((c0 & 0x3f) * 256) + c1); // 0x100 - 0x3fff
if (c1 == 1) {
c0 = sl_getc();
c1 = sl_getc();
int index = getCaliValue();
return v_ref_indexed(c0 << 8 | c1, index);
} else if (c1 >= 0x40) {
return v_ref(c1); // 0x40 - 0xff
int addr = sl_getIndex();
int var;
if ((c0 & 0x40) == 0) {
var = c0 & 0x3f; // 0 - 0x3f
} else {
int c1 = sl_getc();
if (c0 != 0xc0)
var = (c0 & 0x3f) * 256 + c1; // 0x100 - 0x3fff
else if (c1 == 1) {
c0 = sl_getc();
c1 = sl_getc();
var = c0 << 8 | c1;
int index = getCaliValue();
int *store = v_ref_indexed(var, index);
if (!store)
WARNING("%03d:%05x: Out of bounds index access: %s[%d]\n", sl_getPage(), addr, v_name(var), index);
return store;
} else if (c1 >= 0x40) {
var = c1; // 0x40 - 0xff
} else {
SYSERROR("Invalid variable reference at %d:0x%x", sl_getPage(), addr);
return NULL;
}
}
SYSERROR("Invalid variable reference at %d:0x%x", sl_getPage(), sl_getIndex() - 2);
return NULL;
int *store = v_ref(var);
if (!store)
WARNING("%03d:%05x: Out of bounds array access: %s\n", sl_getPage(), addr, v_name(var));
return store;
}
/* 変数番号が返る */
-8
View File
@@ -33,9 +33,7 @@
#include "pms.h"
#include "bmp.h"
#include "qnt.h"
#ifdef HAVE_JPEG
#include "jpeg.h"
#endif
#include "ald_manager.h"
#include "savedata.h"
#include "cache.h"
@@ -87,10 +85,8 @@ static CG_TYPE check_cgformat(BYTE *data) {
return ALCG_BMP8;
} else if (vsp_checkfmt(data)) {
return ALCG_VSP;
#ifdef HAVE_JPEG
} else if (jpeg_checkfmt(data) && nact->ags.world_depth >= 15) {
return ALCG_JPEG;
#endif
}
WARNING("Unknown Cg Type\n");
return ALCG_UNKNOWN;
@@ -221,11 +217,9 @@ static cgdata *loader(int no) {
case ALCG_QNT:
cg = qnt_extract(dfile->data);
break;
#ifdef HAVE_JPEG
case ALCG_JPEG:
cg = jpeg_extract(dfile->data, dfile->size);
break;
#endif
default:
break;
}
@@ -424,11 +418,9 @@ int cg_load_with_filename(char *fname_utf8, int x, int y) {
case ALCG_BMP24:
cg = bmp16m_extract(data);
break;
#ifdef HAVE_JPEG
case ALCG_JPEG:
cg = jpeg_extract(data, filesize);
break;
#endif
default:
return status;
}
+8 -3
View File
@@ -735,7 +735,10 @@ void commands2F43() {
int eLength = getCaliValue();
int eColor = getCaliValue();
DEBUG_COMMAND_YET("grDrawFillCircle %d, %d, %d, %d:\n", eX, eY, eLength, eColor);
sdl_fillCircle(eX, eY, eLength, eColor);
ags_updateArea(eX, eY, eLength, eLength);
DEBUG_COMMAND("grDrawFillCircle %d, %d, %d, %d:\n", eX, eY, eLength, eColor);
}
void commands2F44() {
@@ -1336,11 +1339,13 @@ void commands2F79() {
}
void commands2F7A() {
DEBUG_COMMAND_YET("menuFreeShelterDIB:\n");
// no-op
DEBUG_COMMAND("menuFreeShelterDIB:\n");
}
void commands2F7B() {
DEBUG_COMMAND_YET("msgFreeShelterDIB:\n");
// no-op
DEBUG_COMMAND("msgFreeShelterDIB:\n");
}
void commands2F7C() {
+1 -1
View File
@@ -161,7 +161,7 @@ void commandLL() {
DEBUG_COMMAND("LL %d,%d,%d,%d:\n",type, link_no, _var, num);
if (dfile->size < num * sizeof(WORD)) {
WARNING("data shortage (req = %d, result = %d)\n", num, dfile->size/ sizeof(WORD));
WARNING("data shortage (link_no = %d, requested %d, loaded %d)\n", link_no, num, dfile->size/ sizeof(WORD));
/* sysVar[0] = 254; 大嘘*/
/* return; */
num = dfile->size / sizeof(WORD);
+6 -2
View File
@@ -142,13 +142,17 @@ static int eval_variable(void) {
int var = dbg_lookup_var(buf);
if (var < 0)
eval_error("unknown variable \"%s\"", buf);
int *store;
if (consume('[')) {
int index = eval_expr();
expect(']');
return *v_ref_indexed(var, index);;
store = v_ref_indexed(var, index);
} else {
return *v_ref(var);
store = v_ref(var);
}
if (!store)
eval_error("out of bounds array access");
return *store;
}
static int eval_prim(void) {
+13 -3
View File
@@ -374,7 +374,11 @@ static void cmd_variables(cJSON *args, cJSON *resp) {
cJSON_AddItemToArray(variables, var);
cJSON_AddStringToObject(var, "name", dsym_variable_name(symbols, i));
char value[20];
sprintf(value, "%d", *v_ref(i));
int *store = v_ref(i);
if (store)
sprintf(value, "%d", *store);
else
strcpy(value, "(Out of bounds)");
cJSON_AddStringToObject(var, "value", value);
cJSON_AddNumberToObject(var, "variablesReference", 0);
}
@@ -426,13 +430,19 @@ static void cmd_setVariable(cJSON *args, cJSON *resp) {
cJSON_AddStringToObject(resp, "message", "syntax error");
return;
}
*v_ref(var) = parsed_value & 0xffff;
int *store = v_ref(var);
if (!store) {
cJSON_AddBoolToObject(resp, "success", false);
cJSON_AddStringToObject(resp, "message", "out of bounds array access");
return;
}
*store = parsed_value & 0xffff;
cJSON *body;
cJSON_AddBoolToObject(resp, "success", true);
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
char new_value[20];
sprintf(new_value, "%d", *v_ref(var));
sprintf(new_value, "%d", *store);
cJSON_AddStringToObject(body, "value", new_value);
} else if (cJSON_IsNumber(vref) && vref->valueint == VREF_STRINGS) {
int idx;
+10 -108
View File
@@ -279,110 +279,11 @@ static int eCopyArea23(int sx, int sy, int w, int h, int dx, int dy, int opt) {
return key;
}
#define SCA25_6_SLICE 10
static int eCopyArea25(int sx, int sy, int w, int h, int dx, int dy, int opt) {
int r, rr, x, xx, y, yy, key = 0, cnt;
int waitcnt = opt == 0 ? 20 : opt;
int w2=w/2,h2=h/2,h1=h-1,mr=(int)(sqrt(w2*w2+h2*h2));
int ux=0,uy=0,ux_y=h2-1,uw,uh;
cnt = sdl_getTicks();
for (r = SCA25_6_SLICE; r < mr; r += SCA25_6_SLICE ) {
cnt += waitcnt;
rr=r*r;
uw=uh=0;
for (y = 0; y < h2; y++) {
yy=h2-y;
xx=rr-yy*yy;
if (xx > 0) {
x=(int)(sqrt(xx));
x=(w2>x)?x:w2;
xx=w2-x;
ux=dx+xx;
uw=x*2;
if (uh == 0) {
uh=(h2-y)*2;
uy=dy+y;
}
if (xx == 0) {
ags_copyArea(sx+xx, sy+y, uw, ux_y-y+1, ux, dy+y);
ags_copyArea(sx+xx, sy+h1-ux_y, uw, ux_y-y+1, ux, dy+h1-ux_y);
ux_y=y;
break;
}
ags_copyArea(sx+xx, sy+y , uw, 1, ux, dy+y );
ags_copyArea(sx+xx, sy+h1-y, uw, 1, ux, dy+h1-y);
}
}
ags_updateArea(ux,uy,uw,uh);
EC_WAIT;
}
ags_copyArea(sx,sy,w,h,dx,dy);
ags_updateArea(dx, dy, w, h);
return key;
}
static int eCopyArea26(int sx, int sy, int w, int h, int dx, int dy, int opt) {
int r, rr, x, xx=0, y, yy, key = 0, cnt;
int waitcnt = opt == 0 ? 20 : opt;
int w2=w/2,w1=w-1,h2=h/2,h1=h-1,mr=(int)(sqrt(w2*w2+h2*h2));
int ux=0,uy=0,ux_y=0,uw,uh;
cnt = sdl_getTicks();
for (r = mr - SCA25_6_SLICE; r > 0; r -= SCA25_6_SLICE) {
cnt += waitcnt;
rr=r*r;
uy=ux_y;
uw=uh=0;
for (y = ux_y; y < h2; y++) {
yy=h2-y;
xx=rr-yy*yy;
if (xx < 0) {
uy++;
continue;
}
x=(int)(sqrt(xx));
x=(w2>x)?x:w2;
xx=w2-x;
if (xx == 0) break;
if ((xx-ux) > uw) uw=xx-ux;
uh++;
ags_copyArea(sx+ux, sy+y, xx-ux, 1, dx+ux, dy+y);
ags_copyArea(sx+w1-xx, sy+y, xx-ux, 1, dx+w1-xx, dy+y);
ags_copyArea(sx+ux, sy+h1-y, xx-ux, 1, dx+ux, dy+h1-y);
ags_copyArea(sx+w1-xx, sy+h1-y, xx-ux, 1, dx+w1-xx, dy+h1-y);
}
if (uy != ux_y) {
ags_copyArea(sx, sy+ux_y,w,uy-ux_y,dx,dy+ux_y);
ags_updateArea(dx,dy+ux_y,w,uy-ux_y);
ags_copyArea(sx, sy+h-uy,w,uy-ux_y,dx,dy+h-uy);
ags_updateArea(dx,dy+h-uy,w,uy-ux_y);
ux_y=uy;
}
ags_updateArea(dx+ux, dy+uy, uw, uh);
ags_updateArea(dx+w1-ux-uw, dy+uy, uw, uh);
ags_updateArea(dx+ux, dy+h-uy-uh, uw, uh);
ags_updateArea(dx+w1-ux-uw, dy+h-uy-uh, uw, uh);
ux=xx;
EC_WAIT;
}
ags_copyArea(sx,sy,w,h,dx,dy);
ags_updateArea(dx, dy, w, h);
return key;
}
static int eCopyArea1000(int sx, int sy, int w, int h, int dx, int dy, int opt, int spCol) {
/* XOR */
return sys_getInputInfo();
}
static int eCopyArea1001(int sx, int sy, int w, int h, int dx, int dy, int opt, int spCol) {
/* パレットシフト */
return sys_getInputInfo();
}
static int eCopyArea2000(int sx, int sy, int w, int h, int dx, int dy, int opt) {
sdl_fillRectangleRGB(dx, dy, w, h, 0, 0, 0);
ags_copyArea_alphaLevel(sx, sy, w, h, dx, dy, opt);
@@ -457,6 +358,9 @@ static int duration(enum nact_effect effect, int opt, SDL_Rect *rect) {
return (opt ? opt : 30) * rect->h / 16;
case NACT_EFFECT_MOSAIC:
return (opt ? opt : 100) * 8;
case NACT_EFFECT_CIRCLE_WIPE_OUT:
case NACT_EFFECT_CIRCLE_WIPE_IN:
return (opt ? opt : 20) * sqrt(rect->w * rect->w + rect->h * rect->h) / 40;
case NACT_EFFECT_FADEIN:
case NACT_EFFECT_WHITEIN:
case NACT_EFFECT_FADEOUT:
@@ -492,6 +396,8 @@ static int duration(enum nact_effect effect, int opt, SDL_Rect *rect) {
return opt ? opt : 1000;
case NACT_EFFECT_LINEAR_BLUR:
return opt ? opt : 1700;
case NACT_EFFECT_PALETTE_SHIFT:
return 0;
}
return 1000;
}
@@ -608,20 +514,16 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt
case 23:
ret = eCopyArea23(sx, sy, w, h, dx, dy, opt);
break;
case 25:
ret = eCopyArea25(sx, sy, w, h, dx, dy, opt);
break;
case 26:
ret = eCopyArea26(sx, sy, w, h, dx, dy, opt);
break;
case 1000:
if (nact->ags.world_depth != 8) return;
ret = eCopyArea1000(sx, sy, w, h, dx, dy, opt, spCol);
break;
case 1001:
if (nact->ags.world_depth != 8) return;
ret = eCopyArea1001(sx, sy, w, h, dx, dy, opt, spCol);
case NACT_EFFECT_PALETTE_SHIFT:
if (nact->ags.world_depth != 8 || spCol == -1) return;
ags_copyPaletteShift(sx, sy, w, h, dx, dy, spCol);
ags_updateArea(dx, dy, w, h);
ret = sys_getInputInfo();
break;
case 2000:
if (nact->ags.world_depth == 8) return;
+6 -1
View File
@@ -20,7 +20,7 @@
#ifndef __EFFECT_H__
#define __EFFECT_H__
// Effect types of the CE command.
// Effect types of the CE/CD command.
enum nact_effect {
NACT_EFFECT_WIPE_IN = 7,
NACT_EFFECT_WIPE_OUT = 8,
@@ -35,6 +35,8 @@ enum nact_effect {
NACT_EFFECT_WIPE_OUT_H = 20,
NACT_EFFECT_WIPE_IN_H = 21,
NACT_EFFECT_MOSAIC = 24,
NACT_EFFECT_CIRCLE_WIPE_OUT = 25,
NACT_EFFECT_CIRCLE_WIPE_IN = 26,
NACT_EFFECT_FADEIN = 27,
NACT_EFFECT_WHITEIN = 28,
NACT_EFFECT_FADEOUT = 29,
@@ -62,6 +64,7 @@ enum nact_effect {
NACT_EFFECT_WINDMILL_180 = 51,
NACT_EFFECT_WINDMILL_360 = 52,
NACT_EFFECT_LINEAR_BLUR = 53,
NACT_EFFECT_PALETTE_SHIFT = 1001, // CD command only
};
// Effect types of SCAT.DrawEffect and Gpx.EffectCopy.
@@ -131,6 +134,8 @@ enum sdl_effect_type {
EFFECT_WIPE_IN_V,
EFFECT_WIPE_OUT_H,
EFFECT_WIPE_IN_H,
EFFECT_CIRCLE_WIPE_OUT,
EFFECT_CIRCLE_WIPE_IN,
EFFECT_BLIND_DOWN,
EFFECT_BLIND_UP,
EFFECT_BLIND_LR,
+16 -31
View File
@@ -17,16 +17,20 @@
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#undef max
#undef min
#include <SDL_cpuinfo.h>
#if defined(__ARM_NEON)
#define STBI_NEON
#endif
#define STBI_NO_STDIO
#define STBI_ONLY_JPEG
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "config.h"
#include "system.h"
#include "ags.h"
#include "jpeg.h"
boolean jpeg_checkfmt(BYTE *data) {
@@ -34,37 +38,18 @@ boolean jpeg_checkfmt(BYTE *data) {
}
cgdata *jpeg_extract(BYTE *data, size_t size) {
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
// TODO: Error handling
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, data, size);
if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) {
WARNING("jpeg_read_header failed\n");
jpeg_destroy_decompress(&cinfo);
int width, height, channels;
BYTE *pixels = stbi_load_from_memory(data, size, &width, &height, &channels, 3);
if (!pixels) {
WARNING("cannot decode jpeg: %s\n", stbi_failure_reason());
return NULL;
}
jpeg_start_decompress(&cinfo);
cgdata *cg = calloc(1, sizeof(cgdata));
cg->type = ALCG_JPEG;
cg->width = cinfo.output_width;
cg->height = cinfo.output_height;
cg->width = width;
cg->height = height;
cg->depth = 24;
cg->pic = malloc(3 * cg->width * cg->height);
int row_stride = cinfo.output_width * cinfo.output_components;
while (cinfo.output_scanline < cinfo.output_height) {
JSAMPROW dst = cg->pic + cinfo.output_scanline * row_stride;
jpeg_read_scanlines(&cinfo, &dst, 1);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
cg->pic = pixels;
return cg;
}
+2 -1
View File
@@ -54,12 +54,13 @@ extern void sdl_updateAll(MyRectangle *view_rect);
extern void sdl_updateScreen(void);
/* パレット関係 */
extern void sdl_setPalette(Palette256 *pal, int src, int cnt);
extern void sdl_setPalette(Palette256 *pal, int first, int count);
/* 描画関係 */
extern void sdl_drawRectangle(int x, int y, int w, int h, BYTE c);
extern void sdl_fillRectangle(int x, int y, int w, int h, BYTE c);
extern void sdl_fillRectangleRGB(int x, int y, int w, int h, BYTE r, BYTE g, BYTE b);
extern void sdl_fillCircle(int left, int top, int diameter, BYTE c);
extern void sdl_drawLine(int x1, int y1, int x2, int y2, BYTE c);
extern SDL_Rect sdl_floodFill(int x, int y, int col);
extern SDL_Rect sdl_drawString(int x, int y, const char *str_utf8, BYTE col);
+39 -24
View File
@@ -49,6 +49,12 @@ static void sdl_pal_check(void) {
}
}
static Uint32 palette_color(BYTE c) {
if (sdl_dib->format->BitsPerPixel == 8)
return c;
return SDL_MapRGB(sdl_dib->format, sdl_col[c].r, sdl_col[c].g, sdl_col[c].b);
}
void sdl_updateScreen(void) {
if (!sdl_dirty)
return;
@@ -112,26 +118,20 @@ void sdl_updateAll(MyRectangle *view_rect) {
}
/* Color の複数個指定 */
void sdl_setPalette(Palette256 *pal, int src, int cnt) {
int i;
for (i = 0; i < cnt; i++) {
sdl_col[src + i].r = pal->red [src + i];
sdl_col[src + i].g = pal->green[src + i];
sdl_col[src + i].b = pal->blue [src + i];
}
if (sdl_dib->format->BitsPerPixel == 8) {
SDL_SetPaletteColors(sdl_dib->format->palette, sdl_col, src, cnt);
void sdl_setPalette(Palette256 *pal, int first, int count) {
for (int i = 0; i < count; i++) {
sdl_col[first + i].r = pal->red [first + i];
sdl_col[first + i].g = pal->green[first + i];
sdl_col[first + i].b = pal->blue [first + i];
}
if (sdl_dib->format->BitsPerPixel == 8)
SDL_SetPaletteColors(sdl_dib->format->palette, &sdl_col[first], first, count);
}
/* 矩形の描画 */
void sdl_drawRectangle(int x, int y, int w, int h, BYTE c) {
sdl_pal_check();
Uint32 col = (sdl_dib->format->BitsPerPixel == 8) ? c
: SDL_MapRGB(sdl_dib->format, sdl_col[c].r, sdl_col[c].g, sdl_col[c].b);
Uint32 col = palette_color(c);
SDL_Rect rect = {x, y, w, 1};
SDL_FillRect(sdl_dib, &rect, col);
@@ -151,11 +151,7 @@ void sdl_fillRectangle(int x, int y, int w, int h, BYTE c) {
sdl_pal_check();
SDL_Rect rect = {x, y, w, h};
Uint32 col = (sdl_dib->format->BitsPerPixel == 8) ? c
: SDL_MapRGB(sdl_dib->format, sdl_col[c].r, sdl_col[c].g, sdl_col[c].b);
SDL_FillRect(sdl_dib, &rect, col);
SDL_FillRect(sdl_dib, &rect, palette_color(c));
}
void sdl_fillRectangleRGB(int x, int y, int w, int h, BYTE r, BYTE g, BYTE b) {
@@ -166,6 +162,28 @@ void sdl_fillRectangleRGB(int x, int y, int w, int h, BYTE r, BYTE g, BYTE b) {
SDL_FillRect(sdl_dib, &rect, SDL_MapRGB(sdl_dib->format, r, g, b));
}
void sdl_fillCircle(int left, int top, int diameter, BYTE c) {
diameter &= ~1;
if (diameter <= 0)
return;
Uint32 col = palette_color(c);
// This draws a circle that is pixel-identical to System3.9's grDrawFillCircle.
for (int y = 0; y < diameter; y++) {
int dy = diameter - 2*y;
int dx = diameter - 1;
for (int x = 0; 2*x < diameter; x++) {
if (dy*dy + dx*dx <= diameter*diameter) {
SDL_Rect rect = {left + x, top + y, diameter - 2*x, 1};
SDL_FillRect(sdl_dib, &rect, col);
break;
}
dx -= 2;
}
}
}
/* 領域コピー */
void sdl_copyArea(int sx, int sy, int w, int h, int dx, int dy) {
if (sx == dx && sy == dy)
@@ -264,8 +282,7 @@ void sdl_drawLine(int x1, int y1, int x2, int y2, BYTE c) {
#undef TYPE
SDL_Rect sdl_floodFill(int x, int y, int c) {
Uint32 col = (sdl_dib->format->BitsPerPixel == 8) ? c
: SDL_MapRGB(sdl_dib->format, sdl_col[c].r, sdl_col[c].g, sdl_col[c].b);
Uint32 col = palette_color(c);
switch (sdl_dib->format->BytesPerPixel) {
case 1:
@@ -312,10 +329,8 @@ void sdl_wrapColor(int sx, int sy, int w, int h, BYTE c, int rate) {
SDL_Surface *s = SDL_CreateRGBSurface(0, w, h, sdl_dib->format->BitsPerPixel, 0, 0, 0, 0);
assert(s->format->BitsPerPixel > 8);
Uint32 col = SDL_MapRGB(sdl_dib->format, sdl_col[c].r, sdl_col[c].g, sdl_col[c].b);
SDL_Rect r_src = {0, 0, w, h};
SDL_FillRect(s, &r_src, col);
SDL_FillRect(s, &r_src, palette_color(c));
SDL_SetSurfaceBlendMode(s, SDL_BLENDMODE_BLEND);
SDL_SetSurfaceAlphaMod(s, rate);
+55
View File
@@ -44,6 +44,8 @@ enum sdl_effect_type from_nact_effect(enum nact_effect effect) {
case NACT_EFFECT_WIPE_OUT_H: return EFFECT_WIPE_OUT_H;
case NACT_EFFECT_WIPE_IN_H: return EFFECT_WIPE_IN_H;
case NACT_EFFECT_MOSAIC: return EFFECT_MOSAIC;
case NACT_EFFECT_CIRCLE_WIPE_OUT: return EFFECT_CIRCLE_WIPE_OUT;
case NACT_EFFECT_CIRCLE_WIPE_IN: return EFFECT_CIRCLE_WIPE_IN;
case NACT_EFFECT_FADEIN: return EFFECT_FADEIN;
case NACT_EFFECT_WHITEIN: return EFFECT_WHITEIN;
case NACT_EFFECT_FADEOUT: return EFFECT_FADEOUT_FROM_NEW;
@@ -634,6 +636,56 @@ static void wipe_free(struct sdl_effect *eff) {
free(eff);
}
// EFFECT_CIRCLE_WIPE_*
static void circle_wipe_step(struct sdl_effect *eff, double progress);
static void circle_wipe_free(struct sdl_effect *eff);
static struct sdl_effect *circle_wipe_new(SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new, enum sdl_effect_type type) {
struct sdl_effect *eff = calloc(1, sizeof(struct sdl_effect));
if (!eff)
NOMEMERR();
effect_init(eff, rect, old, new, type);
eff->step = circle_wipe_step;
eff->finish = circle_wipe_free;
return eff;
}
static void circle_wipe_step(struct sdl_effect *eff, double progress) {
SDL_Texture *bg = eff->tx_old;
SDL_Texture *fg = eff->tx_new;
if (eff->type == EFFECT_CIRCLE_WIPE_IN) {
bg = eff->tx_new;
fg = eff->tx_old;
progress = 1 - progress;
}
SDL_RenderCopy(sdl_renderer, bg, NULL, &eff->dst_rect);
int hw = eff->dst_rect.w / 2;
int hh = eff->dst_rect.h / 2;
int r = sqrt(hw*hw + hh*hh) * progress;
for (int y = -r; y < r; y++) {
if (y < -hh || y >= hh)
continue;
for (int x = max(-r, -hw); x < 0; x++) {
if (y*y + x*x <= r*r) {
SDL_Rect sr = {hw + x, hh + y, -2*x, 1};
SDL_Rect dr = {eff->dst_rect.x + hw + x, eff->dst_rect.y + hh + y, -2*x, 1};
SDL_RenderCopy(sdl_renderer, fg, &sr, &dr);
break;
}
}
}
SDL_RenderPresent(sdl_renderer);
}
static void circle_wipe_free(struct sdl_effect *eff) {
effect_finish(eff, true);
free(eff);
}
// EFFECT_BLIND_*
static void blind_step(struct sdl_effect *eff, double progress);
@@ -1530,6 +1582,9 @@ struct sdl_effect *sdl_effect_init(SDL_Rect *rect, agsurface_t *old, int ox, int
case EFFECT_WIPE_OUT_H:
case EFFECT_WIPE_IN_H:
return wipe_new(rect, sf_old, sf_new, type);
case EFFECT_CIRCLE_WIPE_OUT:
case EFFECT_CIRCLE_WIPE_IN:
return circle_wipe_new(rect, sf_old, sf_new, type);
case EFFECT_BLIND_DOWN:
case EFFECT_BLIND_UP:
case EFFECT_BLIND_LR:
-1
View File
@@ -325,7 +325,6 @@ int sdl_getMouseInfo(MyPoint *p) {
}
void sdl_getWheelInfo(int *forward, int *back) {
sdl_getEvent();
*forward = mouse_wheel_up;
*back = mouse_wheel_down;
+7899
View File
File diff suppressed because it is too large Load Diff
+11 -10
View File
@@ -28,7 +28,6 @@
#include "utfsjis.h"
#include "variable.h"
#include "xsystem35.h"
#include "scenario.h"
typedef struct {
int *pointvar;
@@ -54,6 +53,14 @@ int preVarPage; /* 直前にアクセスした変数のページ */
int preVarIndex; /* 直前にアクセスした変数のINDEX */
int preVarNo; /* 直前にアクセスした変数の番号 */
const char *v_name(int var) {
if (var < nact->ain.varnum)
return nact->ain.var[var];
static char buf[10];
sprintf(buf, "VAR%d", var);
return buf;
}
static char *advance(const char *s, int n) {
while (*s && n > 0) {
s = advance_char(s, nact->encoding);
@@ -77,10 +84,8 @@ int *v_ref(int var) {
int *index = attr->pointvar;
int page = attr->page;
int offset = attr->offset;
if (*index + offset >= arrayVarBuffer[page - 1].size) {
WARNING("%03d:%05x: ArrayIndexOutOfBounds (%d, %d, %d, %d)\n", sl_getPage(), sl_getIndex(), var, *index, page, offset);
if (*index + offset >= arrayVarBuffer[page - 1].size)
return NULL;
}
preVarIndex = offset + *index;
return arrayVarBuffer[page - 1].value + offset + *index;
}
@@ -92,10 +97,8 @@ int *v_ref_indexed(int var, int index) {
if (attr->page == 0) {
// If VAR_n is not an array variable, VAR_n[i] points to VAR_(n+i).
if ((var + index) >= SYSVAR_MAX) {
WARNING("%03d:%05x: ArrayIndexOutOfBounds (%d, %d)\n", sl_getPage(), sl_getIndex(), var, index);
if ((var + index) >= SYSVAR_MAX)
return NULL;
}
preVarIndex = var + index;
return sysVar + var + index;
}
@@ -103,10 +106,8 @@ int *v_ref_indexed(int var, int index) {
// Indexed array access
int page = attr->page;
int offset = attr->offset;
if (offset + index >= arrayVarBuffer[page - 1].size) {
WARNING("%03d:%05x: ArrayIndexOutOfBounds (%d, %d, %d, %d)\n", sl_getPage(), sl_getIndex(), var, index, page, offset);
if (offset + index >= arrayVarBuffer[page - 1].size)
return NULL;
}
preVarIndex = offset + index;
return arrayVarBuffer[page - 1].value + offset + index;
}
+1
View File
@@ -47,6 +47,7 @@ extern int preVarPage;
extern int preVarIndex;
extern int preVarNo;
const char *v_name(int var);
int *v_ref(int var);
int *v_ref_indexed(int var, int index);
boolean v_allocateArrayBuffer(int page, int size, boolean saveflag);