shithub: cstory

Download patch

ref: 8892dc24b535c84cac47fb2fa08ad37f2b422152
parent: 451945e80cc0a51384de0e292c294795733e7696
author: Clownacy <Clownacy@users.noreply.github.com>
date: Sun Sep 1 14:15:12 EDT 2019

ASM-accurate Main.cpp and added the various Windows menus

--- a/msvc2003/CSE2.rc
+++ b/msvc2003/CSE2.rc
@@ -175,6 +175,80 @@
 
 #endif    // APSTUDIO_INVOKED
 
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+MENU_MAIN MENU 
+BEGIN
+    MENUITEM "Quit",                        40001
+    MENUITEM "Volume",                      40004
+    MENUITEM "Version",                     40002
+    MENUITEM "Debug Save",                  40005
+    MENUITEM "Mute",                        40007
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+DLG_ABOUT DIALOGEX 0, 0, 123, 75
+STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
+FONT 9, "Arial", 400, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "OK",1,37,54,50,14,BS_FLAT
+    CTEXT           "---",1011,7,14,109,35
+END
+
+DLG_MUTE DIALOGEX 0, 0, 118, 111
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Mute"
+FONT 9, "Arial", 400, 0, 0x80
+BEGIN
+    DEFPUSHBUTTON   "OK",1,7,90,50,14
+    PUSHBUTTON      "Cancel",2,61,90,50,14
+    CONTROL         "0",1010,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | 
+                    WS_TABSTOP,7,7,20,10
+    CONTROL         "1",1018,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | 
+                    WS_TABSTOP,17,15,20,10
+    CONTROL         "2",1019,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | 
+                    WS_TABSTOP,26,24,20,10
+    CONTROL         "3",1020,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | 
+                    WS_TABSTOP,35,33,20,10
+    CONTROL         "4",1021,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | 
+                    WS_TABSTOP,45,41,20,10
+    CONTROL         "5",1022,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | 
+                    WS_TABSTOP,54,50,20,10
+    CONTROL         "6",1023,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | 
+                    WS_TABSTOP,63,58,20,10
+    CONTROL         "7",1024,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | 
+                    WS_TABSTOP,73,67,20,10
+END
+
+DLG_SAVE DIALOGEX 0, 0, 118, 47
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Save"
+FONT 9, "Arial", 0, 0, 0x1
+BEGIN
+    EDITTEXT        1008,36,8,72,12,ES_AUTOHSCROLL
+    DEFPUSHBUTTON   "OK",1,8,28,48,12
+    PUSHBUTTON      "Cancel",2,60,28,48,12
+    LTEXT           "Name",-1,8,8,20,12,SS_CENTERIMAGE
+END
+
+DLG_YESNO DIALOGEX 0, 0, 119, 49
+STYLE DS_SETFONT | WS_POPUP | WS_CAPTION
+FONT 9, "Arial", 400, 0, 0x80
+BEGIN
+    PUSHBUTTON      "Yes",1,7,28,50,14,BS_FLAT
+    PUSHBUTTON      "No",2,62,28,50,14,BS_FLAT
+    CTEXT           "---",1009,7,8,105,15,SS_CENTERIMAGE
+END
+
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
 
--- a/msvc2003/CSE2.vcproj
+++ b/msvc2003/CSE2.vcproj
@@ -34,7 +34,7 @@
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="Version.lib dsound.lib WinMM.lib dxguid.lib dinput.lib ddraw.lib ShLwApi.Lib"
+				AdditionalDependencies="Version.lib dsound.lib WinMM.lib dxguid.lib dinput.lib ddraw.lib ShLwApi.Lib Imm32.lib"
 				OutputFile="$(OutDir)\$(ProjectName).exe"
 				LinkIncremental="2"
 				AdditionalLibraryDirectories=""
@@ -85,7 +85,7 @@
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="Version.lib dsound.lib WinMM.lib dxguid.lib dinput.lib ddraw.lib ShLwApi.Lib"
+				AdditionalDependencies="Version.lib dsound.lib WinMM.lib dxguid.lib dinput.lib ddraw.lib ShLwApi.Lib Imm32.lib"
 				OutputFile="$(OutDir)\$(ProjectName).exe"
 				LinkIncremental="1"
 				IgnoreAllDefaultLibraries="FALSE"
