diff --git a/CMakeLists.txt b/CMakeLists.txt
index a43b7f63..7420dfe0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -504,7 +504,7 @@ if(NOT BUILD_HYDRA_CORE AND NOT BUILD_LIBRETRO_CORE)
         )
     else()
         set(FRONTEND_SOURCE_FILES src/panda_sdl/main.cpp src/panda_sdl/frontend_sdl.cpp src/panda_sdl/mappings.cpp)
-        set(FRONTEND_HEADER_FILES "")
+        set(FRONTEND_HEADER_FILES "include/panda_sdl/frontend_sdl.hpp")
     endif()
 
     target_link_libraries(Alber PRIVATE AlberCore)
diff --git a/include/panda_sdl/frontend_sdl.hpp b/include/panda_sdl/frontend_sdl.hpp
index dd6ab6c0..07038962 100644
--- a/include/panda_sdl/frontend_sdl.hpp
+++ b/include/panda_sdl/frontend_sdl.hpp
@@ -23,6 +23,8 @@ class FrontendSDL {
 	SDL_GameController* gameController = nullptr;
 	InputMappings keyboardMappings;
 
+	u32 windowWidth = 400;
+	u32 windowHeight = 480;
 	int gameControllerID;
 	bool programRunning = true;
 	
diff --git a/src/panda_sdl/frontend_sdl.cpp b/src/panda_sdl/frontend_sdl.cpp
index 3c7ccc1d..77b1f55f 100644
--- a/src/panda_sdl/frontend_sdl.cpp
+++ b/src/panda_sdl/frontend_sdl.cpp
@@ -162,8 +162,13 @@ void FrontendSDL::run() {
 					if (emu.romType == ROMType::None) break;
 
 					if (event.button.button == SDL_BUTTON_LEFT) {
-						const s32 x = event.button.x;
-						const s32 y = event.button.y;
+						if (windowWidth == 0 || windowHeight == 0) [[unlikely]] {
+							break;
+						}
+
+						// Go from window positions to [0, 400) for x and [0, 480) for y
+						const s32 x = (s32)std::round(event.button.x * 400.f / windowWidth);
+						const s32 y = (s32)std::round(event.button.y * 480.f / windowHeight);
 
 						// Check if touch falls in the touch screen area
 						if (y >= 240 && y <= 480 && x >= 40 && x < 40 + 320) {
@@ -242,8 +247,13 @@ void FrontendSDL::run() {
 
 					// Handle "dragging" across the touchscreen
 					if (hid.isTouchScreenPressed()) {
-						const s32 x = event.motion.x;
-						const s32 y = event.motion.y;
+						if (windowWidth == 0 || windowHeight == 0) [[unlikely]] {
+							break;
+						}
+
+						// Go from window positions to [0, 400) for x and [0, 480) for y
+						const s32 x = (s32)std::round(event.motion.x * 400.f / windowWidth);
+						const s32 y = (s32)std::round(event.motion.y * 480.f / windowHeight);
 
 						// Check if touch falls in the touch screen area and register the new touch screen position
 						if (y >= 240 && y <= 480 && x >= 40 && x < 40 + 320) {
@@ -293,9 +303,9 @@ void FrontendSDL::run() {
 				case SDL_WINDOWEVENT: {
 					auto type = event.window.event;
 					if (type == SDL_WINDOWEVENT_RESIZED) {
-						const u32 width = event.window.data1;
-						const u32 height = event.window.data2;
-						emu.setOutputSize(width, height);
+						windowWidth = event.window.data1;
+						windowHeight = event.window.data2;
+						emu.setOutputSize(windowWidth, windowHeight);
 					}
 				}
 			}