Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
27ee349
Implemented achievements I/O, overlay and error handling
hyperbx Nov 5, 2025
98f0d40
Implemented achievements menu
hyperbx Nov 8, 2025
df465af
Update resources submodule
hyperbx Nov 8, 2025
df98c2f
Added Achievement Notifications option
hyperbx Nov 8, 2025
d2570d6
Use total instead of percentage for achievement progress
hyperbx Nov 8, 2025
03ebc6f
Use original game's time format
hyperbx Nov 8, 2025
fcf549e
Fix gold medals not reappearing when switching between menus
hyperbx Nov 11, 2025
476d5eb
English localisation
hyperbx Nov 11, 2025
f956e32
Update locale
hyperbx Nov 11, 2025
293d21b
Added sliding transition to achievements menu
hyperbx Nov 11, 2025
eec51a8
Update locale
hyperbx Nov 13, 2025
5028082
Italian localisation
hyperbx Nov 13, 2025
1744c8f
Spanish localisation by DaGuAr
hyperbx Nov 13, 2025
bdf30a3
Adjusted achievement text marquee start/end position
hyperbx Nov 13, 2025
bab6a9c
Fix text card string replacement causing crashes on main menu exit
hyperbx Nov 13, 2025
550de85
Fixed UTF-8 std::string -> std::wstring conversion
hyperbx Nov 14, 2025
a98013b
Update Spanish localisation
hyperbx Nov 14, 2025
e31b7df
Improve transitions and visual feedback
hyperbx Nov 14, 2025
4e8ae72
Update Spanish localisation
hyperbx Nov 14, 2025
56da57e
options_menu: disable description fade animation if current option is…
hyperbx Nov 14, 2025
0171b3c
German localisation by Ray Vassos
hyperbx Nov 15, 2025
78c6397
French & Japanese Locale
IsaacMarovitz Dec 26, 2025
db1e2b3
Fix typo
IsaacMarovitz Dec 26, 2025
7ecb3e9
Finish French
IsaacMarovitz Dec 28, 2025
5f979d8
Remove JP full stops
IsaacMarovitz Dec 28, 2025
f2898aa
Japanese
IsaacMarovitz Dec 28, 2025
1f26bd2
Font atlas
IsaacMarovitz Dec 28, 2025
ce56d3a
Minor adjustments
IsaacMarovitz Dec 28, 2025
5d42ac0
Fix missing “legendary”
IsaacMarovitz Dec 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions MarathonRecomp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ set(MARATHON_RECOMP_KERNEL_CXX_SOURCES
)

set(MARATHON_RECOMP_LOCALE_CXX_SOURCES
"locale/achievement_locale.cpp"
"locale/config_locale.cpp"
"locale/locale.cpp"
)
Expand Down Expand Up @@ -538,7 +539,6 @@ set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/bc_diff/button_bc_diff.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/bc_diff/button_bc_diff.bin" ARRAY_NAME "g_button_bc_diff" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.bin" ARRAY_NAME "g_im_font_atlas" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.dds" ARRAY_NAME "g_im_font_atlas_texture" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/achievements_menu/trophy.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/achievements_menu/trophy.dds" ARRAY_NAME "g_trophy" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/button_window.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/button_window.dds" ARRAY_NAME "g_button_window" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/controller.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/controller.dds" ARRAY_NAME "g_controller" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/sonicnext-dev.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/sonicnext-dev.dds" ARRAY_NAME "g_sonicnextdev" COMPRESSION_TYPE "zstd")
Expand All @@ -549,7 +549,7 @@ BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/com
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/main_menu9.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/main_menu9.dds" ARRAY_NAME "g_main_menu9" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/arrow.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/arrow.dds" ARRAY_NAME "g_arrow" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/window.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/window.dds" ARRAY_NAME "g_window" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_arrow.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_arrow.dds" ARRAY_NAME "g_select_arrow" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_arrow.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_arrow.dds" ARRAY_NAME "g_select_arrow" COMPRESSION_TYPE "zstd")

