shithub: ft²

Download patch

ref: 17ac33dc875bb058794df9d3ca2b0274f3cd9e54
parent: 04baa345fb4255ca4a177fd7c4c3bee24d59db46
author: Olav Sørensen <olav.sorensen@live.no>
date: Mon Jul 11 17:40:08 EDT 2022

Some fullscreen fixes and more

--- a/src/ft2_config.c
+++ b/src/ft2_config.c
@@ -210,6 +210,33 @@
 	loadConfigFromBuffer(true);
 }
 
+static void updateImageStretchAndPixelFilter(uint8_t oldWindowFlags, uint8_t oldSpecialFlags2)
+{
+	bool didFullscreenUpdate = false;
+
+	// handle pixel filter change
+	if ((oldWindowFlags & PIXEL_FILTER) != (config.windowFlags & PIXEL_FILTER))
+	{
+		recreateTexture();
+		if (video.fullscreen) // force an update if in fullscreen mode
+		{
+			leaveFullscreen();
+			enterFullscreen();
+			didFullscreenUpdate = true;
+		}
+	}
+
+	// handle image stretch change
+	if ((oldSpecialFlags2 & STRETCH_IMAGE) != (config.specialFlags2 & STRETCH_IMAGE))
+	{
+		if (video.fullscreen && !didFullscreenUpdate) // force an update if in fullscreen mode
+		{
+			leaveFullscreen();
+			enterFullscreen();
+		}
+	}
+}
+
 void resetConfig(void)
 {
 	if (okBox(2, "System request", "Are you sure you want to reset your FT2 configuration?") != 1)
@@ -216,6 +243,7 @@
 		return;
 
 	const uint8_t oldWindowFlags = config.windowFlags;
+	const uint8_t oldSpecialFlags2 = config.specialFlags2;
 
 	setDefaultConfigSettings();
 	setToDefaultAudioOutputDevice();
@@ -228,18 +256,8 @@
 	showBottomScreen();
 
 	setWindowSizeFromConfig(true);
+	updateImageStretchAndPixelFilter(oldWindowFlags, oldSpecialFlags2);
 
-	// handle pixel filter change
-	if ((oldWindowFlags & PIXEL_FILTER) != (config.windowFlags & PIXEL_FILTER))
-	{
-		recreateTexture();
-		if (video.fullscreen)
-		{
-			leaveFullScreen();
-			enterFullscreen();
-		}
-	}
-
 	if (config.specialFlags2 & HARDWARE_MOUSE)
 		SDL_ShowCursor(SDL_TRUE);
 	else
@@ -339,6 +357,7 @@
 void loadConfig2(void) // called by "Load config" button
 {
 	const uint8_t oldWindowFlags = config.windowFlags;
+	const uint8_t oldSpecialFlags2 = config.specialFlags2;
 
 	loadConfig(CONFIG_SHOW_ERRORS);
 
@@ -346,16 +365,8 @@
 	showTopScreen(false);
 	showBottomScreen();
 
-	// handle pixel filter change
-	if ((oldWindowFlags & PIXEL_FILTER) != (config.windowFlags & PIXEL_FILTER))
-	{
-		recreateTexture();
-		if (video.fullscreen)
-		{
-			leaveFullScreen();
-			enterFullscreen();
-		}
-	}
+	setWindowSizeFromConfig(true);
+	updateImageStretchAndPixelFilter(oldWindowFlags, oldSpecialFlags2);
 
 	if (config.specialFlags2 & HARDWARE_MOUSE)
 		SDL_ShowCursor(SDL_TRUE);
@@ -2110,7 +2121,7 @@
 	recreateTexture();
 	if (video.fullscreen)
 	{
-		leaveFullScreen();
+		leaveFullscreen();
 		enterFullscreen();
 	}
 }
@@ -2121,7 +2132,7 @@
 
 	if (video.fullscreen)
 	{
-		leaveFullScreen();
+		leaveFullscreen();
 		enterFullscreen();
 	}
 }
--- a/src/ft2_events.c
+++ b/src/ft2_events.c
@@ -38,7 +38,7 @@
                    "Try to mention what you did before the crash happened.\n" \
                    "My email can be found at the bottom of www.16-bits.org."
 
-static bool backupMadeAfterCrash;
+static bool backupMadeAfterCrash, didDropFile;
 
 #ifdef _WIN32
 #define SYSMSG_FILE_ARG (WM_USER+1)
@@ -50,49 +50,14 @@
 static LPCTSTR sharedMemBuf;
 #endif
 
-static void handleInput(void);
+static void handleSDLEvents(void);
 