@@ -135,7 +135,7 @@
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="Version.lib dsound.lib WinMM.lib dxguid.lib dinput.lib ddraw.lib ShLwApi.Lib"
+				AdditionalDependencies="Version.lib dsound.lib WinMM.lib dxguid.lib dinput.lib ddraw.lib ShLwApi.Lib Imm32.lib"
 				OutputFile="$(OutDir)\$(ProjectName).exe"
 				LinkIncremental="1"
 				IgnoreAllDefaultLibraries="FALSE"
@@ -186,7 +186,7 @@
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="Version.lib dsound.lib WinMM.lib dxguid.lib dinput.lib ddraw.lib ShLwApi.Lib"
+				AdditionalDependencies="Version.lib dsound.lib WinMM.lib dxguid.lib dinput.lib ddraw.lib ShLwApi.Lib Imm32.lib"
 				OutputFile="$(OutDir)\$(ProjectName).exe"
 				LinkIncremental="2"
 				AdditionalLibraryDirectories=""
@@ -825,6 +825,9 @@
 				RelativePath="..\assets\resources\Org\Zonbie.org">
 			</File>
 		</Filter>
+		<File
+			RelativePath="..\assets\resources\Wave\Wave.dat">
+		</File>
 	</Files>
 	<Globals>
 	</Globals>
--- a/msvc2003/devilution/comparer-config.toml
+++ b/msvc2003/devilution/comparer-config.toml
@@ -783,8 +783,44 @@
 addr = 0x4122E0
 
 [[func]]
+name = "SetWindowName"
+addr = 0x412320
+
+[[func]]
+name = "PutFramePerSecound"
+addr = 0x412370
+
+[[func]]
+name = "GetFramePerSecound"
+addr = 0x4123A0
+
+[[func]]
 name = "WinMain"
 addr = 0x412420
+
+[[func]]
+name = "InactiveWindow"
+addr = 0x412BC0
+
+[[func]]
+name = "ActiveWindow"
+addr = 0x412BF0
+
+[[func]]
+name = "DragAndDropHandler"
+addr = 0x412C30
+
+[[func]]
+name = "WindowProcedure"
+addr = 0x412CA0
+
+[[func]]
+name = "SystemTask"
+addr = 0x413570
+
+[[func]]
+name = "JoystickProc"
+addr = 0x4135E0
 
 [[func]]
 name = "InitMapData2"
--- a/msvc2003/resource1.h
+++ b/msvc2003/resource1.h
@@ -5,9 +5,10 @@
 
 // Next default values for new objects
 // 
+
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        169
+#define _APS_NEXT_RESOURCE_VALUE        172
 #define _APS_NEXT_COMMAND_VALUE         40001
 #define _APS_NEXT_CONTROL_VALUE         1001
 #define _APS_NEXT_SYMED_VALUE           101
--- a/src/Input.cpp
+++ b/src/Input.cpp
@@ -143,7 +143,7 @@
 	return FALSE;
 }
 
-BOOL GetJoystickStatus(BOOL *buttons)
+BOOL GetJoystickStatus(JOYSTICK_STATUS *status)
 {
 	DIJOYSTATE joystate;
 
@@ -165,25 +165,25 @@
 	for (int i = 0; i < 32; ++i)
 	{
 		if (joystate.rgbButtons[i] & 0x80)
-			buttons[i + 4] = TRUE;
+			status->bButton[i] = TRUE;
 		else
-			buttons[i + 4] = FALSE;
+			status->bButton[i] = FALSE;
 	}
 
-	buttons[3] = FALSE;
-	buttons[1] = FALSE;
-	buttons[2] = FALSE;
-	buttons[0] = FALSE;
+	status->bDown = FALSE;
+	status->bRight = FALSE;
+	status->bUp = FALSE;
+	status->bLeft = FALSE;
 
 	if (joystate.lX < joystick_neutral_x - 10000)
-		buttons[0] = TRUE;
+		status->bLeft = TRUE;
 	else if (joystate.lX > joystick_neutral_x + 10000)
-		buttons[1] = TRUE;
+		status->bRight = TRUE;
 
 	if (joystate.lY < joystick_neutral_y - 10000)
-		buttons[2] = TRUE;
+		status->bUp = TRUE;
 	else if (joystate.lY > joystick_neutral_y + 10000)
-		buttons[3] = TRUE;
+		status->bDown = TRUE;
 
 	return TRUE;
 }