## Installer ##
BIN2C(TARGET_OBJ MarathonRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd")
Expand Down
21 changes: 12 additions & 9 deletions MarathonRecomp/api/Marathon.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "Sonicteam/Globals.h"
#include "Sonicteam/HUDButtonWindow.h"
#include "Sonicteam/HUDCALLBACK.h"
#include "Sonicteam/HUDGoldMedal.h"
#include "Sonicteam/HUDLimitTime.h"
#include "Sonicteam/HUDLoading.h"
#include "Sonicteam/HUDMainDisplay.h"
Expand All @@ -56,17 +57,19 @@
#include "Sonicteam/HudTextParts.h"
#include "Sonicteam/ImageFilter.h"
#include "Sonicteam/MainDisplayTask.h"
#include "Sonicteam/MainMenuExpositionTask.h"
#include "Sonicteam/MainMenuTask.h"
#include "Sonicteam/MainMode.h"
#include "Sonicteam/Message/MsgCameramanChangeMode.h"
#include "Sonicteam/Message/MsgHUDButtonWindowChangeButtons.h"
#include "Sonicteam/Message/MsgHUDMainMenuChangeState.h"
#include "Sonicteam/Message/MsgHUDMainMenuSetCursor.h"
#include "Sonicteam/Message/MsgHUDMainMenuTransition.h"
#include "Sonicteam/Message/MsgMissionGetGlobalFlag.h"
#include "Sonicteam/Message/MsgObjJump123GetNextPoint.h"
#include "Sonicteam/Message/MsgPauseAdapterText.h"
#include "Sonicteam/Message/MsgSuckPlayer.h"
#include "Sonicteam/Message/Camera/Cameraman/MsgChangeMode.h"
#include "Sonicteam/Message/HUDButtonWindow/MsgChangeButtons.h"
#include "Sonicteam/Message/HUDGoldMedal/MsgChangeState.h"
#include "Sonicteam/Message/HUDMainMenu/MsgChangeState.h"
#include "Sonicteam/Message/HUDMainMenu/MsgSetCursor.h"
#include "Sonicteam/Message/HUDMainMenu/MsgTransition.h"
#include "Sonicteam/Message/Mission/MsgGetGlobalFlag.h"
#include "Sonicteam/Message/ObjJump123/MsgGetNextPoint.h"
#include "Sonicteam/Message/PauseAdapter/MsgGetText.h"
#include "Sonicteam/Message/Player/MsgSuckPlayer.h"
#include "Sonicteam/MessageWindowTask.h"
#include "Sonicteam/Mission/Core.h"
#include "Sonicteam/MovieObject.h"
Expand Down
41 changes: 41 additions & 0 deletions MarathonRecomp/api/Sonicteam/HUDGoldMedal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <Marathon.inl>
#include <boost/smart_ptr/shared_ptr.h>
#include <Sonicteam/SoX/Engine/Doc.h>
#include <Sonicteam/SoX/Engine/Task.h>
#include <Sonicteam/SoX/RefCountObject.h>
#include <Sonicteam/CsdObject.h>
#include <Sonicteam/HudTextParts.h>
#include <Sonicteam/TextCard.h>
#include <Sonicteam/TextEntity.h>

namespace Sonicteam
{
class HUDGoldMedal : public SoX::RefCountObject, public SoX::Engine::Task
{
public:
xpointer<CsdObject> m_pCsdObject;
xpointer<HudTextParts> m_pMedalCountText;
xpointer<SoX::Engine::Doc> m_pDoc;
MARATHON_INSERT_PADDING(0x3C);
be<uint32_t> m_EpisodeIndex;
be<uint32_t> m_ScrollIndex;
be<uint32_t> m_MedalCount;
boost::shared_ptr<TextCard> m_spMedalCountTextCard;
MARATHON_INSERT_PADDING(0x10);
boost::shared_ptr<TextCard> m_aspTextCards[5];
boost::shared_ptr<TextEntity> m_aspTextEntities[5];
};

MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_pCsdObject, 0x54);
MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_pMedalCountText, 0x58);
MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_pDoc, 0x5C);
MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_EpisodeIndex, 0x9C);
MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_ScrollIndex, 0xA0);
MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_MedalCount, 0xA4);
MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_spMedalCountTextCard, 0xA8);
MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_aspTextCards, 0xC0);
MARATHON_ASSERT_OFFSETOF(HUDGoldMedal, m_aspTextEntities, 0xE8);
MARATHON_ASSERT_SIZEOF(HUDGoldMedal, 0x110);
}
5 changes: 4 additions & 1 deletion MarathonRecomp/api/Sonicteam/HUDMainMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ namespace Sonicteam
enum HUDMainMenuState : uint32_t
{
HUDMainMenuState_OptionsOutro = 5,
HUDMainMenuState_SinglePlayerTextOutro = 8,
HUDMainMenuState_SinglePlayerCursorIntro = 86,
HUDMainMenuState_OptionsIntro = 90,
HUDMainMenuState_MainCursorIntro = 98,
HUDMainMenuState_MainCursorOutro = 99
HUDMainMenuState_MainCursorOutro = 99,
HUDMainMenuState_GoldMedalResultsCursorOutro = 101
};

