From a7e3503e2c80af00a31b4299091bd16d19f033c8 Mon Sep 17 00:00:00 2001 From: haruna Date: Sun, 17 Oct 2021 13:49:17 +0900 Subject: [PATCH 1/5] fix: lint README to make more linkable (#40) * fix: lint README to make more linkable * restore blank lines between `Known source ports` and `Source` --- README.md | 112 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index b81a792..225e650 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,87 @@ -# SpaceCadetPinball -**Summary:** Reverse engineering of `3D Pinball for Windows – Space Cadet`, a game bundled with Windows. + -**How to play:** Place compiled executable into a folder containing original game resources (not included).\ +# SpaceCadetPinball + +## Summary + +Reverse engineering of `3D Pinball for Windows – Space Cadet`, a game bundled with Windows. + +## How to play + +Place compiled executable into a folder containing original game resources (not included).\ Supports data files from Windows and Full Tilt versions of the game. -**Known source ports:** -| Platform | Author | URL | -| --- | --- | --- | -| PS Vita | Axiom | | -| Emscripten | alula |
Play online: https://alula.github.io/SpaceCadetPinball | -| Nintendo Switch | averne | https://github.com/averne/SpaceCadetPinball-NX | -| webOS TV | mariotaku | https://github.com/webosbrew/SpaceCadetPinball | +## Known source ports + +| Platform | Author | URL | +| --------------- | --------- | ---------------------------------------------------------------------------------------------------------- | +| PS Vita | Axiom | | +| Emscripten | alula |
Play online: | +| Nintendo Switch | averne | | +| webOS TV | mariotaku | | Platforms covered by this project: desktop Windows, Linux and macOS. -\ -\ -\ -\ -\ -\ -**Source:** - * `pinball.exe` from `Windows XP` (SHA-1 `2A5B525E0F631BB6107639E2A69DF15986FB0D05`) and its public PDB - * `CADET.EXE` 32bit version from `Full Tilt! Pinball` (SHA-1 `3F7B5699074B83FD713657CD94671F2156DBEDC4`) -**Tools used:** `Ghidra`, `Ida`, `Visual Studio` +
+
+
+
+
+
-**What was done:** - * All structures were populated, globals and locals named. - * All subs were decompiled, C pseudo code was converted to compilable C++. Loose (namespace?) subs were assigned to classes. +## Source -**Compiling:** +* `pinball.exe` from `Windows XP` (SHA-1 `2A5B525E0F631BB6107639E2A69DF15986FB0D05`) and its public PDB +* `CADET.EXE` 32bit version from `Full Tilt! Pinball` (SHA-1 `3F7B5699074B83FD713657CD94671F2156DBEDC4`) + +## Tools used + +`Ghidra`, `Ida`, `Visual Studio` + +## What was done + +* All structures were populated, globals and locals named. +* All subs were decompiled, C pseudo code was converted to compilable C++. Loose (namespace?) subs were assigned to classes. + +## Compiling + +Project uses `C++11` and depends on `SDL2` libs. + +### On Windows -Project uses `C++11` and depends on `SDL2` libs.\ -On Windows:\ Download and unpack devel packages for `SDL2` and `SDL2_mixer`.\ -Set paths to them in CMakeLists.txt, see suggested placement in /Libs.\ -Compile with Visual Studio; tested with 2019. +Set paths to them in `CMakeLists.txt`, see suggested placement in `/Libs`.\ +Compile with Visual Studio; tested with 2019. + +### On Linux -On Linux:\ Install devel packages for `SDL2` and `SDL2_mixer`.\ Compile with CMake; tested with GCC 10, Clang 11.\ -To cross-compile for Windows, install a 64-bit version of mingw and its `SDL2` and `SDL2_mixer` distributions, then use the `mingwcc.cmake` toolchain. +To cross-compile for Windows, install a 64-bit version of mingw and its `SDL2` and `SDL2_mixer` distributions, then use the `mingwcc.cmake` toolchain. + +### On macOS + +* **Homebrew**: Install the `SDL2`, `SDL2_mixer` homebrew packages. +* **MacPorts**: Install the `libSDL2`, `libSDL2_mixer` macports packages. + +Compile with CMake. Ensure that `CMAKE_OSX_ARCHITECTURES` variable is set for either `x86_64` Apple Intel or `arm64` for Apple Silicon. -On macOS:\ -**Homebrew**: Install the `SDL2`, `SDL2_mixer` homebrew packages.\ -**MacPorts**: Install the `libSDL2`, `libSDL2_mixer` macports packages.\ -Compile with CMake. Ensure that `CMAKE_OSX_ARCHITECTURES` variable is set for either `x86_64` Apple Intel or `arm64` for Apple Silicon.\ Tested with: macOS Big Sur (Intel) with Xcode 13 & macOS Montery Beta (Apple Silicon) with Xcode 13. -**Plans:** - * ~~Decompile original game~~ - * ~~Resizable window, scaled graphics~~ - * ~~Loader for high-res sprites from CADET.DAT~~ - * Misc features of Full Tilt: 3 music tracks, multiball, centered textboxes, etc. - * Cross-platform port - * Using SDL2, SDL2_mixer, ImGui - * Maybe: Android port - * Maybe x2: support for other two tables - * Table specific BL (control interactions and missions) is hardcoded, othere parts might be also patched +## Plans + +* ~~Decompile original game~~ +* ~~Resizable window, scaled graphics~~ +* ~~Loader for high-res sprites from CADET.DAT~~ +* Misc features of Full Tilt: 3 music tracks, multiball, centered textboxes, etc. +* Cross-platform port + * Using SDL2, SDL2_mixer, ImGui + * Maybe: Android port +* Maybe x2: support for other two tables + * Table specific BL (control interactions and missions) is hardcoded, othere parts might be also patched + +## On 64-bit bug that killed the game -**On 64-bit bug that killed the game:**\ I did not find it, decompiled game worked in x64 mode on the first try.\ It was either lost in decompilation or introduced in x64 port/not present in x86 build.\ Based on public description of the bug (no ball collision), I guess that the bug was in `TEdgeManager::TestGridBox` From f56abf05969cc5ecae8654ce0bcfa324d161084f Mon Sep 17 00:00:00 2001 From: Mariotaku Date: Sun, 17 Oct 2021 13:52:05 +0900 Subject: [PATCH 2/5] Compatibility and game controller patches (#42) * Compatibility for old CMake versions (3.0) Compatibility for SDL Mixer 2.0.1 Basic controller support: LB, RB for flippers, A for plunger, DPAD for table bump * Update SpaceCadetPinball/Sound.cpp Co-authored-by: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> --- CMakeLists.txt | 13 +++++--- SpaceCadetPinball/Sound.cpp | 4 +++ SpaceCadetPinball/winmain.cpp | 63 +++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d729de1..a7bf214 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.0) project(SpaceCadetPinball) set(CMAKE_CXX_STANDARD 11) @@ -191,10 +191,13 @@ set_source_files_properties( SpaceCadetPinball/imgui_impl_sdl.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS 1 ) -target_precompile_headers(SpaceCadetPinball - PUBLIC - SpaceCadetPinball/pch.h -) + +if(${CMAKE_VERSION} VERSION_GREATER "3.16.0" OR ${CMAKE_VERSION} VERSION_EQUAL "3.16.0") + target_precompile_headers(SpaceCadetPinball + PUBLIC + SpaceCadetPinball/pch.h + ) +endif() target_link_libraries(SpaceCadetPinball ${SDL2_LIBRARY} ${SDL2_MIXER_LIBRARY}) diff --git a/SpaceCadetPinball/Sound.cpp b/SpaceCadetPinball/Sound.cpp index 902c042..d492459 100644 --- a/SpaceCadetPinball/Sound.cpp +++ b/SpaceCadetPinball/Sound.cpp @@ -8,7 +8,11 @@ int* Sound::TimeStamps = nullptr; bool Sound::Init(int channels, bool enableFlag) { +#if SDL_MIXER_VERSION_ATLEAST(2, 0, 3) Mix_Init(MIX_INIT_MID); +#else + Mix_Init(MIX_INIT_FLUIDSYNTH); +#endif auto result = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); SetChannels(channels); Enable(enableFlag); diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index f8951e8..eb154a2 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -741,6 +741,69 @@ int winmain::event_handler(const SDL_Event* event) default: ; } break; + case SDL_JOYDEVICEADDED: + if (SDL_IsGameController(event->jdevice.which)) + { + SDL_GameControllerOpen(event->jdevice.which); + } + break; + case SDL_JOYDEVICEREMOVED: + { + SDL_GameController *controller = SDL_GameControllerFromInstanceID(event->jdevice.which); + if (controller) + { + SDL_GameControllerClose(controller); + } + } + break; + case SDL_CONTROLLERBUTTONDOWN: + switch (event->cbutton.button) + { + case SDL_CONTROLLER_BUTTON_A: + pb::keydown(Options.Key.Plunger); + break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + pb::keydown(Options.Key.LeftFlipper); + break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + pb::keydown(Options.Key.RightFlipper); + break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + pb::keydown(Options.Key.LeftTableBump); + break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + pb::keydown(Options.Key.RightTableBump); + break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + pb::keydown(Options.Key.BottomTableBump); + break; + default: ; + } + break; + case SDL_CONTROLLERBUTTONUP: + switch (event->cbutton.button) + { + case SDL_CONTROLLER_BUTTON_A: + pb::keyup(Options.Key.Plunger); + break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + pb::keyup(Options.Key.LeftFlipper); + break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + pb::keyup(Options.Key.RightFlipper); + break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + pb::keyup(Options.Key.LeftTableBump); + break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + pb::keyup(Options.Key.RightTableBump); + break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + pb::keyup(Options.Key.BottomTableBump); + break; + default: ; + } + break; default: ; } From b7bf1563e51e09fd219424cb74356b162b956944 Mon Sep 17 00:00:00 2001 From: Iscle Date: Sun, 17 Oct 2021 06:58:00 +0200 Subject: [PATCH 3/5] Update README.md (#45) Co-authored-by: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 225e650..a0dda1c 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ Supports data files from Windows and Full Tilt versions of the game. | Emscripten | alula |
Play online: | | Nintendo Switch | averne | | | webOS TV | mariotaku | | +| Android (WIP) | Iscle | https://github.com/Iscle/SpaceCadetPinball | Platforms covered by this project: desktop Windows, Linux and macOS. From 787c623cfe14c801ecd000a6bb5dd31e50df4e60 Mon Sep 17 00:00:00 2001 From: Mariotaku Date: Sun, 17 Oct 2021 15:00:49 +0900 Subject: [PATCH 4/5] Backward compatibility for mixer version check (#46) SDL_MIXER_VERSION_ATLEAST isn't available in SDL Mixer 2.0.1, which will cause build errors. --- SpaceCadetPinball/Sound.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SpaceCadetPinball/Sound.cpp b/SpaceCadetPinball/Sound.cpp index d492459..dfcc4bd 100644 --- a/SpaceCadetPinball/Sound.cpp +++ b/SpaceCadetPinball/Sound.cpp @@ -1,6 +1,9 @@ #include "pch.h" #include "Sound.h" +#ifndef SDL_MIXER_VERSION_ATLEAST +#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) +#endif int Sound::num_channels; bool Sound::enabled_flag = false; From d06aa1c736d752c9fe31063a134c00a90e686372 Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Sun, 17 Oct 2021 12:00:30 +0300 Subject: [PATCH 5/5] Changed SDL_mixer version guard. SDL_MIXER_COMPILEDVERSION is not in Windows release of mixer v2.0.1, so it is back to basics with SDL_MIXER_PATCHLEVEL. MIX_INIT_FLUIDSYNTH was renamed in 2.0.2, according to headers from Windows releases. Ref PR #42, #46 --- SpaceCadetPinball/Sound.cpp | 10 +--------- SpaceCadetPinball/pch.h | 8 ++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/SpaceCadetPinball/Sound.cpp b/SpaceCadetPinball/Sound.cpp index dfcc4bd..4fa9336 100644 --- a/SpaceCadetPinball/Sound.cpp +++ b/SpaceCadetPinball/Sound.cpp @@ -1,21 +1,13 @@ #include "pch.h" #include "Sound.h" -#ifndef SDL_MIXER_VERSION_ATLEAST -#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) -#endif - int Sound::num_channels; bool Sound::enabled_flag = false; int* Sound::TimeStamps = nullptr; bool Sound::Init(int channels, bool enableFlag) { -#if SDL_MIXER_VERSION_ATLEAST(2, 0, 3) - Mix_Init(MIX_INIT_MID); -#else - Mix_Init(MIX_INIT_FLUIDSYNTH); -#endif + Mix_Init(MIX_INIT_MID_Proxy); auto result = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); SetChannels(channels); Enable(enableFlag); diff --git a/SpaceCadetPinball/pch.h b/SpaceCadetPinball/pch.h index c1fa767..9a49af3 100644 --- a/SpaceCadetPinball/pch.h +++ b/SpaceCadetPinball/pch.h @@ -34,6 +34,14 @@ #include "SDL.h" #include +// MIX_INIT_FLUIDSYNTH was renamed to MIX_INIT_MID in SDL_mixer v2.0.2 +constexpr int MIX_INIT_MID_Proxy = +#if SDL_MIXER_PATCHLEVEL >= 2 + MIX_INIT_MID; +#else + MIX_INIT_FLUIDSYNTH; +#endif + //https://github.com/ocornut/imgui 7b913db1ce9dd2fd98e5790aa59974dd4496be3b #include "imgui.h" #include "imgui_internal.h"