mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-26 16:38:06 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50a6b17c5e | ||
|
|
0d49619366 | ||
|
|
da3cc5d900 | ||
|
|
1785e93fcc |
@@ -1,5 +1,8 @@
|
||||
# Changelog
|
||||
|
||||
## 2.19.1 - 2026-08-02
|
||||
- Fixed an issue that prevented moving upward during battles in Rance 4.
|
||||
|
||||
## 2.19.0 - 2026-07-19
|
||||
- Replaced the GTK-based popup menu and dialogs with a pure-SDL implementation.
|
||||
- On Android, the popup menu opens with a three-finger tap.
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ set(CMAKE_C_STANDARD 99)
|
||||
enable_testing()
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
|
||||
|
||||
set(XSYSTEM35_VERSION "2.19.0")
|
||||
set(XSYSTEM35_VERSION "2.19.1")
|
||||
|
||||
include(CheckSymbolExists)
|
||||
include(FetchContent)
|
||||
|
||||
@@ -17,7 +17,7 @@ android {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 34
|
||||
versionCode 36
|
||||
versionName "2.19.0" + gitRevision()
|
||||
versionName "2.19.1" + gitRevision()
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
|
||||
|
||||
@@ -193,7 +193,7 @@ void ags_setViewArea(int x, int y, int width, int height) {
|
||||
nact->ags.view_area.y = y;
|
||||
nact->ags.view_area.w = width;
|
||||
nact->ags.view_area.h = height;
|
||||
gfx_setWindowSize(width, height);
|
||||
gfx_setViewSize(width, height);
|
||||
}
|
||||
|
||||
void ags_setWindowTitle(const char *title_utf8) {
|
||||
@@ -202,20 +202,33 @@ void ags_setWindowTitle(const char *title_utf8) {
|
||||
gfx_setWindowTitle(buf);
|
||||
}
|
||||
|
||||
void ags_getDIBInfo(DispInfo *info) {
|
||||
info->width = nact->ags.world_width;
|
||||
info->height = nact->ags.world_height;
|
||||
info->depth = nact->ags.world_depth;
|
||||
}
|
||||
|
||||
void ags_getViewAreaInfo(DispInfo *info) {
|
||||
gfx_getWindowInfo(NULL, NULL, &info->depth);
|
||||
info->width = nact->ags.view_area.w;
|
||||
info->height = nact->ags.view_area.h;
|
||||
}
|
||||
|
||||
void ags_getWindowInfo(DispInfo *info) {
|
||||
gfx_getWindowInfo(&info->width, &info->height, &info->depth);
|
||||
void ags_getDisplayInfo(enum ags_display display, int *width, int *height, int *depth) {
|
||||
SDL_DisplayMode dm;
|
||||
switch (display) {
|
||||
case AGS_DISPLAY_CURRENT:
|
||||
SDL_GetCurrentDisplayMode(0, &dm);
|
||||
*width = dm.w;
|
||||
*height = dm.h;
|
||||
*depth = SDL_BITSPERPIXEL(dm.format);
|
||||
break;
|
||||
case AGS_DISPLAY_DIB:
|
||||
*width = nact->ags.world_width;
|
||||
*height = nact->ags.world_height;
|
||||
*depth = nact->ags.world_depth;
|
||||
break;
|
||||
case AGS_DISPLAY_VIEW_AREA:
|
||||
SDL_GetCurrentDisplayMode(0, &dm);
|
||||
*width = nact->ags.view_area.w;
|
||||
*height = nact->ags.view_area.h;
|
||||
*depth = SDL_BITSPERPIXEL(dm.format);
|
||||
break;
|
||||
case AGS_DISPLAY_DESKTOP:
|
||||
SDL_GetDesktopDisplayMode(0, &dm);
|
||||
*width = dm.w;
|
||||
*height = dm.h;
|
||||
*depth = SDL_BITSPERPIXEL(dm.format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ags_setExposeSwitch(bool expose) {
|
||||
@@ -733,10 +746,10 @@ void ags_setCursorLocation(int x, int y, bool is_dibgeo, bool for_selection) {
|
||||
for (int i = 1; i < 8; i++) {
|
||||
int xi = ((dx*i*i*i) >> 9) - ((3*dx*i*i)>> 6) + ((3*dx*i) >> 3) + p.x;
|
||||
int yi = ((dy*i*i*i) >> 9) - ((3*dy*i*i)>> 6) + ((3*dy*i) >> 3) + p.y;
|
||||
event_set_mouse_location(xi, yi);
|
||||
gfx_warpMouse(xi, yi);
|
||||
sys_sleep(cursor_move_time / 7);
|
||||
}
|
||||
event_set_mouse_location(x, y);
|
||||
gfx_warpMouse(x, y);
|
||||
} else if (!for_selection) {
|
||||
event_set_mouse_internal_location(x, y);
|
||||
sys_sleep(cursor_move_time);
|
||||
|
||||
@@ -102,11 +102,12 @@ typedef struct {
|
||||
uint32_t index;
|
||||
} PixelColor;
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
int height;
|
||||
int depth;
|
||||
} DispInfo;
|
||||
enum ags_display {
|
||||
AGS_DISPLAY_CURRENT,
|
||||
AGS_DISPLAY_DIB,
|
||||
AGS_DISPLAY_VIEW_AREA,
|
||||
AGS_DISPLAY_DESKTOP,
|
||||
};
|
||||
|
||||
struct _ags {
|
||||
SDL_Color pal[256]; /* system palette */
|
||||
@@ -145,9 +146,7 @@ void ags_reset(void);
|
||||
extern void ags_setWorldSize(int width, int height, int depth);
|
||||
extern void ags_setViewArea(int x, int y, int width, int height);
|
||||
extern void ags_setWindowTitle(const char *title_utf8);
|
||||
extern void ags_getDIBInfo(DispInfo *info);
|
||||
extern void ags_getWindowInfo(DispInfo *info);
|
||||
extern void ags_getViewAreaInfo(DispInfo *info);
|
||||
extern void ags_getDisplayInfo(enum ags_display display, int *width, int *height, int *depth);
|
||||
extern bool ags_check_param(int *x, int *y, int *w, int *h);
|
||||
extern bool ags_check_param_xy(int *x, int *y);
|
||||
extern surface_t *ags_getDIB();
|
||||
|
||||
+6
-6
@@ -90,7 +90,7 @@ typedef struct {
|
||||
#define UNITMAP_ATTRIB_WALKRESULT (3)
|
||||
|
||||
/* UnitMAP 全体へのポインタ */
|
||||
static int *UnitMap = NULL;
|
||||
static vmvar_t *UnitMap = NULL;
|
||||
/* VC command */
|
||||
static int nPageNum;
|
||||
static int x0Map;
|
||||
@@ -160,7 +160,7 @@ void commandVC() { /* from Rance4 */
|
||||
return;
|
||||
}
|
||||
|
||||
UnitMap = (int *)calloc(cxMap * cyMap * nPageNum * UNITMAP_ATTRIB_DEPTH, sizeof(int));
|
||||
UnitMap = calloc(cxMap * cyMap * nPageNum * UNITMAP_ATTRIB_DEPTH, sizeof(*UnitMap));
|
||||
srcimg = (UnitMapSrcImg *)calloc(nPageNum, sizeof(UnitMapSrcImg));
|
||||
|
||||
if (NULL == UnitMap || NULL == srcimg) {
|
||||
@@ -458,7 +458,7 @@ void commandVR() { /* from Rance4 */
|
||||
int nPage = getCaliValue();
|
||||
int nType = getCaliValue();
|
||||
vmvar_t *var = getCaliVariable();
|
||||
int *dst;
|
||||
vmvar_t *dst;
|
||||
|
||||
TRACE("VR %d,%d,%p:",nPage, nType, var);
|
||||
|
||||
@@ -481,14 +481,14 @@ void commandVR() { /* from Rance4 */
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dst, var, sizeof(int) * MAPSIZE_PER_ATTRIB);
|
||||
memcpy(dst, var, MAPSIZE_PER_ATTRIB * sizeof(*dst));
|
||||
}
|
||||
|
||||
void commandVW() { /* from Rance4 */
|
||||
int nPage = getCaliValue();
|
||||
int nType = getCaliValue();
|
||||
vmvar_t *var = getCaliVariable();
|
||||
int *src;
|
||||
vmvar_t *src;
|
||||
|
||||
TRACE("VW %d,%d,%p:",nPage, nType, var);
|
||||
|
||||
@@ -511,7 +511,7 @@ void commandVW() { /* from Rance4 */
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(var, src, sizeof(int) * MAPSIZE_PER_ATTRIB);
|
||||
memcpy(var, src, MAPSIZE_PER_ATTRIB * sizeof(*src));
|
||||
}
|
||||
|
||||
void commandVE() { /* from T2 */
|
||||
|
||||
+12
-28
@@ -53,6 +53,14 @@ static uint32_t get_counter(int num) {
|
||||
return sys_get_ticks() - counters[num].base;
|
||||
}
|
||||
|
||||
static void write_display_info(vmvar_t *var, enum ags_display display) {
|
||||
int width, height, depth;
|
||||
ags_getDisplayInfo(display, &width, &height, &depth);
|
||||
var[0] = width;
|
||||
var[1] = height;
|
||||
var[2] = depth;
|
||||
}
|
||||
|
||||
void commandZC() {
|
||||
/* システムの使用環境を変更する */
|
||||
int m = getCaliValue();
|
||||
@@ -394,39 +402,21 @@ void commandZZ2() {
|
||||
void commandZZ3() {
|
||||
/* WINDOWSの全画面サイズや表示色数を変数列に返す */
|
||||
vmvar_t *var = getCaliVariable();
|
||||
DispInfo info;
|
||||
|
||||
ags_getWindowInfo(&info);
|
||||
*var = info.width;
|
||||
*(var + 1) = info.height;
|
||||
*(var + 2) = info.depth;
|
||||
|
||||
write_display_info(var, AGS_DISPLAY_CURRENT);
|
||||
TRACE("ZZ3 %p:",var);
|
||||
}
|
||||
|
||||
void commandZZ4() {
|
||||
/* DIB の全画面 サイズや色数を変数列に返す */
|
||||
vmvar_t *var = getCaliVariable();
|
||||
DispInfo info;
|
||||
|
||||
ags_getDIBInfo(&info);
|
||||
*var = info.width;
|
||||
*(var + 1) = info.height;
|
||||
*(var + 2) = info.depth;
|
||||
|
||||
write_display_info(var, AGS_DISPLAY_DIB);
|
||||
TRACE("ZZ4 %p:",var);
|
||||
}
|
||||
|
||||
void commandZZ5() {
|
||||
/* SYSTEM3.5用表示画面 の サイズや色数を変数列に返す */
|
||||
vmvar_t *var = getCaliVariable();
|
||||
DispInfo info;
|
||||
|
||||
ags_getViewAreaInfo(&info);
|
||||
*var = info.width;
|
||||
*(var + 1) = info.height;
|
||||
*(var + 2) = info.depth;
|
||||
|
||||
write_display_info(var, AGS_DISPLAY_VIEW_AREA);
|
||||
TRACE("ZZ5 %p:",var);
|
||||
}
|
||||
|
||||
@@ -449,13 +439,7 @@ void commandZZ8() {
|
||||
void commandZZ9() {
|
||||
/* 起動時のスクリーンサイズを取得する */
|
||||
vmvar_t *var = getCaliVariable();
|
||||
DispInfo info;
|
||||
|
||||
ags_getWindowInfo(&info);
|
||||
*var = info.width;
|
||||
*(var + 1) = info.height;
|
||||
*(var + 2) = info.depth;
|
||||
|
||||
write_display_info(var, AGS_DISPLAY_DESKTOP);
|
||||
TRACE("ZZ9 %p:",var);
|
||||
}
|
||||
|
||||
|
||||
+19
-45
@@ -35,7 +35,6 @@
|
||||
#include "debugger.h"
|
||||
#include "nact.h"
|
||||
#include "gfx.h"
|
||||
#include "gfx_private.h"
|
||||
#include "scheduler.h"
|
||||
#include "menu.h"
|
||||
#include "modal.h"
|
||||
@@ -54,8 +53,8 @@ enum CustomEventCode {
|
||||
DEBUGGER_COMMAND,
|
||||
};
|
||||
|
||||
/* pointer の状態 */
|
||||
static int mousex, mousey, mouseb;
|
||||
static SDL_Point mouse_pos;
|
||||
static int mouseb;
|
||||
static int mouse_wheel_up, mouse_wheel_down;
|
||||
bool RawKeyInfo[256];
|
||||
|
||||
@@ -264,8 +263,8 @@ void send_agsevent(enum agsevent_type type, int code) {
|
||||
agsevent_t agse = {
|
||||
.type = type,
|
||||
.code = code,
|
||||
.mousex = mousex,
|
||||
.mousey = mousey
|
||||
.mousex = mouse_pos.x,
|
||||
.mousey = mouse_pos.y
|
||||
};
|
||||
nact->ags.eventcb(&agse); // Async in emscripten
|
||||
|
||||
@@ -277,37 +276,16 @@ void send_agsevent(enum agsevent_type type, int code) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void event_set_mouse_location(int x, int y) {
|
||||
// scale mouse x and y
|
||||
float scalex, scaley;
|
||||
SDL_RenderGetScale(gfx_renderer, &scalex, &scaley);
|
||||
x *= scalex;
|
||||
y *= scaley;
|
||||
|
||||
// calculate window borders
|
||||
int logw, logh;
|
||||
SDL_RenderGetLogicalSize(gfx_renderer, &logw, &logh);
|
||||
|
||||
float scalew, scaleh;
|
||||
scalew = logw * scalex;
|
||||
scaleh = logh * scaley;
|
||||
|
||||
int winw, winh;
|
||||
SDL_GetWindowSize(gfx_window, &winw, &winh);
|
||||
|
||||
float border_left = (winw - scalew) / 2;
|
||||
float border_top = (winh - scaleh) / 2;
|
||||
|
||||
// offset x and y by window borders
|
||||
x += border_left;
|
||||
y += border_top;
|
||||
SDL_WarpMouseInWindow(gfx_window, x, y);
|
||||
void event_set_mouse_internal_location(int x, int y) {
|
||||
mouse_pos.x = x;
|
||||
mouse_pos.y = y;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
}
|
||||
|
||||
void event_set_mouse_internal_location(int x, int y) {
|
||||
mousex = x;
|
||||
mousey = y;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
SDL_Point event_get_touch_position(const SDL_TouchFingerEvent *e) {
|
||||
int view_w, view_h;
|
||||
gfx_getViewSize(&view_w, &view_h);
|
||||
return (SDL_Point){e->x * view_w, e->y * view_h};
|
||||
}
|
||||
|
||||
// Stores a deferred touch event (valid if .timestamp != 0) to add a delay
|
||||
@@ -365,7 +343,7 @@ void event_handle_event(SDL_Event *e) {
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (e->window.event) {
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
gfx_dirty = true;
|
||||
gfx_requestRedraw();
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
volume_on_window_focus(false);
|
||||
@@ -381,7 +359,7 @@ void event_handle_event(SDL_Event *e) {
|
||||
break;
|
||||
#endif
|
||||
case SDL_APP_DIDENTERFOREGROUND:
|
||||
gfx_dirty = true;
|
||||
gfx_requestRedraw();
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
keyEventProsess(&e->key, true);
|
||||
@@ -393,7 +371,7 @@ void event_handle_event(SDL_Event *e) {
|
||||
msgskip_activate(!msgskip_isActivated());
|
||||
break;
|
||||
case SDLK_F4:
|
||||
gfx_setFullscreen(!gfx_fullscreen);
|
||||
gfx_setFullscreen(!gfx_isFullscreen());
|
||||
break;
|
||||
}
|
||||
#ifdef __ANDROID__
|
||||
@@ -454,8 +432,7 @@ void event_handle_event(SDL_Event *e) {
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = true;
|
||||
} else {
|
||||
button = SDL_BUTTON_LEFT;
|
||||
mousex = e->tfinger.x * view_w;
|
||||
mousey = e->tfinger.y * view_h;
|
||||
mouse_pos = event_get_touch_position(&e->tfinger);
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
defer_touch_event(&e->tfinger);
|
||||
}
|
||||
@@ -466,16 +443,14 @@ void event_handle_event(SDL_Event *e) {
|
||||
case SDL_FINGERUP:
|
||||
if (SDL_GetNumTouchFingers(e->tfinger.touchId) == 0) {
|
||||
int ags_button = (mouseb & 1 << SDL_BUTTON_LEFT) ? AGSEVENT_BUTTON_LEFT : AGSEVENT_BUTTON_RIGHT;
|
||||
mousex = e->tfinger.x * view_w;
|
||||
mousey = e->tfinger.y * view_h;
|
||||
mouse_pos = event_get_touch_position(&e->tfinger);
|
||||
send_agsevent(AGSEVENT_BUTTON_RELEASE, ags_button);
|
||||
defer_touch_event(&e->tfinger);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERMOTION:
|
||||
mousex = e->tfinger.x * view_w;
|
||||
mousey = e->tfinger.y * view_h;
|
||||
mouse_pos = event_get_touch_position(&e->tfinger);
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
break;
|
||||
|
||||
@@ -608,8 +583,7 @@ int event_get_mouse(SDL_Point *p) {
|
||||
get_event();
|
||||
|
||||
if (p) {
|
||||
p->x = mousex;
|
||||
p->y = mousey;
|
||||
*p = mouse_pos;
|
||||
}
|
||||
|
||||
int m1 = mouseb & (1 << 1) ? SYS35KEY_RET : 0;
|
||||
|
||||
+1
-1
@@ -27,8 +27,8 @@
|
||||
void event_init(void);
|
||||
void event_remove(void);
|
||||
void event_set_joy_device_index(int index);
|
||||
void event_set_mouse_location(int x, int y);
|
||||
void event_set_mouse_internal_location(int x, int y);
|
||||
SDL_Point event_get_touch_position(const SDL_TouchFingerEvent *e);
|
||||
int event_get_key(void);
|
||||
int event_get_mouse(SDL_Point *p);
|
||||
void event_get_wheel(vmvar_t *forward, vmvar_t *back);
|
||||
|
||||
+6
-44
@@ -35,7 +35,7 @@
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "font.h"
|
||||
#include "gfx_private.h"
|
||||
#include "gfx.h"
|
||||
#include "hacks.h"
|
||||
|
||||
typedef struct {
|
||||
@@ -155,44 +155,6 @@ void font_measure_text(FontSpec font, const char *str_utf8, int len, int *w, int
|
||||
}
|
||||
}
|
||||
|
||||
// SDL can't blit ARGB to an indexed bitmap properly, so we do it ourselves.
|
||||
static void gfx_drawAntiAlias_8bpp(int dstx, int dsty, SDL_Surface *src, uint8_t col)
|
||||
{
|
||||
const SDL_Color* palette = gfx_palette->colors;
|
||||
Uint8 cache[256*7];
|
||||
memset(cache, 0, 256);
|
||||
|
||||
for (int y = 0; y < src->h && dsty + y < main_surface->h; y++) {
|
||||
if (dsty + y < 0)
|
||||
continue;
|
||||
uint8_t *sp = (uint8_t*)src->pixels + y * src->pitch;
|
||||
uint8_t *dp = (uint8_t*)main_surface->pixels + (dsty + y) * main_surface->pitch + dstx;
|
||||
for (int x = 0; x < src->w && dstx + x < main_surface->w; x++) {
|
||||
Uint8 r, g, b, alpha;
|
||||
SDL_GetRGBA(*((Uint32*)sp), src->format, &r, &g, &b, &alpha);
|
||||
alpha = alpha >> 5; // reduce bit depth
|
||||
if (!alpha) {
|
||||
// Transparent, do nothing
|
||||
} else if (alpha == 7) {
|
||||
*dp = col; // Fully opaque
|
||||
} else if (cache[*dp] & 1 << alpha) {
|
||||
*dp = cache[alpha << 8 | *dp]; // use cached value
|
||||
} else {
|
||||
// find nearest color in palette
|
||||
cache[*dp] |= 1 << alpha;
|
||||
int c = gfx_nearest_color(
|
||||
(palette[col].r * alpha + palette[*dp].r * (7 - alpha)) / 7,
|
||||
(palette[col].g * alpha + palette[*dp].g * (7 - alpha)) / 7,
|
||||
(palette[col].b * alpha + palette[*dp].b * (7 - alpha)) / 7);
|
||||
cache[alpha << 8 | *dp] = c;
|
||||
*dp = c;
|
||||
}
|
||||
sp += src->format->BytesPerPixel;
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Rect font_draw_text(FontSpec font, int x, int y, const char *str_utf8, uint8_t cl) {
|
||||
SDL_Surface *fs;
|
||||
SDL_Rect r_src, r_dst = {};
|
||||
@@ -212,11 +174,11 @@ SDL_Rect font_draw_text(FontSpec font, int x, int y, const char *str_utf8, uint8
|
||||
if ((game_id == GAME_RANCE3 || game_id == GAME_RANCE3_ENG) && cl == 32)
|
||||
antialias = false;
|
||||
|
||||
if (antialias) {
|
||||
fs = TTF_RenderUTF8_Blended(fontset->id, str_utf8, gfx_palette->colors[cl]);
|
||||
} else {
|
||||
fs = TTF_RenderUTF8_Solid(fontset->id, str_utf8, gfx_palette->colors[cl]);
|
||||
}
|
||||
SDL_Color color = gfx_getPaletteColor(cl);
|
||||
if (antialias)
|
||||
fs = TTF_RenderUTF8_Blended(fontset->id, str_utf8, color);
|
||||
else
|
||||
fs = TTF_RenderUTF8_Solid(fontset->id, str_utf8, color);
|
||||
if (!fs) {
|
||||
WARNING("Text rendering failed: %s", TTF_GetError());
|
||||
return r_dst;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <SDL_surface.h>
|
||||
#include <SDL_video.h>
|
||||
#include "portab.h"
|
||||
#include "ags.h"
|
||||
|
||||
@@ -31,9 +32,12 @@ void gfx_Remove(void);
|
||||
|
||||
/* ウィンド関係 */
|
||||
void gfx_setWorldSize(int width, int height, int depth);
|
||||
void gfx_setWindowSize(int w, int h);
|
||||
void gfx_setViewSize(int w, int h);
|
||||
void gfx_getViewSize(int *width, int *height);
|
||||
SDL_Window *gfx_getWindow(void);
|
||||
void gfx_warpMouse(int x, int y);
|
||||
SDL_Rect gfx_viewToWindowRect(SDL_Rect rect);
|
||||
void gfx_setWindowTitle(char *name);
|
||||
void gfx_getWindowInfo(int *width, int *height, int *depth);
|
||||
void gfx_setFullscreen(bool on);
|
||||
bool gfx_isFullscreen(void);
|
||||
void gfx_raiseWindow(void);
|
||||
@@ -44,10 +48,12 @@ SDL_Surface *gfx_createSurfaceView(SDL_Surface *sf, int x, int y, int w, int h);
|
||||
/* 画面更新 */
|
||||
void gfx_updateArea(SDL_Rect *src, SDL_Point *dst);
|
||||
void gfx_updateAll(SDL_Rect *view_rect);
|
||||
void gfx_requestRedraw(void);
|
||||
void gfx_updateScreen(void);
|
||||
|
||||
/* パレット関係 */
|
||||
void gfx_setPalette(SDL_Color *pal, int first, int count);
|
||||
SDL_Color gfx_getPaletteColor(uint8_t color);
|
||||
|
||||
/* 描画関係 */
|
||||
void gfx_drawRectangle(int x, int y, int w, int h, uint8_t c);
|
||||
@@ -55,6 +61,7 @@ void gfx_fillRectangle(int x, int y, int w, int h, uint8_t c);
|
||||
void gfx_fillRectangleRGB(int x, int y, int w, int h, uint8_t r, uint8_t g, uint8_t b);
|
||||
void gfx_fillCircle(int left, int top, int diameter, uint8_t c);
|
||||
void gfx_drawLine(int x1, int y1, int x2, int y2, uint8_t c);
|
||||
void gfx_drawAntiAlias_8bpp(int x, int y, SDL_Surface *src, uint8_t color);
|
||||
SDL_Rect gfx_floodFill(int x, int y, int col);
|
||||
SDL_Rect gfx_drawString(int x, int y, const char *str_utf8, uint8_t col, FontSpec font);
|
||||
void gfx_copyArea(int sx,int sy, int w, int h, int dx, int dy);
|
||||
|
||||
+48
-1
@@ -43,6 +43,8 @@
|
||||
#include "modal.h"
|
||||
#include "debugger.h"
|
||||
|
||||
static bool gfx_dirty;
|
||||
|
||||
static void gfx_pal_check(void) {
|
||||
if (nact->ags.pal_changed) {
|
||||
nact->ags.pal_changed = false;
|
||||
@@ -56,6 +58,10 @@ static Uint32 palette_color(uint8_t c) {
|
||||
return SDL_MapRGB(main_surface->format, gfx_palette->colors[c].r, gfx_palette->colors[c].g, gfx_palette->colors[c].b);
|
||||
}
|
||||
|
||||
SDL_Color gfx_getPaletteColor(uint8_t color) {
|
||||
return gfx_palette->colors[color];
|
||||
}
|
||||
|
||||
void gfx_updateScreen(void) {
|
||||
if (!gfx_dirty)
|
||||
return;
|
||||
@@ -66,6 +72,10 @@ void gfx_updateScreen(void) {
|
||||
gfx_dirty = false;
|
||||
}
|
||||
|
||||
void gfx_requestRedraw(void) {
|
||||
gfx_dirty = true;
|
||||
}
|
||||
|
||||
/* off-screen の指定領域を Main Window へ転送 */
|
||||
void gfx_updateArea(SDL_Rect *rect, SDL_Point *dst) {
|
||||
SDL_Rect sw = {0, 0, main_surface->w, main_surface->h};
|
||||
@@ -254,7 +264,7 @@ SDL_Rect gfx_floodFill(int x, int y, int c) {
|
||||
}
|
||||
}
|
||||
|
||||
int gfx_nearest_color(int r, int g, int b) {
|
||||
static int nearest_color(int r, int g, int b) {
|
||||
int i, col, mind = INT_MAX;
|
||||
for (i = 0; i < 256; i++) {
|
||||
int dr = r - gfx_palette->colors[i].r;
|
||||
@@ -269,6 +279,43 @@ int gfx_nearest_color(int r, int g, int b) {
|
||||
return col;
|
||||
}
|
||||
|
||||
// SDL can't blit ARGB to an indexed bitmap properly, so we do it ourselves.
|
||||
void gfx_drawAntiAlias_8bpp(int dstx, int dsty, SDL_Surface *src, uint8_t col) {
|
||||
const SDL_Color *palette = gfx_palette->colors;
|
||||
Uint8 cache[256 * 7];
|
||||
memset(cache, 0, 256);
|
||||
|
||||
for (int y = 0; y < src->h && dsty + y < main_surface->h; y++) {
|
||||
if (dsty + y < 0)
|
||||
continue;
|
||||
uint8_t *sp = (uint8_t *)src->pixels + y * src->pitch;
|
||||
uint8_t *dp = (uint8_t *)main_surface->pixels
|
||||
+ (dsty + y) * main_surface->pitch + dstx;
|
||||
for (int x = 0; x < src->w && dstx + x < main_surface->w; x++) {
|
||||
Uint8 r, g, b, alpha;
|
||||
SDL_GetRGBA(*(Uint32 *)sp, src->format, &r, &g, &b, &alpha);
|
||||
alpha >>= 5; // reduce bit depth
|
||||
if (!alpha) {
|
||||
// Transparent, do nothing.
|
||||
} else if (alpha == 7) {
|
||||
*dp = col; // Fully opaque.
|
||||
} else if (cache[*dp] & 1 << alpha) {
|
||||
*dp = cache[alpha << 8 | *dp];
|
||||
} else {
|
||||
cache[*dp] |= 1 << alpha;
|
||||
int c = nearest_color(
|
||||
(palette[col].r * alpha + palette[*dp].r * (7 - alpha)) / 7,
|
||||
(palette[col].g * alpha + palette[*dp].g * (7 - alpha)) / 7,
|
||||
(palette[col].b * alpha + palette[*dp].b * (7 - alpha)) / 7);
|
||||
cache[alpha << 8 | *dp] = c;
|
||||
*dp = c;
|
||||
}
|
||||
sp += src->format->BytesPerPixel;
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Rect gfx_drawString(int x, int y, const char *str_utf8, uint8_t col, FontSpec font) {
|
||||
gfx_pal_check();
|
||||
return font_draw_text(font, x, y, str_utf8, col);
|
||||
|
||||
@@ -30,17 +30,13 @@
|
||||
#include "portab.h"
|
||||
#include "ags.h"
|
||||
|
||||
extern SDL_Window *gfx_window;
|
||||
extern SDL_Renderer *gfx_renderer;
|
||||
extern SDL_Texture *gfx_texture;
|
||||
extern SDL_Palette *gfx_palette;
|
||||
extern surface_t *gfx_dibinfo;
|
||||
extern int view_w;
|
||||
extern int view_h;
|
||||
extern bool gfx_dirty;
|
||||
extern bool gfx_fullscreen;
|
||||
|
||||
int gfx_nearest_color(int r, int g, int b);
|
||||
SDL_Surface *gfx_dib_to_surface_with_alpha(int x, int y, int w, int h);
|
||||
SDL_Surface *gfx_dib_to_surface_colorkey(int x, int y, int w, int h, int col);
|
||||
|
||||
|
||||
+30
-12
@@ -36,7 +36,7 @@
|
||||
#include "xsystem35.h"
|
||||
#include "image.h"
|
||||
|
||||
SDL_Window *gfx_window;
|
||||
static SDL_Window *gfx_window;
|
||||
SDL_Renderer *gfx_renderer;
|
||||
SDL_Texture *gfx_texture;
|
||||
SDL_Surface *main_surface; // offscreen surface
|
||||
@@ -44,8 +44,7 @@ SDL_Palette *gfx_palette;
|
||||
surface_t *gfx_dibinfo;
|
||||
int view_w;
|
||||
int view_h;
|
||||
bool gfx_dirty;
|
||||
bool gfx_fullscreen;
|
||||
static bool gfx_fullscreen;
|
||||
|
||||
static void window_init(const char *render_driver);
|
||||
static void makeDIB(int width, int height, int depth);
|
||||
@@ -57,7 +56,7 @@ int gfx_Initialize(const char *render_driver) {
|
||||
/* offscreen Pixmap */
|
||||
makeDIB(SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT, SYS35_DEFAULT_DEPTH);
|
||||
|
||||
gfx_setWindowSize(SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT);
|
||||
gfx_setViewSize(SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Prevent SDL from calling emscripten_exit_fullscreen on visibilitychange
|
||||
@@ -171,13 +170,32 @@ void gfx_setWorldSize(int width, int height, int depth) {
|
||||
SDL_FillRect(main_surface, NULL, 0);
|
||||
}
|
||||
|
||||
/* display の size と depth の取得 */
|
||||
void gfx_getWindowInfo(int *width, int *height, int *depth) {
|
||||
SDL_DisplayMode dm;
|
||||
SDL_GetCurrentDisplayMode(0, &dm);
|
||||
if (width) *width = dm.w;
|
||||
if (height) *height = dm.h;
|
||||
if (depth) *depth = SDL_BITSPERPIXEL(dm.format);
|
||||
void gfx_getViewSize(int *width, int *height) {
|
||||
if (width)
|
||||
*width = view_w;
|
||||
if (height)
|
||||
*height = view_h;
|
||||
}
|
||||
|
||||
SDL_Window *gfx_getWindow(void) {
|
||||
return gfx_window;
|
||||
}
|
||||
|
||||
static SDL_Point view_to_window_point(int x, int y) {
|
||||
SDL_Point point;
|
||||
SDL_RenderLogicalToWindow(gfx_renderer, x, y, &point.x, &point.y);
|
||||
return point;
|
||||
}
|
||||
|
||||
void gfx_warpMouse(int x, int y) {
|
||||
SDL_Point point = view_to_window_point(x, y);
|
||||
SDL_WarpMouseInWindow(gfx_window, point.x, point.y);
|
||||
}
|
||||
|
||||
SDL_Rect gfx_viewToWindowRect(SDL_Rect rect) {
|
||||
SDL_Point tl = view_to_window_point(rect.x, rect.y);
|
||||
SDL_Point br = view_to_window_point(rect.x + rect.w, rect.y + rect.h);
|
||||
return (SDL_Rect){tl.x, tl.y, br.x - tl.x, br.y - tl.y};
|
||||
}
|
||||
|
||||
/* DIBの取得 */
|
||||
@@ -212,7 +230,7 @@ void gfx_raiseWindow(void) {
|
||||
SDL_RaiseWindow(gfx_window);
|
||||
}
|
||||
|
||||
void gfx_setWindowSize(int w, int h) {
|
||||
void gfx_setViewSize(int w, int h) {
|
||||
if (w == view_w && h == view_h) return;
|
||||
|
||||
view_w = w;
|
||||
|
||||
+8
-10
@@ -139,9 +139,11 @@ bool input_modal_number(INPUTNUM_PARAM *p) {
|
||||
|
||||
#else // not Android or Emscripten
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "nact.h"
|
||||
#include "font.h"
|
||||
#include "gfx_private.h"
|
||||
#include "gfx.h"
|
||||
#include "modal.h"
|
||||
#include "utfsjis.h"
|
||||
|
||||
@@ -223,12 +225,8 @@ static bool menu_string_handler(const SDL_Event *e, modal *modal) {
|
||||
// near the field. `box` is in logical (view) coordinates; convert to window
|
||||
// pixels for SDL_SetTextInputRect.
|
||||
static void set_text_input_rect(mu_Rect box) {
|
||||
SDL_Rect r = { box.x, box.y, box.w, box.h };
|
||||
int x2, y2;
|
||||
SDL_RenderLogicalToWindow(gfx_renderer, box.x, box.y, &r.x, &r.y);
|
||||
SDL_RenderLogicalToWindow(gfx_renderer, box.x + box.w, box.y + box.h, &x2, &y2);
|
||||
r.w = x2 - r.x;
|
||||
r.h = y2 - r.y;
|
||||
SDL_Rect r = gfx_viewToWindowRect(
|
||||
(SDL_Rect){box.x, box.y, box.w, box.h});
|
||||
SDL_SetTextInputRect(&r);
|
||||
}
|
||||
|
||||
@@ -270,7 +268,7 @@ static bool inputstring_build(mu_Context *ctx, modal *modal) {
|
||||
int w = 320;
|
||||
int h = 3 * (row_h + ctx->style->spacing) + ctx->style->padding * 2
|
||||
+ ctx->style->title_height;
|
||||
mu_Rect r = mu_rect((view_w - w) / 2, (view_h - h) / 2, w, h);
|
||||
mu_Rect r = modal_centered_rect(w, h);
|
||||
|
||||
if (mu_begin_window_ex(ctx, title, r,
|
||||
MU_OPT_NORESIZE | MU_OPT_NOCLOSE | MU_OPT_NOSCROLL)) {
|
||||
@@ -327,7 +325,7 @@ bool input_modal_string(INPUTSTRING_PARAM *p) {
|
||||
|
||||
// Look up an AGS color index in the active palette and return it as a mu_Color.
|
||||
static mu_Color palette_color(int index) {
|
||||
SDL_Color c = gfx_palette->colors[index];
|
||||
SDL_Color c = gfx_getPaletteColor(index);
|
||||
return (mu_Color){ c.r, c.g, c.b, 255 };
|
||||
}
|
||||
|
||||
@@ -436,7 +434,7 @@ static bool inputnumber_build(mu_Context *ctx, modal *modal) {
|
||||
int w = 240;
|
||||
int h = 3 * (row_h + ctx->style->spacing) + ctx->style->padding * 2
|
||||
+ ctx->style->title_height;
|
||||
mu_Rect r = mu_rect((view_w - w) / 2, (view_h - h) / 2, w, h);
|
||||
mu_Rect r = modal_centered_rect(w, h);
|
||||
|
||||
if (mu_begin_window_ex(ctx, title, r,
|
||||
MU_OPT_NORESIZE | MU_OPT_NOCLOSE | MU_OPT_NOSCROLL)) {
|
||||
|
||||
+7
-5
@@ -50,12 +50,14 @@ EM_JS(void, menu_setSkipState, (bool enabled, bool activated), {
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "event.h"
|
||||
#include "system.h"
|
||||
#include "nact.h"
|
||||
#include "menu.h"
|
||||
#include "gfx_private.h"
|
||||
#include "gfx.h"
|
||||
#include "msgskip.h"
|
||||
#include "modal.h"
|
||||
#include "volume.h"
|
||||
@@ -105,8 +107,8 @@ static bool menu_popup_handler(const SDL_Event *e, modal *modal) {
|
||||
st->touch_armed = true;
|
||||
} else if (e->type == SDL_FINGERDOWN && st->touch_armed) {
|
||||
// A tap outside the menu dismisses it.
|
||||
int x = e->tfinger.x * view_w, y = e->tfinger.y * view_h;
|
||||
if (!point_in_rect(x, y, st->rect))
|
||||
SDL_Point p = event_get_touch_position(&e->tfinger);
|
||||
if (!point_in_rect(p.x, p.y, st->rect))
|
||||
st->base.cancelled = true;
|
||||
}
|
||||
return modal_default_handler(e, modal);
|
||||
@@ -124,7 +126,7 @@ static bool menu_build(mu_Context *ctx, modal *modal) {
|
||||
int w = 200;
|
||||
// `rows` rows with (rows - 1) inter-row gaps, plus the window's body padding.
|
||||
int h = rows * row_h + (rows - 1) * ctx->style->spacing + ctx->style->padding * 2;
|
||||
mu_Rect r = mu_rect((view_w - w) / 2, (view_h - h) / 2, w, h);
|
||||
mu_Rect r = modal_centered_rect(w, h);
|
||||
st->rect = r;
|
||||
|
||||
if (mu_begin_window_ex(ctx, "menu", r,
|
||||
@@ -198,7 +200,7 @@ static bool confirm_lose_progress(const char *title, const char *confirm_label)
|
||||
};
|
||||
const SDL_MessageBoxData messagebox_data = {
|
||||
.flags = SDL_MESSAGEBOX_INFORMATION,
|
||||
.window = gfx_window,
|
||||
.window = gfx_getWindow(),
|
||||
.title = title,
|
||||
.message = _("Any unsaved progress will be lost."),
|
||||
.numbuttons = SDL_arraysize(buttons),
|
||||
|
||||
+19
-14
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "event.h"
|
||||
#include "font.h"
|
||||
#include "gfx.h"
|
||||
#include "gfx_private.h"
|
||||
#include "modal.h"
|
||||
#include "nact.h"
|
||||
@@ -54,7 +55,7 @@ static enum {
|
||||
} touch_phase;
|
||||
static int touch_hover_frames; // frames left to dwell in TOUCH_HOVER
|
||||
static bool touch_release_after_press; // finger lifted early; release once pressed
|
||||
static int touch_x, touch_y;
|
||||
static SDL_Point touch_pos;
|
||||
|
||||
static const FontSpec menu_font = { FONT_GOTHIC, FONT_WEIGHT_NORMAL, MODAL_FONT_SIZE };
|
||||
|
||||
@@ -137,23 +138,20 @@ bool modal_default_handler(const SDL_Event *e, modal *modal) {
|
||||
// Touch handling (see touch_phase above). The press/release is driven
|
||||
// from the frame loop in modal_run(), not emitted here directly.
|
||||
case SDL_FINGERDOWN:
|
||||
touch_x = e->tfinger.x * view_w;
|
||||
touch_y = e->tfinger.y * view_h;
|
||||
mu_input_mousemove(ctx, touch_x, touch_y);
|
||||
touch_pos = event_get_touch_position(&e->tfinger);
|
||||
mu_input_mousemove(ctx, touch_pos.x, touch_pos.y);
|
||||
touch_phase = TOUCH_HOVER;
|
||||
touch_hover_frames = TOUCH_HOVER_FRAMES;
|
||||
touch_release_after_press = false;
|
||||
break;
|
||||
case SDL_FINGERMOTION:
|
||||
touch_x = e->tfinger.x * view_w;
|
||||
touch_y = e->tfinger.y * view_h;
|
||||
mu_input_mousemove(ctx, touch_x, touch_y);
|
||||
touch_pos = event_get_touch_position(&e->tfinger);
|
||||
mu_input_mousemove(ctx, touch_pos.x, touch_pos.y);
|
||||
break;
|
||||
case SDL_FINGERUP:
|
||||
touch_x = e->tfinger.x * view_w;
|
||||
touch_y = e->tfinger.y * view_h;
|
||||
touch_pos = event_get_touch_position(&e->tfinger);
|
||||
if (touch_phase == TOUCH_PRESS) {
|
||||
mu_input_mouseup(ctx, touch_x, touch_y, MU_MOUSE_LEFT);
|
||||
mu_input_mouseup(ctx, touch_pos.x, touch_pos.y, MU_MOUSE_LEFT);
|
||||
touch_phase = TOUCH_NONE;
|
||||
} else if (touch_phase == TOUCH_HOVER) {
|
||||
// Tap ended before the press was emitted; release right after it.
|
||||
@@ -294,6 +292,13 @@ bool modal_handle_event(const SDL_Event *e) {
|
||||
return current_modal->handler(e, current_modal);
|
||||
}
|
||||
|
||||
mu_Rect modal_centered_rect(int width, int height) {
|
||||
int view_w, view_h;
|
||||
gfx_getViewSize(&view_w, &view_h);
|
||||
return mu_rect((view_w - width) / 2, (view_h - height) / 2,
|
||||
width, height);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE // Prevent inlining, because this function is listed in ASYNCIFY_ADD
|
||||
void modal_run(modal *m) {
|
||||
assert(!ctx); // modals are not nestable
|
||||
@@ -314,12 +319,12 @@ void modal_run(modal *m) {
|
||||
if (touch_hover_frames > 0) {
|
||||
touch_hover_frames--;
|
||||
} else {
|
||||
mu_input_mousedown(ctx, touch_x, touch_y, MU_MOUSE_LEFT);
|
||||
mu_input_mousedown(ctx, touch_pos.x, touch_pos.y, MU_MOUSE_LEFT);
|
||||
touch_phase = TOUCH_PRESS;
|
||||
}
|
||||
}
|
||||
if (touch_phase == TOUCH_PRESS && touch_release_after_press) {
|
||||
mu_input_mouseup(ctx, touch_x, touch_y, MU_MOUSE_LEFT);
|
||||
mu_input_mouseup(ctx, touch_pos.x, touch_pos.y, MU_MOUSE_LEFT);
|
||||
touch_phase = TOUCH_NONE;
|
||||
touch_release_after_press = false;
|
||||
}
|
||||
@@ -334,7 +339,7 @@ void modal_run(modal *m) {
|
||||
mu_Id hash = mu_get_id(ctx, ctx->command_list.items, ctx->command_list.idx);
|
||||
if (hash != prev_hash) {
|
||||
prev_hash = hash;
|
||||
gfx_dirty = true;
|
||||
gfx_requestRedraw();
|
||||
}
|
||||
nact->callback();
|
||||
sys_wait_vsync(); // -> gfx_updateScreen() -> modal_render_overlay()
|
||||
@@ -343,7 +348,7 @@ void modal_run(modal *m) {
|
||||
current_modal = NULL;
|
||||
free(ctx);
|
||||
ctx = NULL;
|
||||
gfx_dirty = true; // repaint once more to clear the overlay
|
||||
gfx_requestRedraw(); // repaint once more to clear the overlay
|
||||
|
||||
// The gesture that opened/dismissed the dialog must not leave the engine
|
||||
// with a key or button stuck "down".
|
||||
|
||||
@@ -48,6 +48,9 @@ void modal_run(modal *modal);
|
||||
// consumed, false when no modal is running or the handler falls through.
|
||||
bool modal_handle_event(const union SDL_Event *e);
|
||||
|
||||
// Return a rectangle of the requested size centered in the logical view.
|
||||
mu_Rect modal_centered_rect(int width, int height);
|
||||
|
||||
// Render the active modal's overlay onto the screen. Call this from the screen
|
||||
// update path; it is a no-op when no modal is running.
|
||||
void modal_render_overlay(void);
|
||||
|
||||
+1
-2
@@ -21,7 +21,6 @@
|
||||
#include <SDL.h>
|
||||
#include "debugger.h"
|
||||
#include "gfx.h"
|
||||
#include "gfx_private.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -136,5 +135,5 @@ void sys_show_message_box(enum messagebox_type type, const char* title_utf8, con
|
||||
case MESSAGEBOX_WARNING: flags = SDL_MESSAGEBOX_WARNING; break;
|
||||
case MESSAGEBOX_INFO: flags = SDL_MESSAGEBOX_INFORMATION; break;
|
||||
}
|
||||
SDL_ShowSimpleMessageBox(flags, title_utf8, message_utf8, gfx_window);
|
||||
SDL_ShowSimpleMessageBox(flags, title_utf8, message_utf8, gfx_getWindow());
|
||||
}
|
||||
|
||||
+1
-2
@@ -34,7 +34,6 @@
|
||||
#include "utfsjis.h"
|
||||
#include "music.h"
|
||||
#include "modal.h"
|
||||
#include "gfx_private.h"
|
||||
|
||||
// Volume Valancer で扱う最大チャンネル数
|
||||
#define MAXVOLCH 16
|
||||
@@ -193,7 +192,7 @@ static bool volume_build(mu_Context *ctx, modal *modal) {
|
||||
+ ctx->style->padding * 2;
|
||||
int h = (nch + 1) * (row_h + ctx->style->spacing) + ctx->style->padding * 2
|
||||
+ ctx->style->title_height;
|
||||
mu_Rect r = mu_rect((view_w - w) / 2, (view_h - h) / 2, w, h);
|
||||
mu_Rect r = modal_centered_rect(w, h);
|
||||
|
||||
if (mu_begin_window_ex(ctx, _("Sound Settings"), r,
|
||||
MU_OPT_NORESIZE | MU_OPT_NOSCROLL)) {
|
||||
|
||||
+3
-3
@@ -20,7 +20,7 @@
|
||||
#include <commctrl.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include "input_modal.h"
|
||||
#include "gfx_private.h"
|
||||
#include "gfx.h"
|
||||
#include "resources.h"
|
||||
|
||||
static HWND get_hwnd(SDL_Window *window) {
|
||||
@@ -139,7 +139,7 @@ bool input_modal_string(INPUTSTRING_PARAM *p) {
|
||||
DialogBoxParamW(
|
||||
GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCEW(IDD_TEXTINPUT),
|
||||
get_hwnd(gfx_window),
|
||||
get_hwnd(gfx_getWindow()),
|
||||
text_dialog_proc,
|
||||
(LPARAM)p);
|
||||
return true;
|
||||
@@ -149,7 +149,7 @@ bool input_modal_number(INPUTNUM_PARAM *p) {
|
||||
INT_PTR ret = DialogBoxParamW(
|
||||
GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCEW(IDD_NUMINPUT),
|
||||
get_hwnd(gfx_window),
|
||||
get_hwnd(gfx_getWindow()),
|
||||
num_dialog_proc,
|
||||
(LPARAM)p);
|
||||
return ret == IDOK;
|
||||
|
||||
+11
-8
@@ -18,12 +18,12 @@
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include "system.h"
|
||||
#include "menu.h"
|
||||
#include "nact.h"
|
||||
#include "gfx.h"
|
||||
#include "gfx_private.h"
|
||||
#include "resources.h"
|
||||
#include "msgskip.h"
|
||||
#include "texthook.h"
|
||||
@@ -46,7 +46,7 @@ static void saveScreenshot(void) {
|
||||
|
||||
OPENFILENAME ofn = {
|
||||
.lStructSize = sizeof(OPENFILENAME),
|
||||
.hwndOwner = get_hwnd(gfx_window),
|
||||
.hwndOwner = get_hwnd(gfx_getWindow()),
|
||||
.lpstrFilter = "Bitmap files (*.bmp)\0*.bmp\0All files (*.*)\0*.*\0",
|
||||
.lpstrFile = pathbuf,
|
||||
.nMaxFile = MAX_PATH,
|
||||
@@ -79,12 +79,15 @@ static bool toggle_menu_item(UINT id, bool *checked_out) {
|
||||
}
|
||||
|
||||
void menu_init(void) {
|
||||
SDL_Window *window = gfx_getWindow();
|
||||
int view_w, view_h;
|
||||
gfx_getViewSize(&view_w, &view_h);
|
||||
HINSTANCE hinst = (HINSTANCE)GetModuleHandle(NULL);
|
||||
hmenu = LoadMenu(hinst, MAKEINTRESOURCE(IDR_MENU1));
|
||||
SetMenu(get_hwnd(gfx_window), hmenu);
|
||||
SetMenu(get_hwnd(window), hmenu);
|
||||
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
||||
// Let SDL recalc the window size, taking menu height into account.
|
||||
SDL_SetWindowSize(gfx_window, view_w, view_h);
|
||||
SDL_SetWindowSize(window, view_w, view_h);
|
||||
CheckMenuItem(hmenu, ID_OPTION_MOUSE_MOVE, MF_BYCOMMAND | MFS_CHECKED);
|
||||
}
|
||||
|
||||
@@ -108,11 +111,11 @@ void win_menu_onSysWMEvent(SDL_SysWMmsg* msg) {
|
||||
break;
|
||||
case ID_SCREEN_WINDOW:
|
||||
gfx_setFullscreen(false);
|
||||
SetMenu(get_hwnd(gfx_window), hmenu);
|
||||
SetMenu(get_hwnd(gfx_getWindow()), hmenu);
|
||||
break;
|
||||
case ID_SCREEN_FULL:
|
||||
gfx_setFullscreen(true);
|
||||
SetMenu(get_hwnd(gfx_window), NULL);
|
||||
SetMenu(get_hwnd(gfx_getWindow()), NULL);
|
||||
break;
|
||||
case ID_SCREEN_INTEGER_SCALING:
|
||||
if (toggle_menu_item(ID_SCREEN_INTEGER_SCALING, &checked))
|
||||
@@ -140,11 +143,11 @@ void win_menu_onSysWMEvent(SDL_SysWMmsg* msg) {
|
||||
void win_menu_onMouseMotion(int x, int y) {
|
||||
if (!gfx_isFullscreen())
|
||||
return;
|
||||
SetMenu(get_hwnd(gfx_window), y > 0 ? NULL : hmenu);
|
||||
SetMenu(get_hwnd(gfx_getWindow()), y > 0 ? NULL : hmenu);
|
||||
}
|
||||
|
||||
void menu_setSkipState(bool enabled, bool activated) {
|
||||
HWND hwnd = get_hwnd(gfx_window);
|
||||
HWND hwnd = get_hwnd(gfx_getWindow());
|
||||
|
||||
EnableMenuItem(hmenu, ID_MSGSKIP, enabled ? MF_ENABLED : MF_GRAYED);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
%#stack.adv:
|
||||
%#math.adv:
|
||||
%#variable.adv:
|
||||
%#unitmap.adv:
|
||||
|
||||
HH0,tests_passed: ' tests passed' R
|
||||
HH0,tests_failed: ' tests failed' R
|
||||
|
||||
@@ -7,6 +7,7 @@ strvar.adv
|
||||
stack.adv
|
||||
math.adv
|
||||
variable.adv
|
||||
unitmap.adv
|
||||
|
||||
#DLLHeader
|
||||
ShString.HEL
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
MS FILE,"unitmap.adv":
|
||||
!unitmap_src0:11!!unitmap_src1:22!!unitmap_src2:33!!unitmap_src3:44!
|
||||
!unitmap_dst0:0!!unitmap_dst1:0!!unitmap_dst2:0!!unitmap_dst3:0!!unitmap_sentinel:1234!
|
||||
|
||||
VC 1,0,0,2,2,1,1:
|
||||
|
||||
; VR copies consecutive 16-bit VM variables to the unit map.
|
||||
VR 0,3,unitmap_src0:
|
||||
VG 0,3,0,0:
|
||||
~AssertEquals RND,11,__LINE__:
|
||||
VG 0,3,1,0:
|
||||
~AssertEquals RND,22,__LINE__:
|
||||
VG 0,3,0,1:
|
||||
~AssertEquals RND,33,__LINE__:
|
||||
VG 0,3,1,1:
|
||||
~AssertEquals RND,44,__LINE__:
|
||||
|
||||
; VW performs the reverse conversion without overwriting adjacent variables.
|
||||
VS 0,3,0,0,101:
|
||||
VS 0,3,1,0,102:
|
||||
VS 0,3,0,1,103:
|
||||
VS 0,3,1,1,104:
|
||||
VW 0,3,unitmap_dst0:
|
||||
~AssertEquals unitmap_dst0,101,__LINE__:
|
||||
~AssertEquals unitmap_dst1,102,__LINE__:
|
||||
~AssertEquals unitmap_dst2,103,__LINE__:
|
||||
~AssertEquals unitmap_dst3,104,__LINE__:
|
||||
~AssertEquals unitmap_sentinel,1234,__LINE__:
|
||||
|
||||
%0:
|
||||
Reference in New Issue
Block a user