diff --git a/README.md b/README.md index 9e8f27b8..3061beec 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ cd scripts **Prerequisites**: `git`, `make`, `7zip` -*Note: Building on Windows is temporarily not working. You can still build on Windows using WSL.* +*Note: Building Windows is untested with the new build system. If you encounter issues, you can still build on Windows using WSL.* ```powershell cd scripts @@ -142,7 +142,6 @@ The project is divided into the following directories: * `config` - Config files for Splat (binary splitting tool). * `scripts` - Utility scripts for setting up the build environment. * `docs` - Documentation and instructions for contributing. -* `test` - Handwritten unit tests for the decomp code. * `tools` - Utilities for function matching. * `reference` - Reference files for functions and data structures. diff --git a/build/README.txt b/build/readme.txt similarity index 100% rename from build/README.txt rename to build/readme.txt diff --git a/config/readme.txt b/config/readme.txt new file mode 100644 index 00000000..6a0e218c --- /dev/null +++ b/config/readme.txt @@ -0,0 +1 @@ +This directory contains config files for Splat, which is used for Binary splitting. diff --git a/disc/.gitkeep b/disc/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/disc/readme.txt b/disc/readme.txt new file mode 100644 index 00000000..f6eea6cc --- /dev/null +++ b/disc/readme.txt @@ -0,0 +1 @@ +To build the project, you need to extract the executable file SCUS_971.98 from your own copy of the game and put it in this directory. diff --git a/reference/readme.txt b/reference/readme.txt index 97dd2f13..189f3677 100644 --- a/reference/readme.txt +++ b/reference/readme.txt @@ -1,4 +1,4 @@ -This directory contains reference files you can use to help with decompiling game functions. They are all source code files we wrote by hand before we used Splat to decompile and reassemble the game to a byte-matching executable. Because of this, none of the functions in this directory is matching, but we tried to make them as close as possible to the original game functions. +This directory contains reference files you can use to help with decompiling game functions. They are all source code files we wrote by hand before we used Splat to decompile and reassemble the game to a byte-matching executable. Because of this, none of the functions in this directory match, but we tried to make them as close as possible to the original game functions. The include directory contains header files that are used by the source files in the src dir. Many of the short data structures/enums are correct and can be copied directly into the actual decomp. The longer ones are probably not correct (missing fields, wrong field types, etc), but they can be used as a reference. diff --git a/test/AddUnitTest.cmake b/test/AddUnitTest.cmake deleted file mode 100644 index bcfd9ea2..00000000 --- a/test/AddUnitTest.cmake +++ /dev/null @@ -1,24 +0,0 @@ -macro(add_unit_test) - set(options PARALLEL) - set(oneValueArgs NAME) - set(multiValueArgs SOURCES LIBS) - cmake_parse_arguments(TEST "${options}" "${oneValueArgs}" - "${multiValueArgs}" ${ARGN}) - message(STATUS "Generating Test ${TEST_NAME}... (${TEST_SOURCES})") - add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_SOURCES}) - target_link_libraries(${TEST_NAME} ${TEST_LIBS}) - if(TEST_PARALLEL AND HAVE_MPI) - set(TESTCOMMAND ${MPIEXEC}) - set(TESTARGS ${MPIEXEC_NUMPROC_FLAG} 3 ${MPIEXEC_PREFLAGS} - "./${TEST_NAME}" ${MPIEXEC_POSTFLAGS}) - set(TESTCOMMAND ${TESTCOMMAND} ${TESTARGS}) - else() - set(TESTCOMMAND ${TEST_NAME}) - endif() - add_test(NAME ${TEST_NAME} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin/tests - COMMAND ${TESTCOMMAND}) - - get_property(TESTNAMES GLOBAL PROPERTY TESTNAMES) - set_property(GLOBAL PROPERTY TESTNAMES ${TESTNAMES} ${TEST_NAME}) -endmacro(add_unit_test) diff --git a/test/clock/CMakeLists.txt b/test/clock/CMakeLists.txt deleted file mode 100644 index af761eb8..00000000 --- a/test/clock/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ - -add_unit_test(PARALLEL TRUE NAME clock.set_clock_rate SOURCES set_clock_rate.cpp LIBS ${P2_LIB_TARGET}) diff --git a/test/clock/set_clock_rate.cpp b/test/clock/set_clock_rate.cpp deleted file mode 100644 index 9117cba6..00000000 --- a/test/clock/set_clock_rate.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include - -#include - -int main() -{ - SetClockRate(1.0); - JtAssert(g_rtClock == 1.0f); - JtAssert(g_clock.fEnabled); - - SetClockRate(0.5); - JtAssert(g_rtClock == 0.5f); - JtAssert(g_clock.fEnabled); - - SetClockRate(0); - JtAssert(g_rtClock == 0.f); - JtAssert(!g_clock.fEnabled); - - SetClockRate(-1); - JtAssert(g_rtClock == -1.f); - JtAssert(!g_clock.fEnabled); - - return 0; -} diff --git a/test/coin/CMakeLists.txt b/test/coin/CMakeLists.txt deleted file mode 100644 index 9420cdf9..00000000 --- a/test/coin/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ - -add_unit_test(PARALLEL TRUE NAME coin.collect_coins SOURCES collect_coins.cpp LIBS ${P2_LIB_TARGET}) diff --git a/test/coin/collect_coins.cpp b/test/coin/collect_coins.cpp deleted file mode 100644 index 012228f6..00000000 --- a/test/coin/collect_coins.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -#include - -int main() -{ - COIN coin; - - // Test collecting a coin normally - g_pgsCur->ccoin = 0; - g_pgsCur->ccharm = 0; - OnCoinSmack(&coin); - - JtAssert(g_pgsCur->ccoin == 1); - JtAssert(g_pgsCur->ccharm == 0); - - g_pgsCur->ccoin = 98; - OnCoinSmack(&coin); - - JtAssert(g_pgsCur->ccoin == 99); - JtAssert(g_pgsCur->ccharm == 0); - - // Test collecting a 100 coins to get a charm - OnCoinSmack(&coin); - - JtAssert(g_pgsCur->ccoin == 0); - JtAssert(g_pgsCur->ccharm == 1); - - // Test collecting 100 coins to get an extra life - g_pgsCur->ccoin = 99; - g_pgsCur->ccharm = 2; - g_pgsCur->clife = 5; - OnCoinSmack(&coin); - - JtAssert(g_pgsCur->ccoin == 0); - JtAssert(g_pgsCur->ccharm == 2); - JtAssert(g_pgsCur->clife == 6); - - // Test collecting a coin when coins, lives, and charms are all at max - g_pgsCur->ccoin = 99; - g_pgsCur->ccharm = 2; - g_pgsCur->clife = 99; - OnCoinSmack(&coin); - - JtAssert(g_pgsCur->ccoin == 99); - JtAssert(g_pgsCur->ccharm == 2); - JtAssert(g_pgsCur->clife == 99); -} diff --git a/test/difficulty/CMakeLists.txt b/test/difficulty/CMakeLists.txt deleted file mode 100644 index ebd9561e..00000000 --- a/test/difficulty/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ - -add_unit_test(PARALLEL TRUE NAME difficulty.change_suck SOURCES change_suck.cpp LIBS ${P2_LIB_TARGET}) -add_unit_test(PARALLEL TRUE NAME difficulty.world_preload SOURCES world_preload.cpp LIBS ${P2_LIB_TARGET}) diff --git a/test/difficulty/change_suck.cpp b/test/difficulty/change_suck.cpp deleted file mode 100644 index 370c47a3..00000000 --- a/test/difficulty/change_suck.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -#include - -int main() -{ - // Initialize difficulty - OnDifficultyGameLoad(&g_difficulty); - OnDifficultyWorldPreLoad(&g_difficulty); - OnDifficultyWorldPostLoad(&g_difficulty); - - // Test changing level suck - g_plsCur->uSuck = 0.0f; - JtAssert(g_plsCur->uSuck == 0.0f); - - ChangeSuck(0.1, &g_difficulty); - JtAssert(g_plsCur->uSuck == 0.1f); - - ChangeSuck(1.0, &g_difficulty); - JtAssert(g_plsCur->uSuck == 1.0f); - - ChangeSuck(-1.0, &g_difficulty); - JtAssert(g_plsCur->uSuck == -1.0f); - - // Test collect key scenario - OnDifficultyCollectKey(&g_difficulty); - JtAssert(g_plsCur->uSuck == 0.0f); -} diff --git a/test/difficulty/world_preload.cpp b/test/difficulty/world_preload.cpp deleted file mode 100644 index 7c149221..00000000 --- a/test/difficulty/world_preload.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -#include - -void SetGameLevel(GAMEWORLD gameworld, WORLDLEVEL worldlevel); - -int main() -{ - // Initialize difficulty - OnDifficultyGameLoad(&g_difficulty); - - - // jb_intro = easy - SetGameLevel(GAMEWORLD_Intro, WORLDLEVEL_Approach); - OnDifficultyWorldPreLoad(&g_difficulty); - JtAssert(g_difficulty.pdifficultyLevel == &g_difficultyEasy); - - - // cw_security = easy - SetGameLevel(GAMEWORLD_Clockwerk, WORLDLEVEL_Level2); - OnDifficultyWorldPreLoad(&g_difficulty); - JtAssert(g_difficulty.pdifficultyLevel == &g_difficultyEasy); - - - // uw_bonus_security - SetGameLevel(GAMEWORLD_Underwater, WORLDLEVEL_Level3); - - // no key = medium - g_plsCur->fls = static_cast((int)g_plsCur->fls & ~(int)FLS_KeyCollected); // unset KeyCollected flag - OnDifficultyWorldPreLoad(&g_difficulty); - JtAssert(g_difficulty.pdifficultyLevel == &g_difficultyMedium); - - // with key = hard - g_plsCur->fls = static_cast((int)g_plsCur->fls | (int)FLS_KeyCollected); // setKeyCollected flag - OnDifficultyWorldPreLoad(&g_difficulty); - JtAssert(g_difficulty.pdifficultyLevel == &g_difficultyHard); - - return 0; -} - -void SetGameLevel(GAMEWORLD gameworld, WORLDLEVEL worldlevel) -{ - g_pwsCur = &g_pgsCur->aws[(int)gameworld]; - g_plsCur = &g_pwsCur->als[(int)worldlevel]; - g_pgsCur->gameworldCur = gameworld; - g_pgsCur->worldlevelCur = worldlevel; -} diff --git a/test/game/CMakeLists.txt b/test/game/CMakeLists.txt deleted file mode 100644 index e7fa657a..00000000 --- a/test/game/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ - -add_unit_test(PARALLEL TRUE NAME game.set_coin_count SOURCES set_coin_count.cpp LIBS ${P2_LIB_TARGET}) -add_unit_test(PARALLEL TRUE NAME game.set_charm_count SOURCES set_charm_count.cpp LIBS ${P2_LIB_TARGET}) -add_unit_test(PARALLEL TRUE NAME game.charm_available SOURCES charm_available.cpp LIBS ${P2_LIB_TARGET}) diff --git a/test/game/charm_available.cpp b/test/game/charm_available.cpp deleted file mode 100644 index bef48312..00000000 --- a/test/game/charm_available.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include - -int main() -{ - g_pgsCur->ccoin = 1; // set coins to 1 - g_grfcht &= ~((int)FCHT_InfiniteCharms); // disable infinite charms - - // Confirm max charm count is 2 - JtAssert(CcharmMost() == 2); - - // Test checking if a charm is available - g_pgsCur->ccharm = 0; - JtAssert(FCharmAvailable() == false); - - g_pgsCur->ccharm = 1; - JtAssert(FCharmAvailable() == true); - - g_pgsCur->ccharm = -1; - JtAssert(FCharmAvailable() == false); - - g_pgsCur->ccharm = 0; - g_grfcht |= (int)FCHT_InfiniteCharms; // enable infinite charms cheat - JtAssert(FCharmAvailable() == true); - - // Test setting charm count - SetCcharm(0); - JtAssert(g_pgsCur->ccharm == 0); - - SetCcharm(1); - JtAssert(g_pgsCur->ccharm == 1); - - SetCcharm(3); - JtAssert(g_pgsCur->ccharm == 3); - - SetCcharm(-1); - JtAssert(g_pgsCur->ccharm == -1); - - return 0; -} diff --git a/test/game/set_charm_count.cpp b/test/game/set_charm_count.cpp deleted file mode 100644 index 9549e306..00000000 --- a/test/game/set_charm_count.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include - -#include - -int main() -{ - // Confirm max charm count is 2 - JtAssert(CcharmMost() == 2); - - // Test setting charm count - SetCcharm(0); - JtAssert(g_pgsCur->ccharm == 0); - - SetCcharm(1); - JtAssert(g_pgsCur->ccharm == 1); - - SetCcharm(3); - JtAssert(g_pgsCur->ccharm == 3); - - SetCcharm(-1); - JtAssert(g_pgsCur->ccharm == -1); - - return 0; -} diff --git a/test/game/set_coin_count.cpp b/test/game/set_coin_count.cpp deleted file mode 100644 index 9e2a2cf8..00000000 --- a/test/game/set_coin_count.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include - -#include - -int main() -{ - g_pgsCur->ccoin = 1; // set coins to 1 - g_pgsCur->ccharm = 0; // set charms to 0 - - // Test setting coin count - SetCcoin(0); - JtAssert(g_pgsCur->ccoin == 0); - - SetCcoin(14); - JtAssert(g_pgsCur->ccoin == 14); - - SetCcoin(99); - JtAssert(g_pgsCur->ccoin == 99); - - SetCcoin(-1); - JtAssert(g_pgsCur->ccoin == -1); - - SetCcoin(101); - JtAssert(g_pgsCur->ccoin == 101); - - return 0; -} \ No newline at end of file diff --git a/test/gs/CMakeLists.txt b/test/gs/CMakeLists.txt deleted file mode 100644 index 3b75468b..00000000 --- a/test/gs/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ - -add_unit_test(PARALLEL TRUE NAME gs.calculate_gs_percent SOURCES calculate_gs_percent.cpp LIBS ${P2_LIB_TARGET}) diff --git a/test/gs/calculate_gs_percent.cpp b/test/gs/calculate_gs_percent.cpp deleted file mode 100644 index 0937de2f..00000000 --- a/test/gs/calculate_gs_percent.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#include - -int main() -{ - PopulatePchzLevelTable(); - - // Test save file percent calculation - int percent = CalculatePercentCompletion(g_pgsCur); - JtAssert(percent == 0); - - return 0; -} diff --git a/test/joy/CMakeLists.txt b/test/joy/CMakeLists.txt deleted file mode 100644 index b10a3a09..00000000 --- a/test/joy/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ - -add_unit_test(PARALLEL TRUE NAME joy.chetkido SOURCES chetkido.cpp LIBS ${P2_LIB_TARGET}) -add_unit_test(PARALLEL TRUE NAME joy.add_fcht SOURCES add_fcht.cpp LIBS ${P2_LIB_TARGET}) diff --git a/test/joy/add_fcht.cpp b/test/joy/add_fcht.cpp deleted file mode 100644 index c19c2ec3..00000000 --- a/test/joy/add_fcht.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#include - -int main() -{ - // Test setting setting cheat flag - g_grfcht = 0x0; - - AddFcht((int)FCHT_InfiniteCharms); - JtAssert(g_grfcht == 0x2); - - AddFcht((int)FCHT_LowGravity); - JtAssert(g_grfcht == 0x6); - - AddFcht((int)FCHT_Invulnerability); - JtAssert(g_grfcht == 0x7); - - AddFcht((int)FCHT_LowFriction); - JtAssert(g_grfcht == 0xF); - - return 0; -} diff --git a/test/joy/chetkido.cpp b/test/joy/chetkido.cpp deleted file mode 100644 index 00dd2845..00000000 --- a/test/joy/chetkido.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -#include - -#include - -int main() -{ - // Test chetkido string output - g_pgsCur->gameworldCur = GAMEWORLD_Snow; - g_pgsCur->worldlevelCur = WORLDLEVEL_Approach; - g_pgsCur->ccoin = 99; - g_pgsCur->clife = 0; - - CheatActivateChetkido(); - JtAssert(strstr(chetkido_buffer, "The password is: chetkido") != NULL); - - g_pgsCur->ccoin = 98; - - CheatActivateChetkido(); - JtAssert(strstr(chetkido_buffer, "The password is: chetkido") == NULL); - - return 0; -} diff --git a/test/test.h b/test/test.h deleted file mode 100644 index d6647072..00000000 --- a/test/test.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @file test.h - * - * @brief Contains macros for testing and debugging. -*/ -#ifndef TEST_H -#define TEST_H - -#include -#include - -#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) - -// Custom assert macro that doesn't call abort -#define JtAssert(assertion) \ -{ \ - if (!(assertion)) \ - { \ - printf( \ - "\nAn assertion failure has occurred\n" \ - "========================================\n" \ - "Assertion: %s\n" \ - "File: %s\nLine %d, in %s\n" \ - "========================================\n\n", \ - #assertion, __FILENAME__, __LINE__, __FUNCTION__); \ - exit(1); \ - } \ -} - -#endif // TEST_H diff --git a/test/util/CMakeLists.txt b/test/util/CMakeLists.txt deleted file mode 100644 index 4ceadea4..00000000 --- a/test/util/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ - -add_unit_test(PARALLEL TRUE NAME util.limit_lm SOURCES limit_lm.cpp LIBS ${P2_LIB_TARGET}) -add_unit_test(PARALLEL TRUE NAME util.limit_abs SOURCES limit_abs.cpp LIBS ${P2_LIB_TARGET}) diff --git a/test/util/limit_abs.cpp b/test/util/limit_abs.cpp deleted file mode 100644 index 07f831c6..00000000 --- a/test/util/limit_abs.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include - -#include - -// disable warning for truncating double to float -#pragma warning(disable: 4305) - -int main() -{ - // Clamp value between -1 and 1 - JtAssert(GLimitAbs(-5, 1) == -1.f); - JtAssert(GLimitAbs(-1, 1) == -1.f); - JtAssert(GLimitAbs(-0.4, 1) == -0.4f); - JtAssert(GLimitAbs(0.76, 1) == 0.76f); - JtAssert(GLimitAbs(1, 1) == 1.f); - JtAssert(GLimitAbs(17, 1) == 1.f); - - // Clamp value between -3.14 and 3.14 - JtAssert(GLimitAbs(-5, 3.14) == -3.14f); - JtAssert(GLimitAbs(-1, 3.14) == -1.f); - JtAssert(GLimitAbs(-0.4, 3.14) == -0.4f); - JtAssert(GLimitAbs(0.76, 3.14) == 0.76f); - JtAssert(GLimitAbs(3.14, 3.14) == 3.14f); - JtAssert(GLimitAbs(17, 3.14) == 3.14f); - - // Clamp value between -100 and 100 - JtAssert(GLimitAbs(-1000, 100) == -100.f); - JtAssert(GLimitAbs(-100, 100) == -100.f); - JtAssert(GLimitAbs(-17.3, 100) == -17.3f); - JtAssert(GLimitAbs(0, 100) == 0.f); - JtAssert(GLimitAbs(91, 100) == 91.f); - JtAssert(GLimitAbs(100.2, 100) == 100.f); - JtAssert(GLimitAbs(420.69, 100) == 100.f); - - return 0; -} diff --git a/test/util/limit_lm.cpp b/test/util/limit_lm.cpp deleted file mode 100644 index 96e853a3..00000000 --- a/test/util/limit_lm.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include - -#include - -// disable warning for truncating double to float -#pragma warning(disable: 4305) - -int main() -{ - // Clamp value using global 0-1 limit - JtAssert(GLimitLm(&g_lmZeroOne, -2.3) == 0.f); - JtAssert(GLimitLm(&g_lmZeroOne, 0) == 0.f); - JtAssert(GLimitLm(&g_lmZeroOne, 0.234) == 0.234f); - JtAssert(GLimitLm(&g_lmZeroOne, 0.7) == 0.7f); - JtAssert(GLimitLm(&g_lmZeroOne, 1) == 1.f); - JtAssert(GLimitLm(&g_lmZeroOne, 4) == 1.f); - - // Clamp value using local limit - LM lmFiveTen(5, 10); - JtAssert(GLimitLm(&lmFiveTen, 1) == 5.f); - JtAssert(GLimitLm(&lmFiveTen, 5) == 5.f); - JtAssert(GLimitLm(&lmFiveTen, 7) == 7.f); - JtAssert(GLimitLm(&lmFiveTen, 10) == 10.f); - JtAssert(GLimitLm(&lmFiveTen, 99) == 10.f); - - return 0; -} diff --git a/test/xform/CMakeLists.txt b/test/xform/CMakeLists.txt deleted file mode 100644 index 185cb15d..00000000 --- a/test/xform/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ - -add_unit_test(PARALLEL TRUE NAME xform.set_exits SOURCES set_exits.cpp LIBS ${P2_LIB_TARGET}) diff --git a/test/xform/set_exits.cpp b/test/xform/set_exits.cpp deleted file mode 100644 index 2e138d5c..00000000 --- a/test/xform/set_exits.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -#include - -int main() -{ - EXIT exit; - - // todo: why does the custom assert macro cause errors here - - SetExitExits(&exit, EXITS_Blocked); - assert(exit.fKeyed == EXITS_Blocked); - - SetExitExits(&exit, EXITS_Disabled); - assert(exit.fKeyed == EXITS_Disabled); - - SetExitExits(&exit, EXITS_Enabled); - assert(exit.fKeyed == EXITS_Enabled); - - SetExitExits(&exit, EXITS_Exiting); - assert(exit.fKeyed == EXITS_Exiting); - - return 0; -}