--- a/src/Input.h
+++ b/src/Input.h
@@ -16,5 +16,5 @@
 
 void ReleaseDirectInput(void);
 BOOL InitDirectInput(HINSTANCE hinst, HWND hWnd);
-BOOL GetJoystickStatus(BOOL *buttons);
+BOOL GetJoystickStatus(JOYSTICK_STATUS *status);
 BOOL ResetJoystickStatus(void);
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -10,6 +10,7 @@
 
 #include "CommonDefines.h"
 #include "Config.h"
+#include "Dialog.h"
 #include "Draw.h"
 #include "Game.h"
 #include "Generic.h"
@@ -21,6 +22,8 @@
 #include "Sound.h"
 #include "Triangle.h"
 
+LRESULT __stdcall WindowProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
+
 char gModulePath[MAX_PATH];
 char gDataPath[MAX_PATH];
 
@@ -48,16 +51,27 @@
 static const char *lpWindowName = "Cave Story ~ Doukutsu Monogatari";
 #endif
 
+void SetWindowName(HWND hWnd)
+{
+	char window_name[0x100];
+
+	sprintf(window_name, "%s", lpWindowName);
+	SetWindowTextA(hWnd, window_name);
+}
+
 // Framerate stuff
-void PutFramePerSecound()
+void PutFramePerSecound(void)
 {
 	if (bFps)
-		PutNumber4(WINDOW_WIDTH - 40, 8, GetFramePerSecound(), FALSE);
+	{
+		const int fps = GetFramePerSecound();
+		PutNumber4(WINDOW_WIDTH - 40, 8, fps, FALSE);
+	}
 }
 
-int GetFramePerSecound()
+int GetFramePerSecound(void)
 {
-/*	unsigned int current_tick;
+	unsigned int current_tick;
 	static BOOL need_new_base_tick = TRUE;
 	static int frames_this_second;
 	static int current_frame;
@@ -65,11 +79,11 @@
 
 	if (need_new_base_tick)
 	{
-		base_tick = SDL_GetTicks();
+		base_tick = GetTickCount();
 		need_new_base_tick = FALSE;
 	}
 
-	current_tick = SDL_GetTicks();
+	current_tick = GetTickCount();
 	++current_frame;
 
 	if (base_tick + 1000 <= current_tick)
@@ -79,8 +93,7 @@
 		current_frame = 0;
 	}
 
-	return frames_this_second;*/
-	return 0;
+	return frames_this_second;
 }
 
 int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
@@ -198,7 +211,7 @@
 	WNDCLASSEXA wndclassex;
 	memset(&wndclassex, 0, sizeof(WNDCLASSEXA));
 	wndclassex.cbSize = sizeof(WNDCLASSEXA);
-//	wndclassex.lpfnWndProc = WindowProcedure;
+	wndclassex.lpfnWndProc = WindowProcedure;
 	wndclassex.hInstance = hInstance;
 	wndclassex.hbrBackground = (HBRUSH)GetStockObject(3);
 	wndclassex.lpszClassName = lpWindowName;
@@ -354,7 +367,7 @@
 	return 1;
 }
 