-#ifdef _WIN32 // Windows usleep() implementation
-
-static NTSTATUS (__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval);
-static NTSTATUS (__stdcall *NtQueryTimerResolution)(PULONG MinimumResolution, PULONG MaximumResolution, PULONG ActualResolution);
-static NTSTATUS (__stdcall *NtSetTimerResolution)(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
-
-static void (*usleep)(int32_t usec);
-
-static void usleepGood(int32_t usec)
-{
-	LARGE_INTEGER delayInterval;
-
-	// NtDelayExecution() delays in 100ns-units, and negative value = delay from current time
-	usec *= -10;
-
-	delayInterval.HighPart = 0xFFFFFFFF;
-	delayInterval.LowPart = usec;
-	NtDelayExecution(false, &delayInterval);
-}
-
-static void usleepWeak(int32_t usec) // fallback if no NtDelayExecution()
-{
-	Sleep((usec + 500) / 1000);
-}
-
-void windowsSetupUsleep(void)
-{
-	NtDelayExecution = (NTSTATUS (__stdcall *)(BOOL, PLARGE_INTEGER))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution");
-	NtQueryTimerResolution = (NTSTATUS (__stdcall *)(PULONG, PULONG, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryTimerResolution");
-	NtSetTimerResolution = (NTSTATUS (__stdcall *)(ULONG, BOOLEAN, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtSetTimerResolution");
-
-	usleep = (NtDelayExecution != NULL) ? usleepGood : usleepWeak;
-}
-#endif
-
 void readInput(void)
 {
 	readMouseXY();
 	readKeyModifiers();
 	setSyncedReplayerVars();
-	handleInput();
+	handleSDLEvents();
 }
 
 void handleThreadEvents(void)
@@ -407,7 +372,7 @@
 	}
 }
 
-static void handleInput(void)
+static void handleSDLEvents(void)
 {
 	SDL_Event event;
 
@@ -483,6 +448,10 @@
 			editor.autoPlayOnDrop = false;
 			loadDroppedFile(event.drop.file, true);
 			SDL_free(event.drop.file);
+
+			// kludge: allow focus-clickthrough after drag-n-drop
+			SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
+			didDropFile = true;
 		}
 		else if (event.type == SDL_QUIT)
 		{
@@ -520,6 +489,13 @@
 		else if (event.type == SDL_MOUSEBUTTONUP)
 		{
 			mouseButtonUpHandler(event.button.button);
+
+			// kludge: we drag-n-dropped a file before this mouse click release, restore focus-clickthrough mode
+			if (didDropFile)
+			{
+				didDropFile = false;
+				SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "0");
+			}
 		}
 		else if (event.type == SDL_MOUSEBUTTONDOWN)
 		{
--- a/src/ft2_keyboard.c
+++ b/src/ft2_keyboard.c
@@ -703,7 +703,7 @@
 		{
 			if (keyb.leftAltPressed)
 			{
-				toggleFullScreen();
+				toggleFullscreen();
 
 				// prevent fullscreen toggle from firing twice on certain SDL2 Linux ports
 #ifdef __unix__
@@ -896,7 +896,7 @@
 #ifdef __APPLE__
 			if (keyb.leftCommandPressed && keyb.leftCtrlPressed)
 			{
-				toggleFullScreen();
+				toggleFullscreen();
 				return true;
 			}
 			else
--- a/src/ft2_textboxes.c
+++ b/src/ft2_textboxes.c
@@ -896,7 +896,7 @@
 		{
 			// ALT+ENTER = toggle fullscreen, even while text editing
 			if (keyb.leftAltPressed)
-				toggleFullScreen();
+				toggleFullscreen();
 			else
 				exitTextEditing();
 		}
--- a/src/ft2_video.c
+++ b/src/ft2_video.c
@@ -51,9 +51,10 @@
 static sprite_t sprites[SPRITE_NUM];
 
 // for FPS counter
+#define FPS_LINES 15
 #define FPS_SCAN_FRAMES 60
 #define FPS_RENDER_W 285
-#define FPS_RENDER_H (((FONT1_CHAR_H + 1) * 8) + 1)
+#define FPS_RENDER_H (((FONT1_CHAR_H + 1) * FPS_LINES) + 1)
 #define FPS_RENDER_X 2
 #define FPS_RENDER_Y 2
 
@@ -79,6 +80,10 @@
 
 static void drawFPSCounter(void)
 {
+	SDL_version SDLVer;
+
+	SDL_GetVersion(&SDLVer);
+
 	if (editor.framesPassed >= FPS_SCAN_FRAMES && (editor.framesPassed % FPS_SCAN_FRAMES) == 0)
 	{
 		dAvgFPS = 1000.0 / (dRunningFrameDuration / FPS_SCAN_FRAMES);
@@ -94,10 +99,12 @@
 	hLineDouble(FPS_RENDER_X+1, FPS_RENDER_Y, FPS_RENDER_W, PAL_FORGRND);
 	hLineDouble(FPS_RENDER_X+1, FPS_RENDER_Y+FPS_RENDER_H+2, FPS_RENDER_W, PAL_FORGRND);
 
-	// test if enough data is collected yet
+	// if enough frame data isn't collected yet, show a message
 	if (editor.framesPassed < FPS_SCAN_FRAMES)
 	{
-		textOut(FPS_RENDER_X+53, FPS_RENDER_Y+39, PAL_FORGRND, "Gathering frame information...");
+		const char *text = "Gathering frame information...";
+		const uint16_t textW = textWidth(text);
+		textOut(FPS_RENDER_X+((FPS_RENDER_W/2)-(textW/2)), FPS_RENDER_Y+((FPS_RENDER_H/2)-(FONT1_CHAR_H/2)), PAL_FORGRND, text);
 		return;
 	}
 
@@ -109,7 +116,9 @@
 	if (dAudLatency < 0.0 || dAudLatency > 999999999.9999)
 		dAudLatency = 999999999.9999; // prevent number from overflowing text box
 
-	sprintf(fpsTextBuf, "Frames per second: %.4f\n" \
+	sprintf(fpsTextBuf,
+	             "SDL version: %u.%u.%u\n" \
+	             "Frames per second: %.3f\n" \
 	             "Monitor refresh rate: %.1fHz (+/-)\n" \
 	             "59..61Hz GPU VSync used: %s\n" \
 	             "Audio frequency: %.1fkHz (expected %.1fkHz)\n" \
@@ -116,13 +125,27 @@
 	             "Audio buffer samples: %d (expected %d)\n" \
 	             "Audio channels: %d (expected %d)\n" \
 	             "Audio latency: %.1fms (expected %.1fms)\n" \
+	             "Render size: %dx%d (offset %d,%d)\n" \
+	             "Disp. size: %dx%d (window: %dx%d)\n" \
+	             "Render scaling: x=%.2f, y=%.2f\n" \
+	             "Mouse to render space muls: x=%.2f, y=%.2f\n" \
+	             "Relative mouse coords: %d,%d\n" \
+	             "Absolute mouse coords: %d,%d\n" \
 	             "Press CTRL+SHIFT+F to close this box.\n",
-	             dAvgFPS, dRefreshRate,
+	             SDLVer.major, SDLVer.minor, SDLVer.patch,
+	             dAvgFPS,
+	             dRefreshRate,
 	             video.vsync60HzPresent ? "yes" : "no",
 	             audio.haveFreq * (1.0 / 1000.0), audio.wantFreq * (1.0 / 1000.0),
 	             audio.haveSamples, audio.wantSamples,
 	             audio.haveChannels, audio.wantChannels,
-	             dAudLatency, ((audio.wantSamples * 1000.0) / audio.wantFreq));
+	             dAudLatency, ((audio.wantSamples * 1000.0) / audio.wantFreq),
+	             video.renderW, video.renderH, video.renderX, video.renderY,
+	             video.displayW, video.displayH, video.windowW, video.windowH,
+	             video.renderW / (float)SCREEN_W, video.renderH / (float)SCREEN_H,
+	             video.fMouseXMul, video.fMouseYMul,
+	             mouse.x, mouse.y,
+	             mouse.absX, mouse.absY);
 
 	// draw text
 
@@ -136,7 +159,7 @@
 		if (ch == '\n')
 		{
 			yPos += FONT1_CHAR_H+1;
-			xPos = FPS_RENDER_X + 3;
+			xPos = FPS_RENDER_X+3;
 			continue;
 		}
 
@@ -143,6 +166,17 @@
 		charOut(xPos, yPos, PAL_FORGRND, ch);
 		xPos += charWidth(ch);
 	}
+
+	// draw framerate tester symbol
+
+	const uint16_t symbolEnd = 115;
+
+	// ping-pong movement
+	uint16_t x = editor.framesPassed % (symbolEnd * 2);
+	if (x >= symbolEnd)
+		x = (symbolEnd * 2) - x;
+
+	charOut(164 + x, 16, PAL_FORGRND, '*');
 }
 
 void endFPSCounter(void)
@@ -239,6 +273,8 @@
 		SDL_GetWindowSize(video.window, &video.displayW, &video.displayH);
 	}
 
+	SDL_GetWindowSize(video.window, &video.windowW, &video.windowH);
+
 	if (video.fullscreen)
 	{
 		if (config.specialFlags2 & STRETCH_IMAGE)
@@ -293,11 +329,18 @@
 
 void enterFullscreen(void)
 {
-	SDL_DisplayMode dm;
+	SDL_SetWindowFullscreen(video.window, SDL_WINDOW_FULLSCREEN_DESKTOP);
 
 	if (config.specialFlags2 & STRETCH_IMAGE)
 	{
-		SDL_GetDesktopDisplayMode(0, &dm);
+		SDL_DisplayMode dm;
+
+		int32_t di = SDL_GetWindowDisplayIndex(video.window);
+		if (di < 0)
+			di = 0; // return display index 0 (default) on error
+
+		SDL_GetDesktopDisplayMode(di, &dm);
+
 		SDL_RenderSetLogicalSize(video.renderer, dm.w, dm.h);
 	}
 	else
@@ -306,8 +349,10 @@
 	}
 
 	SDL_SetWindowSize(video.window, SCREEN_W, SCREEN_H);
-	SDL_SetWindowFullscreen(video.window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+
+#ifndef __unix__ // can be severely buggy on Linux... (at least when used like this)
 	SDL_SetWindowGrab(video.window, SDL_TRUE);
+#endif
 
 	updateRenderSizeVars();
 	updateMouseScaling();
@@ -314,7 +359,7 @@
 	setMousePosToCenter();
 }
 
-void leaveFullScreen(void)
+void leaveFullscreen(void)
 {
 	SDL_SetWindowFullscreen(video.window, 0);
 	SDL_RenderSetLogicalSize(video.renderer, SCREEN_W, SCREEN_H);
@@ -322,14 +367,21 @@
 	setWindowSizeFromConfig(false);
 
 	SDL_SetWindowSize(video.window, SCREEN_W * video.upscaleFactor, SCREEN_H * video.upscaleFactor);
+
+#ifndef __unix__
 	SDL_SetWindowGrab(video.window, SDL_FALSE);
+#endif
 
 	updateRenderSizeVars();
 	updateMouseScaling();
 	setMousePosToCenter();
+
+#ifdef __unix__ // can be required on Linux... (or else the window keeps moving down every time you leave fullscreen)
+	SDL_SetWindowPosition(video.window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+#endif
 }
 
-void toggleFullScreen(void)
+void toggleFullscreen(void)
 {
 	video.fullscreen ^= 1;
 
@@ -336,7 +388,7 @@
 	if (video.fullscreen)
 		enterFullscreen();
 	else
-		leaveFullScreen();
+		leaveFullscreen();
 }
 
 bool setupSprites(void)
@@ -774,8 +826,12 @@
 	uint8_t oldUpscaleFactor = video.upscaleFactor;
 	if (config.windowFlags & WINSIZE_AUTO)
 	{
+		int32_t di = SDL_GetWindowDisplayIndex(video.window);
+		if (di < 0)
+			di = 0; // return display index 0 (default) on error
+
 		// find out which upscaling factor is the biggest to fit on screen
-		if (SDL_GetDesktopDisplayMode(0, &dm) == 0)
+		if (SDL_GetDesktopDisplayMode(di, &dm) == 0)
 		{
 			for (i = MAX_UPSCALE_FACTOR; i >= 1; i--)
 			{
@@ -886,7 +942,11 @@
 
 	setWindowSizeFromConfig(false);
 
-	SDL_GetDesktopDisplayMode(0, &dm);
+	int32_t di = SDL_GetWindowDisplayIndex(video.window);
+	if (di < 0)
+		di = 0; // return display index 0 (default) on error
+
+	SDL_GetDesktopDisplayMode(di, &dm);
 	video.dMonitorRefreshRate = (double)dm.refresh_rate;
 
 	if (dm.refresh_rate >= 59 && dm.refresh_rate <= 61)
--- a/src/ft2_video.h
+++ b/src/ft2_video.h
@@ -31,7 +31,7 @@
 	float fMouseXMul, fMouseYMul;
 	uint8_t upscaleFactor;
 	bool vsync60HzPresent, windowHidden;
-	int32_t renderX, renderY, renderW, renderH, displayW, displayH;
+	int32_t renderX, renderY, renderW, renderH, displayW, displayH, windowW, windowH;
 	uint32_t *frameBufferUnaligned;
 	SDL_Renderer *renderer;
 	SDL_Texture *texture;
@@ -72,7 +72,7 @@
 void hideSprite(int32_t sprite);
 void handleRedrawing(void);
 void enterFullscreen(void);
-void leaveFullScreen(void);
+void leaveFullscreen(void);
 void setWindowSizeFromConfig(bool updateRenderer);
 bool recreateTexture(void);
-void toggleFullScreen(void);
+void toggleFullscreen(void);