MARATHON_INSERT_PADDING(0x20);
Expand Down
15 changes: 15 additions & 0 deletions MarathonRecomp/api/Sonicteam/MainMenuExpositionTask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <Marathon.inl>
#include <Sonicteam/SoX/RefCountObject.h>

namespace Sonicteam
{
class MainMenuExpositionTask : public SoX::RefCountObject, public SoX::Engine::Task
{
public:
be<uint32_t> m_TextMotionState;
};

MARATHON_ASSERT_OFFSETOF(MainMenuExpositionTask, m_TextMotionState, 0x54);
}
35 changes: 28 additions & 7 deletions MarathonRecomp/api/Sonicteam/MainMenuTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

#include <Marathon.inl>
#include <Sonicteam/SoX/Math/Vector.h>
#include <Sonicteam/SoX/RefSharedPointer.h>
#include <Sonicteam/Player/Object.h>
#include <Sonicteam/ButtonWindowTask.h>
#include <Sonicteam/MainMenuExpositionTask.h>

namespace Sonicteam
{
Expand All @@ -14,7 +16,7 @@ namespace Sonicteam
{
MainMenuState_MainMenuBack = 1,
MainMenuState_MainMenu = 2,
MainMenuState_MainMenuExitPrompt = 4,
MainMenuState_ExitPrompt = 4,
MainMenuState_SinglePlayer = 6,
MainMenuState_EpisodeSelect = 9,
MainMenuState_TrialSelect = 0x0D,
Expand All @@ -26,22 +28,34 @@ namespace Sonicteam
MainMenuState_Tag = 0x1E,
MainMenuState_Tag1PSelect = 0x1F,
MainMenuState_Battle = 0x22,
MainMenuState_GoldMedalResults = 0x26,
MainMenuState_GoldMedalResultsOpen = 0x26,
MainMenuState_GoldMedalResults = 0x27,
MainMenuState_AudioRoom = 0x2F,
MainMenuState_TheaterRoom = 0x31,
MainMenuState_Options = 0x33,
MainMenuState_MainMenuExitToStage = 0x3B,
MainMenuState_MainMenuExitToTitle = 0x3C
MainMenuState_ExitToStage = 0x3B,
MainMenuState_ExitToTitle = 0x3C
};

be<uint32_t> m_State;
MARATHON_INSERT_PADDING(0x24);
xpointer<HUDMainMenu> m_pHUDMainMenu;
MARATHON_INSERT_PADDING(0x20);
MARATHON_INSERT_PADDING(8);
xpointer<HUDGoldMedal> m_pHUDGoldMedal;
MARATHON_INSERT_PADDING(0x14);
xpointer<ButtonWindowTask> m_pButtonWindowTask;
MARATHON_INSERT_PADDING(4);
SoX::RefSharedPointer<MainMenuExpositionTask> m_spMainMenuExpositionTask;
be<uint32_t> m_MainMenuSelectedIndex;
MARATHON_INSERT_PADDING(0x1D8);
be<uint32_t> m_SinglePlayerSelectedIndex;
MARATHON_INSERT_PADDING(0x14);
be<uint32_t> m_FieldBC;
MARATHON_INSERT_PADDING(0x60);
be<uint32_t> m_GoldMedalEpisodeIndex;
MARATHON_INSERT_PADDING(4);
be<uint32_t> m_GoldMedalScrollIndex;
MARATHON_INSERT_PADDING(0x144);
be<uint32_t> m_IsChangingState;
MARATHON_INSERT_PADDING(8);
be<uint32_t> m_PressedButtons;
MARATHON_INSERT_PADDING(0x18);
xpointer<Actor> m_Field298;
Expand All @@ -51,8 +65,15 @@ namespace Sonicteam

MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_State, 0x4C);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_pHUDMainMenu, 0x74);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_pHUDGoldMedal, 0x80);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_pButtonWindowTask, 0x98);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_spMainMenuExpositionTask, 0x9C);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_MainMenuSelectedIndex, 0xA0);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_SinglePlayerSelectedIndex, 0xA4);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_FieldBC, 0xBC);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_GoldMedalEpisodeIndex, 0x120);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_GoldMedalScrollIndex, 0x128);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_IsChangingState, 0x270);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_PressedButtons, 0x27C);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_Field298, 0x298);
MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_apSelectCharacters, 0x29C);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <Marathon.inl>
#include <Sonicteam/SoX/Math/Vector.h>
#include <Sonicteam/SoX/Message.h>