-void InactiveWindow()
+void InactiveWindow(void)
 {
 	if (bActive)
 	{
@@ -366,7 +379,7 @@
 	PlaySoundObject(7, 0);
 }
 
-void ActiveWindow()
+void ActiveWindow(void)
 {
 	if (!bActive)
 	{
@@ -379,226 +392,380 @@
 	PlaySoundObject(7, -1);
 }
 
-void JoystickProc()
+// Turns out you could drag-and-drop a save file onto the
+// window to load it, but this behavior is dummied-out.
+BOOL DragAndDropHandler(HWND hWnd, WPARAM wParam)
 {
-/*	JOYSTICK_STATUS status;
+	char path[MAX_PATH];
+	HDROP hDrop = (HDROP)wParam;
 
-	if (GetJoystickStatus(&status))
+	if (DragQueryFileA(hDrop, 0xFFFFFFFF, NULL, 0) != 0)
 	{
-		// Clear held buttons
-		gKey &= (KEY_ESCAPE | KEY_F2 | KEY_F1);
+		DragQueryFileA(hDrop, 0, path, sizeof(path));
+		LoadProfile(path);
+	}
 
-		// Set movement buttons
-		if (status.bLeft)
-			gKey |= gKeyLeft;
-		if (status.bRight)
-			gKey |= gKeyRight;
-		if (status.bUp)
-			gKey |= gKeyUp;
-		if (status.bDown)
-			gKey |= gKeyDown;
+	DragFinish(hDrop);
 
-		// Set held buttons
-		for (int i = 0; i < 8; i++)
-		{
-			if (status.bButton[i])
-				gKey |= gJoystickButtonTable[i];
-		}
-	}*/
+	return TRUE;
 }
 
-#define DO_KEY_PRESS(key) \
-	if (event.type == SDL_KEYDOWN) \
-		gKey |= key; \
-	else \
-		gKey &= ~key; \
-	break;
-
-BOOL SystemTask()
+LRESULT __stdcall WindowProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
-	// Handle window events
-	BOOL focusGained = TRUE;
-/*
-	while (SDL_PollEvent(NULL) || !focusGained)
+	BOOL window_focus;
+	HMENU hMenu;
+
+	switch (Msg)
 	{
-		SDL_Event event;
-		SDL_WaitEvent(&event);
+		case WM_CREATE:
+			hMenu = GetMenu(hWnd);
+			//if (!CheckFileExists("save"))	// Chances are a line like this used to exist
+				DeleteMenu(hMenu, 40005, MF_BYCOMMAND);
+			DrawMenuBar(hWnd);
 
-		switch (event.type)
-		{
-			case SDL_QUIT:
-				return FALSE;
+			hMenu = GetMenu(hWnd);
+			if (!CheckFileExists("mute"))
+				DeleteMenu(hMenu, 40007, MF_BYCOMMAND);
+			DrawMenuBar(hWnd);
 
-			case SDL_WINDOWEVENT:
-				switch (event.window.event)
-				{
-					case SDL_WINDOWEVENT_FOCUS_GAINED:
-						focusGained = TRUE;
-						ActiveWindow();
-						break;
+			if (CheckFileExists("fps"))
+				bFps = TRUE;
 
-					case SDL_WINDOWEVENT_FOCUS_LOST:
-						focusGained = FALSE;
-						InactiveWindow();
-						break;
+			if (!bFullscreen)
+				LoadWindowRect(hWnd, "window.rect", FALSE);
 
-					default:
-						break;
-				}
-				break;
+			SetWindowName(hWnd);
+			break;
 
-			case SDL_DROPFILE:
-				LoadProfile(event.drop.file);
-				SDL_free(event.drop.file);
-				break;
+		case WM_SYSCOMMAND:
+			switch (wParam)
+			{
+				case SC_MONITORPOWER:
+					break;
 
-			case SDL_KEYDOWN:
-			case SDL_KEYUP:
-#ifdef FIX_BUGS
-				// BUG FIX: Pixel relied on key codes for input, but these differ based on keyboard layout.
-				// This would break the alternate movement keys on typical English keyboards, since the '=' key is in a completely different place to where it is on a Japanese keyboard.
-				// To solve this, we use scancodes instead, which are based on the physical location of keys, rather than their meaning.
-				switch (event.key.keysym.scancode)
-				{
-					case SDL_SCANCODE_ESCAPE:
-						DO_KEY_PRESS(KEY_ESCAPE)
+				case SC_KEYMENU:
+					break;
 
-					case SDL_SCANCODE_W:
-						DO_KEY_PRESS(KEY_MAP)
+				case SC_SCREENSAVE:
+					break;
 
-					case SDL_SCANCODE_LEFT:
-						DO_KEY_PRESS(KEY_LEFT)
+				default:
+					DefWindowProcA(hWnd, Msg, wParam, lParam);
+					break;
+			}
 
-					case SDL_SCANCODE_RIGHT:
-						DO_KEY_PRESS(KEY_RIGHT)
+			break;
 
-					case SDL_SCANCODE_UP:
-						DO_KEY_PRESS(KEY_UP)
+		case WM_IME_NOTIFY:
+			if (wParam == IMN_SETOPENSTATUS)
+			{
+				HIMC hImc = ImmGetContext(hWnd);
+				ImmSetOpenStatus(hImc, 0);
+				ImmReleaseContext(hWnd, hImc);
+			}
 
-					case SDL_SCANCODE_DOWN:
-						DO_KEY_PRESS(KEY_DOWN)
+			break;
 
-					case SDL_SCANCODE_X:
-						DO_KEY_PRESS(KEY_X)
+		case WM_KEYDOWN:
+			switch (wParam)
+			{
+				case VK_ESCAPE:
+					gKey |= KEY_ESCAPE;
+					break;
 
-					case SDL_SCANCODE_Z:
-						DO_KEY_PRESS(KEY_Z)
+				case 'W':
+					gKey |= KEY_MAP;
+					break;
 
-					case SDL_SCANCODE_S:
-						DO_KEY_PRESS(KEY_ARMS)
+				case VK_LEFT:
+					gKey |= KEY_LEFT;
+					break;
 
-					case SDL_SCANCODE_A:
-						DO_KEY_PRESS(KEY_ARMSREV)
+				case VK_RIGHT:
+					gKey |= KEY_RIGHT;
+					break;
 
-					case SDL_SCANCODE_RSHIFT:
-					case SDL_SCANCODE_LSHIFT:
-						DO_KEY_PRESS(KEY_SHIFT)
+				case VK_UP:
+					gKey |= KEY_UP;
+					break;
 
-					case SDL_SCANCODE_F1:
-						DO_KEY_PRESS(KEY_F1)
+				case VK_DOWN:
+					gKey |= KEY_DOWN;
+					break;
 
-					case SDL_SCANCODE_F2:
-						DO_KEY_PRESS(KEY_F2)
+				case 'X':
+					gKey |= KEY_X;
+					break;
 
-					case SDL_SCANCODE_Q:
-						DO_KEY_PRESS(KEY_ITEM)
+				case 'Z':
+					gKey |= KEY_Z;
+					break;
 
-					case SDL_SCANCODE_COMMA:
-						DO_KEY_PRESS(KEY_ALT_LEFT)
+				case 'S':
+					gKey |= KEY_ARMS;
+					break;
 
-					case SDL_SCANCODE_PERIOD:
-						DO_KEY_PRESS(KEY_ALT_DOWN)
+				case 'A':
+					gKey |= KEY_ARMSREV;
+					break;
 
-					case SDL_SCANCODE_SLASH:
-						DO_KEY_PRESS(KEY_ALT_RIGHT)
+				case VK_SHIFT:
+					gKey |= KEY_SHIFT;
+					break;
 
-					case SDL_SCANCODE_L:
-						DO_KEY_PRESS(KEY_ALT_UP)
+				case VK_F1:
+					gKey |= KEY_F1;
+					break;
 
-					case SDL_SCANCODE_SEMICOLON:
-						DO_KEY_PRESS(KEY_PLUS)
+				case VK_F2:
+					gKey |= KEY_F2;
+					break;
 
-					case SDL_SCANCODE_F5:
-						gbUseJoystick = FALSE;
-						break;
+				case 'Q':
+					gKey |= KEY_ITEM;
+					break;
 
-					default:
-						break;
-				}
-				break;
-#else
-				switch (event.key.keysym.sym)
-				{
-					case SDLK_ESCAPE:
-						DO_KEY_PRESS(KEY_ESCAPE)
+				case VK_OEM_COMMA:
+					gKey |= KEY_ALT_LEFT;
+					break;
 
-					case SDLK_w:
-						DO_KEY_PRESS(KEY_MAP)
+				case VK_OEM_PERIOD:
+					gKey |= KEY_ALT_DOWN;
+					break;
 
-					case SDLK_LEFT:
-						DO_KEY_PRESS(KEY_LEFT)
+				case VK_OEM_2:
+					gKey |= KEY_ALT_RIGHT;
+					break;
 
-					case SDLK_RIGHT:
-						DO_KEY_PRESS(KEY_RIGHT)
+				case 'L':
+					gKey |= KEY_L;
+					break;
 
-					case SDLK_UP:
-						DO_KEY_PRESS(KEY_UP)
+				case VK_OEM_PLUS:
+					gKey |= KEY_PLUS;
+					break;
 
-					case SDLK_DOWN:
-						DO_KEY_PRESS(KEY_DOWN)
+				case VK_F5:
+					gbUseJoystick = FALSE;
+					break;
+			}
 
-					case SDLK_x:
-						DO_KEY_PRESS(KEY_X)
+			break;
 
-					case SDLK_z:
-						DO_KEY_PRESS(KEY_Z)
+		case WM_KEYUP:
+			switch (wParam)
+			{
+				case VK_ESCAPE:
+					gKey &= ~KEY_ESCAPE;
+					break;
 
-					case SDLK_s:
-						DO_KEY_PRESS(KEY_ARMS)
+				case 'W':
+					gKey &= ~KEY_MAP;
+					break;
 
-					case SDLK_a:
-						DO_KEY_PRESS(KEY_ARMSREV)
+				case VK_LEFT:
+					gKey &= ~KEY_LEFT;
+					break;
 
-					case SDLK_RSHIFT:
-					case SDLK_LSHIFT:
-						DO_KEY_PRESS(KEY_SHIFT)
+				case VK_RIGHT:
+					gKey &= ~KEY_RIGHT;
+					break;
 
-					case SDLK_F1:
-						DO_KEY_PRESS(KEY_F1)
+				case VK_UP:
+					gKey &= ~KEY_UP;
+					break;
 
-					case SDLK_F2:
-						DO_KEY_PRESS(KEY_F2)
+				case VK_DOWN:
+					gKey &= ~KEY_DOWN;
+					break;
 
-					case SDLK_q:
-						DO_KEY_PRESS(KEY_ITEM)
+				case 'X':
+					gKey &= ~KEY_X;
+					break;
 
-					case SDLK_COMMA:
-						DO_KEY_PRESS(KEY_ALT_LEFT)
+				case 'Z':
+					gKey &= ~KEY_Z;
+					break;
 
-					case SDLK_PERIOD:
-						DO_KEY_PRESS(KEY_ALT_DOWN)
+				case 'S':
+					gKey &= ~KEY_ARMS;
+					break;
 
-					case SDLK_SLASH:
-						DO_KEY_PRESS(KEY_ALT_RIGHT)
+				case 'A':
+					gKey &= ~KEY_ARMSREV;
+					break;
 
-					case SDLK_l:
-						DO_KEY_PRESS(KEY_ALT_UP)
+				case VK_SHIFT:
+					gKey &= ~KEY_SHIFT;
+					break;
 
-					case SDLK_SEMICOLON:
-						DO_KEY_PRESS(KEY_PLUS)
+				case VK_F1:
+					gKey &= ~KEY_F1;
+					break;
 
-					case SDLK_F5:
-						gbUseJoystick = FALSE;
-						break;
-				}
-				break;
-#endif
-		}
+				case VK_F2:
+					gKey &= ~KEY_F2;
+					break;
+
+				case 'Q':
+					gKey &= ~KEY_ITEM;
+					break;
+
+				case VK_OEM_COMMA:
+					gKey &= ~KEY_ALT_LEFT;
+					break;
+
+				case VK_OEM_PERIOD:
+					gKey &= ~KEY_ALT_DOWN;
+					break;
+
+				case VK_OEM_2:
+					gKey &= ~KEY_ALT_RIGHT;
+					break;
+
+				case 'L':
+					gKey &= ~KEY_L;
+					break;
+
+				case VK_OEM_PLUS:
+					gKey &= ~KEY_PLUS;
+					break;
+			}
+
+			break;
+
+		case WM_COMMAND:
+			switch (LOWORD(wParam))
+			{
+				case 40001:
+					if (DialogBoxParamA(ghInstance, "DLG_YESNO", hWnd, QuitDialog, (LPARAM)"Quit?") == 1)
+						PostMessageA(hWnd, WM_CLOSE, 0, 0);
+					break;
+
+				case 40002:
+					DialogBoxParamA(ghInstance, "DLG_ABOUT", hWnd, VersionDialog, NULL);
+					break;
+
+				case 40004:
+					if (!OpenVolumeConfiguration(hWnd))
+					#ifdef JAPANESE
+						MessageBoxA(hWnd, "â{âèâàü[âÇɦÆÞé­ïNô«é+é½é_é¦é±é+éÁé¢", lpWindowName, NULL);
+					#else
+						MessageBoxA(hWnd, "Could not launch volume configuration", lpWindowName, NULL);
+					#endif
+					break;
+
+				case 40005:
+					DialogBoxParamA(ghInstance, "DLG_SAVE", hWnd, DebugSaveDialog, NULL);
+					break;
+
+				case 40007:
+					DialogBoxParamA(ghInstance, "DLG_MUTE", hWnd, DebugMuteDialog, NULL);
+					break;
+			}
+
+			break;
+
+		case WM_DROPFILES:
+			DragAndDropHandler(hWnd, wParam);
+			break;
+
+		case WM_ACTIVATE:
+			switch (LOWORD(wParam))
+			{
+				case WA_INACTIVE:
+					window_focus = FALSE;
+					break;
+
+				case WA_ACTIVE:
+				case WA_CLICKACTIVE:
+					if (HIWORD(wParam) != 0)
+						window_focus = FALSE;
+					else
+						window_focus = TRUE;
+
+					break;
+			}
+
+			if (window_focus)
+				ActiveWindow();
+			else
+				InactiveWindow();
+
+			break;
+
+		case WM_CLOSE:
+			StopOrganyaMusic();
+			PostQuitMessage(0);
+			break;
+
+		default:
+			return DefWindowProcA(hWnd, Msg, wParam, lParam);
 	}
-*/
+
+	return 1;
+}
+
+void JoystickProc(void);
+
+BOOL SystemTask(void)
+{
+	MSG Msg;
+
+	while (PeekMessageA(&Msg, NULL, 0, 0, PM_NOREMOVE) || !bActive)
+	{
+		if (!GetMessageA(&Msg, NULL, 0, 0))
+			return FALSE;
+
+		TranslateMessage(&Msg);
+		DispatchMessageA(&Msg);
+	}
+
 	// Run joystick code
 	if (gbUseJoystick)
 		JoystickProc();
 
 	return TRUE;
+}
+
+void JoystickProc(void)
+{
+	JOYSTICK_STATUS status;
+
+	if (!GetJoystickStatus(&status))
+		return;
+
+	gKey &= (KEY_ESCAPE | KEY_F2 | KEY_F1);
+
+	// Set movement buttons
+	if (status.bLeft)
+		gKey |= gKeyLeft;
+	else
+		gKey &= ~gKeyLeft;
+
+	if (status.bRight)
+		gKey |= gKeyRight;
+	else
+		gKey &= ~gKeyRight;
+
+	if (status.bUp)
+		gKey |= gKeyUp;
+	else
+		gKey &= ~gKeyUp;
+
+	if (status.bDown)
+		gKey |= gKeyDown;
+	else
+		gKey &= ~gKeyDown;
+
+	// Clear held buttons
+	for (int i = 0; i < 8; i++)
+		gKey &= ~gJoystickButtonTable[i];
+
+	// Set held buttons
+	for (int i = 0; i < 8; i++)
+	{
+		if (status.bButton[i])
+			gKey |= gJoystickButtonTable[i];
+	}
 }
--- a/src/Main.h
+++ b/src/Main.h
@@ -5,5 +5,5 @@
 extern HWND ghWnd;
 extern BOOL bFullscreen;
 
-void PutFramePerSecound();
-int GetFramePerSecound();
+void PutFramePerSecound(void);
+int GetFramePerSecound(void);