mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
M-26: [A/E] atexit config+window persistence, --help/--version
- main.c: atexit(portAtExit) = videoSaveWindowState() + configSave(), fires on clean exit(0) (SDL_QUIT/ESC/close); abort() paths skip it. - video.c: new [Window] ini section (Width/Height/X/Y/Maximized); sentinels (0 / -1) reproduce native-size + centered. videoSaveWindowState() snapshots live geometry via the SDL2 wapi backend. Video.Fullscreen now round-trips. - main.c: --version / --help (-h) before crashInit — build id, usage, 21-level -level_XX table. - Verified: -level_09/-level_20 crash-free 6/6 frames, ge007.ini gains populated [Window] block on exit.
This commit is contained in:
1 parent
905eebf447
commit
db1834ca9b
3 files changed
+112
-6
No files matched your search
@@ -48,6 +48,10 @@ void videoResetTextureCache(void);
|
|||||||
/* Current FPS (measured). */
|
/* Current FPS (measured). */
|
||||||
float videoGetFPS(void);
|
float videoGetFPS(void);
|
||||||
|
|
||||||
|
/* Snapshot live window geometry into the config vars (call before configSave
|
||||||
|
* on a clean exit). No-op if the window isn't up. */
|
||||||
|
void videoSaveWindowState(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,10 +38,59 @@
|
|||||||
extern void mainproc(void *args);
|
extern void mainproc(void *args);
|
||||||
extern OSThread mainThread; /* src/init.c:75 */
|
extern OSThread mainThread; /* src/init.c:75 */
|
||||||
|
|
||||||
|
/* name:number pairs for the 21 solo levels (matches tools_pc/level_sweep.sh
|
||||||
|
* and playtest.sh --list). boss.c decodes -level_XX as d0*10 + d1 - 0x210. */
|
||||||
|
static const struct { const char *name; const char *num; } kSoloLevels[] = {
|
||||||
|
{"Dam","33"}, {"Facility","34"}, {"Runway","35"}, {"Surface1","36"},
|
||||||
|
{"Bunker1","09"}, {"Silo","20"}, {"Frigate","26"}, {"Surface2","43"},
|
||||||
|
{"Bunker2","27"}, {"Statue","22"}, {"Archives","24"}, {"Streets","29"},
|
||||||
|
{"Depot","30"}, {"Train","25"}, {"Jungle","37"}, {"Control","23"},
|
||||||
|
{"Caverns","39"}, {"Cradle","41"}, {"Aztec","28"}, {"Egypt","32"},
|
||||||
|
{"Cuba","54"},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void portPrintVersion(void)
|
||||||
|
{
|
||||||
|
printf("GoldenEye 007 PC port\n"
|
||||||
|
" rom : %s\n"
|
||||||
|
" platform : %s\n"
|
||||||
|
" build : %s\n",
|
||||||
|
GE007_ROMID, GE007_TARGET_PLATFORM, GE007_VERSION_HASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void portPrintHelp(const char *argv0)
|
||||||
|
{
|
||||||
|
portPrintVersion();
|
||||||
|
printf("\nusage: %s [options] [-level_XX]\n\n"
|
||||||
|
" --help this message\n"
|
||||||
|
" --version build id only\n"
|
||||||
|
" -level_XX boot straight into a solo level (per-level\n"
|
||||||
|
" memory pools are auto-injected)\n\n"
|
||||||
|
"config: ge007.ini in the data dir (written on first run).\n\n"
|
||||||
|
"solo levels (-level_XX):\n", argv0 ? argv0 : "ge007");
|
||||||
|
for (size_t i = 0; i < sizeof(kSoloLevels) / sizeof(kSoloLevels[0]); ++i) {
|
||||||
|
printf(" %-10s -level_%s\n", kSoloLevels[i].name, kSoloLevels[i].num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void portAtExit(void)
|
||||||
|
{
|
||||||
|
/* Clean-exit only (exit(0) from videoPumpEvents). Crash/fatal paths call
|
||||||
|
* abort(), which does not run atexit handlers. */
|
||||||
|
videoSaveWindowState();
|
||||||
|
configSave();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
sysSetArgs(argc, argv);
|
sysSetArgs(argc, argv);
|
||||||
|
|
||||||
|
if (sysArgCheck("--version")) { portPrintVersion(); return 0; }
|
||||||
|
if (sysArgCheck("--help") || sysArgCheck("-h")) {
|
||||||
|
portPrintHelp(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sysLogPrintf(LOG_INFO, "GoldenEye 007 PC port starting "
|
sysLogPrintf(LOG_INFO, "GoldenEye 007 PC port starting "
|
||||||
"(%s, %s)", GE007_ROMID, GE007_VERSION_HASH);
|
"(%s, %s)", GE007_ROMID, GE007_VERSION_HASH);
|
||||||
|
|
||||||
@@ -50,6 +99,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* 1. Platform + config + filesystem. */
|
/* 1. Platform + config + filesystem. */
|
||||||
configLoad();
|
configLoad();
|
||||||
|
atexit(portAtExit); /* persist config + window geometry on clean exit */
|
||||||
|
|
||||||
/* 2. Load the ROM and map segments. */
|
/* 2. Load the ROM and map segments. */
|
||||||
if (romdataInit() != 0) {
|
if (romdataInit() != 0) {
|
||||||
|
|||||||
+58
-6
@@ -57,6 +57,18 @@ static int cfgMSAA = 1; /* 1/2/4/8 samples; 1 = off
|
|||||||
static int cfgTexFilter = 1; /* 0 = nearest (crisp), 1 = bilinear */
|
static int cfgTexFilter = 1; /* 0 = nearest (crisp), 1 = bilinear */
|
||||||
static int cfgFullscreen = 0; /* 0 = windowed, 1 = borderless fullscreen */
|
static int cfgFullscreen = 0; /* 0 = windowed, 1 = borderless fullscreen */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* [Window] persistence. Defaults are sentinels that reproduce the old
|
||||||
|
* hardcoded behaviour (native size, centered): W/H = 0 -> native, X/Y = -1 ->
|
||||||
|
* let SDL centre the window. videoSaveWindowState() writes the live geometry
|
||||||
|
* back into these on a clean exit (see main.c's atexit handler).
|
||||||
|
*/
|
||||||
|
static int cfgWinW = 0;
|
||||||
|
static int cfgWinH = 0;
|
||||||
|
static int cfgWinX = -1;
|
||||||
|
static int cfgWinY = -1;
|
||||||
|
static int cfgWinMax = 0;
|
||||||
|
|
||||||
PD_CONSTRUCTOR static void videoConfigInit(void)
|
PD_CONSTRUCTOR static void videoConfigInit(void)
|
||||||
{
|
{
|
||||||
configRegisterInt("Video.VSync", &cfgVSync, 0, 1);
|
configRegisterInt("Video.VSync", &cfgVSync, 0, 1);
|
||||||
@@ -64,6 +76,11 @@ PD_CONSTRUCTOR static void videoConfigInit(void)
|
|||||||
configRegisterInt("Video.MSAA", &cfgMSAA, 1, 8);
|
configRegisterInt("Video.MSAA", &cfgMSAA, 1, 8);
|
||||||
configRegisterInt("Video.TextureFilter", &cfgTexFilter, 0, 1);
|
configRegisterInt("Video.TextureFilter", &cfgTexFilter, 0, 1);
|
||||||
configRegisterInt("Video.Fullscreen", &cfgFullscreen, 0, 1);
|
configRegisterInt("Video.Fullscreen", &cfgFullscreen, 0, 1);
|
||||||
|
configRegisterInt("Window.Width", &cfgWinW, 0, 16384);
|
||||||
|
configRegisterInt("Window.Height", &cfgWinH, 0, 16384);
|
||||||
|
configRegisterInt("Window.X", &cfgWinX, -1, 16384);
|
||||||
|
configRegisterInt("Window.Y", &cfgWinY, -1, 16384);
|
||||||
|
configRegisterInt("Window.Maximized", &cfgWinMax, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 frames = 0;
|
static u32 frames = 0;
|
||||||
@@ -88,19 +105,23 @@ int videoInit(void)
|
|||||||
/* MSAA: snap the requested sample count down to a supported power of two. */
|
/* MSAA: snap the requested sample count down to a supported power of two. */
|
||||||
gfx_msaa_level = cfgMSAA >= 8 ? 8 : cfgMSAA >= 4 ? 4 : cfgMSAA >= 2 ? 2 : 1;
|
gfx_msaa_level = cfgMSAA >= 8 ? 8 : cfgMSAA >= 4 ? 4 : cfgMSAA >= 2 ? 2 : 1;
|
||||||
|
|
||||||
|
int winW = cfgWinW > 0 ? cfgWinW : GE_NATIVE_W;
|
||||||
|
int winH = cfgWinH > 0 ? cfgWinH : GE_NATIVE_H;
|
||||||
|
int havePos = (cfgWinX >= 0 && cfgWinY >= 0);
|
||||||
|
|
||||||
struct GfxInitSettings set = {
|
struct GfxInitSettings set = {
|
||||||
.wapi = wmAPI,
|
.wapi = wmAPI,
|
||||||
.rapi = renderingAPI,
|
.rapi = renderingAPI,
|
||||||
.window_settings = {
|
.window_settings = {
|
||||||
.title = "GoldenEye 007",
|
.title = "GoldenEye 007",
|
||||||
.width = GE_NATIVE_W,
|
.width = winW,
|
||||||
.height = GE_NATIVE_H,
|
.height = winH,
|
||||||
.x = 100,
|
.x = havePos ? cfgWinX : 100,
|
||||||
.y = 100,
|
.y = havePos ? cfgWinY : 100,
|
||||||
.fullscreen = cfgFullscreen != 0,
|
.fullscreen = cfgFullscreen != 0,
|
||||||
.fullscreen_is_exclusive = false,
|
.fullscreen_is_exclusive = false,
|
||||||
.maximized = false,
|
.maximized = cfgWinMax != 0,
|
||||||
.centered = true,
|
.centered = !havePos,
|
||||||
.allow_hidpi = false,
|
.allow_hidpi = false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -292,6 +313,37 @@ float videoGetFPS(void)
|
|||||||
return vidAvgFPS;
|
return vidAvgFPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Snapshot the current window geometry into the [Window] / [Video] config
|
||||||
|
* vars so the next configSave() persists it. Called from main.c's atexit
|
||||||
|
* handler (runs on the host thread, which owns the window). A maximized or
|
||||||
|
* fullscreen window keeps its last restored size/pos on disk; only the
|
||||||
|
* flag is updated.
|
||||||
|
*/
|
||||||
|
void videoSaveWindowState(void)
|
||||||
|
{
|
||||||
|
if (!initDone || !wmAPI) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t fs = wmAPI->get_fullscreen_state ? wmAPI->get_fullscreen_state() : 0;
|
||||||
|
int32_t mx = wmAPI->get_maximized_state ? wmAPI->get_maximized_state() : 0;
|
||||||
|
cfgFullscreen = fs ? 1 : 0;
|
||||||
|
cfgWinMax = mx ? 1 : 0;
|
||||||
|
|
||||||
|
if (!fs && !mx && wmAPI->get_dimensions) {
|
||||||
|
uint32_t w = 0, h = 0;
|
||||||
|
int32_t x = 0, y = 0;
|
||||||
|
wmAPI->get_dimensions(&w, &h, &x, &y);
|
||||||
|
if (w > 0 && h > 0) {
|
||||||
|
cfgWinW = (int)w;
|
||||||
|
cfgWinH = (int)h;
|
||||||
|
cfgWinX = x < 0 ? 0 : x;
|
||||||
|
cfgWinY = y < 0 ? 0 : y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void videoUpdateNativeResolution(s32 w, s32 h)
|
void videoUpdateNativeResolution(s32 w, s32 h)
|
||||||
{
|
{
|
||||||
if (w <= 0 || h <= 0) {
|
if (w <= 0 || h <= 0) {
|
||||||
|
|||||||
Reference in new issue
Block a user