namespace Sonicteam::Message::Camera::Cameraman
{
struct MsgChangeMode : SoX::Message<0x14007>
{
be<uint32_t> PadID{};
be<uint32_t> TargetActorID{};
bool IsDemoCamera{};
};

MARATHON_ASSERT_OFFSETOF(MsgChangeMode, PadID, 0x04);
MARATHON_ASSERT_OFFSETOF(MsgChangeMode, TargetActorID, 0x08);
MARATHON_ASSERT_OFFSETOF(MsgChangeMode, IsDemoCamera, 0x0C);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <Marathon.inl>
#include <Sonicteam/SoX/Message.h>

namespace Sonicteam::Message::HUDButtonWindow
{
struct MsgChangeButtons : SoX::Message<0x1B05B>
{
be<uint32_t> ButtonType{};

MsgChangeButtons(uint32_t buttonType = 0) : ButtonType(buttonType) {}
};

MARATHON_ASSERT_OFFSETOF(MsgChangeButtons, ButtonType, 0x04);
}
24 changes: 24 additions & 0 deletions MarathonRecomp/api/Sonicteam/Message/HUDGoldMedal/MsgChangeState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <Marathon.inl>
#include <Sonicteam/SoX/Message.h>

namespace Sonicteam::Message::HUDGoldMedal
{
struct MsgChangeState : SoX::Message<0x1B058>
{
be<uint32_t> State{};
be<uint32_t> Field08{};
uint8_t Field0C{};
be<uint32_t> EpisodeIndex{};

MsgChangeState() {}

MsgChangeState(uint32_t state, uint32_t episodeIndex = 0) : State(state), EpisodeIndex(episodeIndex) {}
};

MARATHON_ASSERT_OFFSETOF(MsgChangeState, State, 0x04);
MARATHON_ASSERT_OFFSETOF(MsgChangeState, Field08, 0x08);
MARATHON_ASSERT_OFFSETOF(MsgChangeState, Field0C, 0x0C);
MARATHON_ASSERT_OFFSETOF(MsgChangeState, EpisodeIndex, 0x10);
}
14 changes: 14 additions & 0 deletions MarathonRecomp/api/Sonicteam/Message/HUDMainMenu/MsgChangeState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <Marathon.inl>
#include <Sonicteam/SoX/Message.h>

namespace Sonicteam::Message::HUDMainMenu
{
struct MsgChangeState : SoX::Message<0x1B053>
{
be<uint32_t> State{};
};

MARATHON_ASSERT_OFFSETOF(MsgChangeState, State, 0x04);
}
27 changes: 27 additions & 0 deletions MarathonRecomp/api/Sonicteam/Message/HUDMainMenu/MsgSetCursor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <Marathon.inl>
#include <Sonicteam/Message/HUDMainMenu/MsgChangeState.h>

namespace Sonicteam::Message::HUDMainMenu
{
struct MsgSetCursor : MsgChangeState
{
be<uint32_t> CursorIndex{};

MsgSetCursor() {}

MsgSetCursor(uint32_t state)
{
State = state;
}

MsgSetCursor(uint32_t state, uint32_t cursorIndex)
{
State = state;
CursorIndex = cursorIndex;
}
};

MARATHON_ASSERT_OFFSETOF(MsgSetCursor, CursorIndex, 0x08);
}
27 changes: 27 additions & 0 deletions MarathonRecomp/api/Sonicteam/Message/HUDMainMenu/MsgTransition.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <Marathon.inl>
#include <Sonicteam/Message/HUDMainMenu/MsgChangeState.h>

namespace Sonicteam::Message::HUDMainMenu
{
struct MsgTransition : MsgChangeState
{
be<uint32_t> Flags{};

MsgTransition() {}

MsgTransition(uint32_t state)
{
State = state;
}

MsgTransition(uint32_t state, uint32_t flags)
{
State = state;
Flags = flags;
}
};

MARATHON_ASSERT_OFFSETOF(MsgTransition, Flags, 0x08);
}
17 changes: 17 additions & 0 deletions MarathonRecomp/api/Sonicteam/Message/Mission/MsgGetGlobalFlag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <Marathon.inl>

namespace Sonicteam::Message::Mission
{
struct MsgGetGlobalFlag : SoX::Message<0x1E004>
{
be<uint32_t> FlagID{};
be<uint32_t> FlagValue{};

MsgGetGlobalFlag(uint32_t flagId) : FlagID(flagId) {}
};

MARATHON_ASSERT_OFFSETOF(MsgGetGlobalFlag, FlagID, 0x04);
MARATHON_ASSERT_OFFSETOF(MsgGetGlobalFlag, FlagValue, 0x08);
}
19 changes: 0 additions & 19 deletions MarathonRecomp/api/Sonicteam/Message/MsgCameramanChangeMode.h

This file was deleted.

This file was deleted.

Loading
Loading