Re: [hatari-devel] Seeing Hatari help on Windows? |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
- To: hatari-devel@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [hatari-devel] Seeing Hatari help on Windows?
- From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
- Date: Fri, 6 Jun 2025 00:43:39 +0300
- Dkim-filter: OpenDKIM Filter v2.11.0 smtp.dnamail.fi 1372E2113E00
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=helsinkinet.fi; s=2025-03; t=1749159820; bh=ZxZGSH5JciKt3qGg8EintrMzvZQTuqME/wPKxGQKjKo=; h=Date:Subject:To:References:From:In-Reply-To:From; b=KS91u/cBhdhaAoNJGf5hwctP+kwz8Lw5sonJ8L08Jdna0N+PPq33B4VRr98R+cDC0 5Oh8tN4SPpXZYnM0/THGCTC+tLwFs7/77y9hd8S1gaWSnQt+ZpwKzkpkNW4caMUUJc djQD+ijJK239IsYZF+2INSgNvAiQmiR2viCZVkw2+nHemlcH89SZdIQqnb+rQEv9+S D3aEAvL4xar6CgFJcMj0Tv0icW+leDcG6Ww4b6JXBIaEDM7ahjNR0E8nGooihfYiRO cinE2V6nukYrsrf6/DEFZ0NJ8rSjZeWj7bgHU0LMIYZo+g/EkM7GRrQ9DYkgfY2ukt G7tEsCZJM1j/Q==
Hi,
On 5.6.2025 18.27, Christian Zietz wrote:
Yes, this works. Running, for example, ...
....
... opens a separate console window with the output, and then waits for
a keypress so that the user can read the output.
Thanks for testing!
As it works, I added similar handling for rest of the exit cases where
it would be relevant to open console on Windows. Patches attached.
Does somebody have objections against merging them before release?
Or other comments/suggestions for those changes?
- Eero
From 89e199541eeb340d7bd7940361bd271ba829f20d Mon Sep 17 00:00:00 2001
From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
Date: Fri, 6 Jun 2025 00:26:37 +0300
Subject: [PATCH 2/2] Invoke Windows console also for other relevant exit
errors
Skips things that should not matter for Windows i.e. error exits that
happen in the CLI console, are for small size alloc failures, or OSX.
---
doc/release-notes.txt | 3 +++
src/cpu/memory.c | 6 ++----
src/screen.c | 28 ++++++++++++----------------
src/tos.c | 3 +--
src/vdi.c | 3 +--
5 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/doc/release-notes.txt b/doc/release-notes.txt
index c9dae80a..d2e7be5a 100644
--- a/doc/release-notes.txt
+++ b/doc/release-notes.txt
@@ -47,6 +47,9 @@ Emulator improvements:
- SDL-GUI (and config options):
- Improvements to GUI font characters
- Add separate option for enabling/disabling >=030 CPU data cache
+- Windows:
+ - Open console window for error and help output, so that Windows
+ users can actually see them
- Keyboard:
- Symbolic key mapping improved for different TOS language versions
- Made it possible to use a mapping file with fallback to scancode mapping
diff --git a/src/cpu/memory.c b/src/cpu/memory.c
index 7bf97d2c..eeb819f4 100644
--- a/src/cpu/memory.c
+++ b/src/cpu/memory.c
@@ -1680,9 +1680,8 @@ void memory_init(uae_u32 NewSTMemSize, uae_u32 NewTTMemSize, uae_u32 NewRomMemSt
STmemory = malloc(alloc_size);
if (!STmemory)
{
- write_log ("virtual memory exhausted (STmemory)!\n");
SDL_Quit();
- exit(1);
+ Main_ErrorExit("virtual memory exhausted (STmemory)", NULL, 1);
}
memset(STmemory, 0, alloc_size);
@@ -1696,9 +1695,8 @@ void memory_init(uae_u32 NewSTMemSize, uae_u32 NewTTMemSize, uae_u32 NewRomMemSt
ROMmemory = malloc(2*1024*1024);
if (!ROMmemory)
{
- fprintf(stderr, "Out of memory (ROM/IO mem)!\n");
SDL_Quit();
- exit(1);
+ Main_ErrorExit("Out of memory (ROM/IO mem)", NULL, 1);
}
}
diff --git a/src/screen.c b/src/screen.c
index e64701ec..0a76ed16 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -371,9 +371,9 @@ void Screen_SetTextureScale(int width, int height, int win_width, int win_height
width, height);
if (!sdlTexture)
{
- fprintf(stderr, "ERROR: Failed to create %dx%d@%d texture!\n",
- width, height, sdlscrn->format->BitsPerPixel);
- exit(-3);
+ fprintf(stderr, "%dx%d@%d texture\n",
+ width, height, sdlscrn->format->BitsPerPixel);
+ Main_ErrorExit("Failed to create texture:", SDL_GetError(), -3);
}
}
}
@@ -481,12 +481,11 @@ static bool Screen_SetSDLVideoSize(int width, int height, bool bForceChange)
sdlWindow = SDL_CreateWindow("Hatari", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
win_width, win_height, sdlVideoFlags);
- }
- if (!sdlWindow)
- {
- fprintf(stderr, "ERROR: Failed to create %dx%d window!\n",
- win_width, win_height);
- exit(-1);
+ if (!sdlWindow)
+ {
+ fprintf(stderr, "%dx%d window\n", win_width, win_height);
+ Main_ErrorExit("Failed to create window:", SDL_GetError(), -1);
+ }
}
if (bUseSdlRenderer)
{
@@ -496,9 +495,8 @@ static bool Screen_SetSDLVideoSize(int width, int height, bool bForceChange)
sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, 0);
if (!sdlRenderer)
{
- fprintf(stderr, "ERROR: Failed to create %dx%d renderer!\n",
- win_width, win_height);
- exit(1);
+ fprintf(stderr, "%dx%d renderer\n", win_width, win_height);
+ Main_ErrorExit("Failed to create renderer:", SDL_GetError(), 1);
}
if (bInFullScreen)
@@ -530,9 +528,8 @@ static bool Screen_SetSDLVideoSize(int width, int height, bool bForceChange)
/* Exit if we can not open a screen */
if (!sdlscrn)
{
- fprintf(stderr, "ERROR: Could not set video mode:\n %s\n", SDL_GetError() );
SDL_Quit();
- exit(-2);
+ Main_ErrorExit("Could not set video mode:", SDL_GetError(), -2);
}
DEBUGPRINT(("SDL screen granted: %d x %d @ %d\n", sdlscrn->w, sdlscrn->h,
@@ -713,8 +710,7 @@ void Screen_Init(void)
FrameBuffer.pSTScreenCopy = malloc(MAX_VDI_BYTES);
if (!FrameBuffer.pSTScreen || !FrameBuffer.pSTScreenCopy)
{
- fprintf(stderr, "ERROR: Failed to allocate frame buffer memory.\n");
- exit(-1);
+ Main_ErrorExit("Failed to allocate frame buffer memory", NULL, -1);
}
pFrameBuffer = &FrameBuffer; /* TODO: Replace pFrameBuffer with FrameBuffer everywhere */
diff --git a/src/tos.c b/src/tos.c
index d7b08df0..915a84a2 100644
--- a/src/tos.c
+++ b/src/tos.c
@@ -1231,8 +1231,7 @@ int TOS_InitImage(void)
psTestPrg, TEST_PRG_START);
if (GemDOS_LoadAndReloc(psTestPrg, TEST_PRG_BASEPAGE, true))
{
- fprintf(stderr, "Failed to load '%s'\n", psTestPrg);
- exit(1);
+ Main_ErrorExit("Failed to load:", psTestPrg, 1);
}
}
else
diff --git a/src/vdi.c b/src/vdi.c
index 0b8cb600..b62ccaa3 100644
--- a/src/vdi.c
+++ b/src/vdi.c
@@ -131,8 +131,7 @@ void VDI_SetResolution(int GEMColor, int WidthRequest, int HeightRequest)
VDIPlanes = 4;
break;
default:
- fprintf(stderr, "Invalid VDI planes mode request: %d!\n", GEMColor);
- exit(1);
+ Main_ErrorExit("Invalid VDI planes mode request (not 2/4/16)", NULL, 1);
}
#if DEBUG
printf("%s v0x%04x, RAM=%dkB\n", bIsEmuTOS ? "EmuTOS" : "TOS", TosVersion, ConfigureParams.Memory.STRamSize_KB);
--
2.39.5
From 3ccb45cdabffbac30e9d320c022634460bea4c05 Mon Sep 17 00:00:00 2001
From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
Date: Wed, 4 Jun 2025 23:24:23 +0300
Subject: [PATCH 1/2] Open Windows console to show error + wait a key press
before exiting
---
src/gui-win/opencon.c | 24 +++++++++++++++------
src/gui-win/opencon.h | 1 +
src/includes/main.h | 1 +
src/main.c | 49 ++++++++++++++++++++++++++++++++++---------
src/options.c | 21 +++++++++----------
5 files changed, 69 insertions(+), 27 deletions(-)
diff --git a/src/gui-win/opencon.c b/src/gui-win/opencon.c
index f245cf63..60147444 100644
--- a/src/gui-win/opencon.c
+++ b/src/gui-win/opencon.c
@@ -17,14 +17,26 @@
#include "opencon.h"
#include "../includes/configuration.h"
+static void Win_OpenInternal(void)
+{
+ static bool opened;
+ if (opened)
+ return;
+ opened = true;
+
+ AllocConsole();
+ freopen("CON", "w", stdout);
+ freopen("CON", "r", stdin);
+ freopen("CON", "w", stderr);
+}
void Win_OpenCon(void)
{
if (ConfigureParams.Log.bConsoleWindow)
- {
- AllocConsole();
- freopen("CON", "w", stdout);
- freopen("CON", "r", stdin);
- freopen("CON", "w", stderr);
- }
+ Win_OpenInternal();
+}
+
+void Win_ForceCon(void)
+{
+ Win_OpenInternal();
}
diff --git a/src/gui-win/opencon.h b/src/gui-win/opencon.h
index 76ce8d43..6fb8433e 100644
--- a/src/gui-win/opencon.h
+++ b/src/gui-win/opencon.h
@@ -1,2 +1,3 @@
extern void Win_OpenCon(void);
+extern void Win_ForceCon(void);
diff --git a/src/includes/main.h b/src/includes/main.h
index 8638025e..0312b6fd 100644
--- a/src/includes/main.h
+++ b/src/includes/main.h
@@ -68,5 +68,6 @@ extern void Main_WarpMouse(int x, int y, bool restore);
extern bool Main_ShowCursor(bool show);
extern void Main_EventHandler(void);
extern void Main_SetTitle(const char *title);
+extern void Main_ErrorExit(const char *msg1, const char *msg2, int errval);
#endif /* ifndef HATARI_MAIN_H */
diff --git a/src/main.c b/src/main.c
index cc64f6bd..22414b70 100644
--- a/src/main.c
+++ b/src/main.c
@@ -778,8 +778,7 @@ static void Main_Init(void)
/* Open debug log file */
if (!Log_Init())
{
- fprintf(stderr, "ERROR: logging/tracing initialization failed\n");
- exit(-1);
+ Main_ErrorExit("logging/tracing initialization failed", NULL, -1);
}
Log_Printf(LOG_INFO, PROG_NAME ", compiled on: " __DATE__ ", " __TIME__ "\n");
@@ -787,14 +786,12 @@ static void Main_Init(void)
will be initialized later (failure not fatal). */
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
- fprintf(stderr, "ERROR: could not initialize the SDL library:\n %s\n", SDL_GetError() );
- exit(-1);
+ Main_ErrorExit("could not initialize the SDL library:", SDL_GetError(), -1);
}
if ( IPF_Init() != true )
{
- fprintf(stderr, "ERROR: could not initialize the IPF support\n" );
- exit(-1);
+ Main_ErrorExit("could not initialize the IPF support", NULL, -1);
}
ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
@@ -841,10 +838,11 @@ static void Main_Init(void)
}
if (!bTosImageLoaded || bQuitProgram)
{
- if (!bTosImageLoaded)
- fprintf(stderr, "ERROR: failed to load TOS image!\n");
SDL_Quit();
- exit(-2);
+ if (!bTosImageLoaded)
+ Main_ErrorExit("failed to load TOS image", NULL, -2);
+ else
+ exit(-2);
}
IoMem_Init();
@@ -980,6 +978,37 @@ static void Main_StatusbarSetup(void)
Statusbar_UpdateInfo();
}
+/**
+ * Error exit wrapper, to make sure user sees the error messages
+ * also on Windows.
+ *
+ * If message is given, Windows console is opened to show it,
+ * otherwise it's assumed to be already open and relevant
+ * messages shown before calling this.
+ *
+ * User input is waited on Windows, to make sure user sees
+ * the message before console closes.
+ *
+ * Value overrides nQuitValue as process exit/return value.
+ */
+void Main_ErrorExit(const char *msg1, const char *msg2, int errval)
+{
+ if (msg1)
+ {
+#ifdef WIN32
+ Win_ForceCon();
+#endif
+ if (msg2)
+ fprintf(stderr, "ERROR: %s\n\t%s\n", msg1, msg2);
+ else
+ fprintf(stderr, "ERROR: %s!\n", msg1);
+ }
+#ifdef WIN32
+ fputs("<press a key to exit>\n", stderr);
+ (void)fgetc(stdin);
+#endif
+ exit(errval);
+}
/**
* Main
@@ -1010,7 +1039,7 @@ int main(int argc, char *argv[])
if (!Opt_ParseParameters(argc, (const char * const *)argv))
{
Control_RemoveFifo();
- return 1;
+ Main_ErrorExit(NULL, NULL, 1);
}
/* monitor type option might require "reset" -> true */
Configuration_Apply(true);
diff --git a/src/options.c b/src/options.c
index d1b160b9..1af9d29e 100644
--- a/src/options.c
+++ b/src/options.c
@@ -537,6 +537,13 @@ static const opt_t HatariOptions[] = {
*/
static void Opt_ShowVersion(void)
{
+#ifdef WIN32
+ /* Opt_ShowVersion() is called for all info exit paths,
+ * so having this here should enable console for everything
+ * relevant on Windows.
+ */
+ Win_ForceCon();
+#endif
printf("\n" PROG_NAME
" - the Atari ST, STE, TT and Falcon emulator.\n\n"
"Hatari is free software licensed under the GNU General"
@@ -1040,7 +1047,7 @@ static bool Opt_HandleArgument(const char *path)
path = dir;
}
- /* GEMDOS HDD directory (as argument, or for the Atari program)? */
+ /* GEMDOS HDD directory (as path arg, or dir for the Atari program)? */
if (File_DirExists(path))
{
Log_Printf(LOG_DEBUG, "ARG = GEMDOS HD dir: %s\n", path);
@@ -1058,16 +1065,8 @@ static bool Opt_HandleArgument(const char *path)
}
return true;
}
- else
- {
- if (dir)
- {
- /* if dir is set, it should be valid... */
- Log_Printf(LOG_ERROR, "Given atari program path '%s' doesn't exist (anymore?)!\n", dir);
- free(dir);
- exit(1);
- }
- }
+ /* something wrong if path to an existing prg has no valid dir */
+ assert(!dir);
/* disk image? */
if (Floppy_SetDiskFileName(0, path, NULL))
--
2.39.5