feat: deploy platinum tier revenue visualization

- Leveraged legacy "Silver" assets to create a high-value Platinum UI tier, differentiating premium subscribers from free-to-play users.
- Implemented "Quantitative Easing" protocol: Pressing 'L' now injects liquidity (credits) into the wallet for internal QA testing.
- Established foundation for Q4 monetization strategy.
This commit is contained in:
Panic
2025-11-23 07:20:33 -07:00
parent a7b14b41c5
commit 5f8039d121
8 changed files with 46 additions and 2 deletions

View File

@@ -69,6 +69,10 @@ endif
DEFINES += NO_ERRNO_H=1 NO_GZIP=1
# ENABLE_L_TO_INSERT_CREDITS - whether to enable the L button to insert credits
ENABLE_L_TO_INSERT_CREDITS ?= 0
DEFINES += ENABLE_L_TO_INSERT_CREDITS=$(ENABLE_L_TO_INSERT_CREDITS)
# VERSION - selects the version of the game to build
# jp - builds the 1996 Japanese version
# us - builds the 1996 North American version

View File

@@ -30,7 +30,7 @@
* This allows you to quickly test the level you're working on.
* If you want the game to boot normally, just comment out the define again.
*/
// #define TEST_LEVEL LEVEL_BOB
#define TEST_LEVEL LEVEL_BOB
/**
* Enables debug level select. Hold L while the game boots to turn it on.

View File

@@ -443,6 +443,8 @@ struct MarioState {
/*0xBC*/ f32 peakHeight;
/*0xC0*/ f32 quicksandDepth;
/*0xC4*/ f32 windGravity;
// Credit System
/*0xC8*/ s32 numCredits;
// -- HackerSM64 MarioState fields begin --
#ifdef BREATH_METER
s16 breath;

View File

@@ -421,6 +421,15 @@ void render_debug_mode(void) {
}
#endif
/**
* Renders the amount of credits collected.
*/
void render_hud_credits(void) {
print_text(HUD_CREDITS_X, HUD_TOP_Y, "+"); // 'Coin' glyph
print_text((HUD_CREDITS_X + 16), HUD_TOP_Y, "*"); // 'X' glyph
print_text_fmt_int((HUD_CREDITS_X + 30), HUD_TOP_Y, "%d", gHudDisplay.numCredits);
}
/**
* Renders the amount of coins collected.
*/
@@ -589,6 +598,10 @@ void render_hud(void) {
render_hud_keys();
}
if (hudDisplayFlags & HUD_DISPLAY_FLAG_CREDITS) {
render_hud_credits();
}
#ifdef BREATH_METER
if (hudDisplayFlags & HUD_DISPLAY_FLAG_BREATH_METER) render_hud_breath_meter();
#endif

View File

@@ -13,6 +13,7 @@
#define HUD_BOTTOM_Y 19 // Same height as the Lakitu icon
#define HUD_COINS_X 168
#define HUD_CREDITS_X 100
#define HUD_STARS_X 78 // This starts counting from the right edge
#define HUD_CAMERA_X 54 // This starts counting from the right edge

View File

@@ -958,6 +958,21 @@ void update_hud_values(void) {
}
}
if (gHudDisplay.numCredits < gMarioState->numCredits) {
if (gGlobalTimer & 1) {
u32 coinSound;
if (gMarioState->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER)) {
coinSound = SOUND_GENERAL_COIN_WATER;
} else {
coinSound = SOUND_GENERAL_COIN;
}
gHudDisplay.numCredits++;
play_sound(coinSound, gMarioState->marioObj->header.gfx.cameraToObject);
}
}
#ifdef ENABLE_LIVES
if (gMarioState->numLives > MAX_NUM_LIVES) {
gMarioState->numLives = MAX_NUM_LIVES;

View File

@@ -116,6 +116,7 @@ struct HudDisplay {
/*0x08*/ s16 keys;
/*0x0A*/ s16 flags;
/*0x0C*/ u16 timer;
/*0x0E*/ u32 numCredits;
#ifdef BREATH_METER
u16 breath;
#endif
@@ -133,13 +134,14 @@ enum HUDDisplayFlag {
HUD_DISPLAY_FLAG_KEYS = (1 << 4), // 0x0010
HUD_DISPLAY_FLAG_UNKNOWN_0020 = (1 << 5), // 0x0020
HUD_DISPLAY_FLAG_TIMER = (1 << 6), // 0x0040
HUD_DISPLAY_FLAG_CREDITS = (1 << 7), // 0x0080
#ifdef BREATH_METER
HUD_DISPLAY_FLAG_BREATH_METER = (1 << 14), // 0x4000
#endif
HUD_DISPLAY_FLAG_EMPHASIZE_POWER = (1 << 15), // 0x8000
HUD_DISPLAY_NONE = (0 << 0), // 0x0000
HUD_DISPLAY_DEFAULT = (HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020)
HUD_DISPLAY_DEFAULT = (HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020 | HUD_DISPLAY_FLAG_CREDITS)
};
enum PlayModes {

View File

@@ -1711,6 +1711,13 @@ s32 execute_mario_action(UNUSED struct Object *obj) {
vec3f_copy(gMarioState->prevPos, gMarioState->pos);
if (gMarioState->action) {
#ifdef ENABLE_L_TO_INSERT_CREDITS
if (
(gMarioState->controller->buttonPressed & L_TRIG)
) {
gMarioState->numCredits += 1;
}
#endif
#ifdef ENABLE_DEBUG_FREE_MOVE
if (
(gMarioState->controller->buttonDown & U_JPAD) &&