diff --git a/src/game/mario.c b/src/game/mario.c index 1edaa835..afeab9ae 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -32,6 +32,7 @@ #include "level_table.h" #include "thread6.h" #include "pc/configfile.h" +#include "pc/cheats.h" #ifdef BETTERCAMERA #include "bettercamera.h" #endif @@ -1397,12 +1398,14 @@ void update_mario_inputs(struct MarioState *m) { update_mario_geometry_inputs(m); debug_print_speed_action_normal(m); + /* Moonjump cheat */ - while (cheatMoonjump == true && cheatEnablecheats == true && m->controller->buttonDown & L_TRIG ){ + while (Cheats.MoonJump == true && Cheats.EnableCheats == true && m->controller->buttonDown & L_TRIG ){ m->vel[1] = 25; - break; + break; // TODO: Unneeded break? } /*End of moonjump cheat */ + if (gCameraMovementFlags & CAM_MOVE_C_UP_MODE) { if (m->action & ACT_FLAG_ALLOW_FIRST_PERSON) { m->input |= INPUT_FIRST_PERSON; @@ -1726,17 +1729,17 @@ s32 execute_mario_action(UNUSED struct Object *o) { /** * Cheat stuff */ - while (cheatGodmode == true && cheatEnablecheats == true){ - gMarioState->health = 0x880; - break; - } - while (cheatInfinitelives == true && cheatEnablecheats == true && gMarioState->numLives < 99){ - gMarioState->numLives += 1; - break; - } - while (cheatSuperspeed == true && cheatEnablecheats == true && gMarioState->forwardVel > 0 ){ - gMarioState->forwardVel += 100; - break; + + if (Cheats.EnableCheats) + { + if (Cheats.GodMode) + gMarioState->health = 0x880; + + if (Cheats.InfiniteLives && gMarioState->numLives < 99) + gMarioState->numLives += 1; + + if (Cheats.SuperSpeed && gMarioState->forwardVel > 0) + gMarioState->forwardVel += 100; } /** * End of cheat stuff diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 4d0c8efa..5b4dbb80 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -13,6 +13,7 @@ #include "behavior_data.h" #include "thread6.h" #include "pc/configfile.h" +#include "pc/cheats.h" struct LandingAction { s16 numFrames; @@ -464,13 +465,12 @@ void update_walking_speed(struct MarioState *m) { /* Handles the "Super responsive controls" cheat. The content of the "else" is Mario's original code for turning around.*/ - if (cheatResponsive == true && cheatEnablecheats == true ) { + if (Cheats.Responsive == true && Cheats.EnableCheats == true ) { m->faceAngle[1] = m->intendedYaw; } else { - m->faceAngle[1] = - m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800); - } + m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800); + } apply_slope_accel(m); } diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 25996e4d..89e6deb1 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -18,6 +18,7 @@ #include "game/options_menu.h" #include "pc/pc_main.h" #include "pc/cliopts.h" +#include "pc/cheats.h" #include "pc/configfile.h" #include "pc/controller/controller_api.h" @@ -219,12 +220,12 @@ static struct Option optsAudio[] = { }; static struct Option optsCheats[] = { - DEF_OPT_TOGGLE( optsCheatsStr[0], &cheatEnablecheats ), - DEF_OPT_TOGGLE( optsCheatsStr[1], &cheatMoonjump ), - DEF_OPT_TOGGLE( optsCheatsStr[2], &cheatGodmode ), - DEF_OPT_TOGGLE( optsCheatsStr[3], &cheatInfinitelives ), - DEF_OPT_TOGGLE( optsCheatsStr[4], &cheatSuperspeed), - DEF_OPT_TOGGLE( optsCheatsStr[5], &cheatResponsive), + DEF_OPT_TOGGLE( optsCheatsStr[0], &Cheats.EnableCheats ), + DEF_OPT_TOGGLE( optsCheatsStr[1], &Cheats.MoonJump ), + DEF_OPT_TOGGLE( optsCheatsStr[2], &Cheats.GodMode ), + DEF_OPT_TOGGLE( optsCheatsStr[3], &Cheats.InfiniteLives ), + DEF_OPT_TOGGLE( optsCheatsStr[4], &Cheats.SuperSpeed), + DEF_OPT_TOGGLE( optsCheatsStr[5], &Cheats.Responsive), }; diff --git a/src/pc/cheats.c b/src/pc/cheats.c new file mode 100644 index 00000000..5663d777 --- /dev/null +++ b/src/pc/cheats.c @@ -0,0 +1,2 @@ +#include "cheats.h" +struct CheatList Cheats; diff --git a/src/pc/cheats.h b/src/pc/cheats.h new file mode 100644 index 00000000..01a7264b --- /dev/null +++ b/src/pc/cheats.h @@ -0,0 +1,13 @@ +#include + +struct CheatList +{ + bool EnableCheats; + bool MoonJump; + bool GodMode; + bool InfiniteLives; + bool SuperSpeed; + bool Responsive; +}; + +extern struct CheatList Cheats; diff --git a/src/pc/configfile.c b/src/pc/configfile.c index f6623a1d..3c2735c2 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -37,15 +37,6 @@ bool configFullscreen = false; unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME -// Cheat stuff -bool cheatEnablecheats = false; -bool cheatMoonjump = false; -bool cheatGodmode = false; -bool cheatInfinitelives = false; -bool cheatSuperspeed = false; -bool cheatResponsive = false; - - // Keyboard mappings (VK_ values, by default keyboard/gamepad/mouse) unsigned int configKeyA[MAX_BINDS] = { 0x0026, 0x1000, 0x1103 }; unsigned int configKeyB[MAX_BINDS] = { 0x0033, 0x1002, 0x1101 }; diff --git a/src/pc/configfile.h b/src/pc/configfile.h index bdecf0e9..49b48b93 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -24,12 +24,6 @@ extern unsigned int configKeyStickUp[]; extern unsigned int configKeyStickDown[]; extern unsigned int configKeyStickLeft[]; extern unsigned int configKeyStickRight[]; -extern bool cheatMoonjump; -extern bool cheatGodmode; -extern bool cheatEnablecheats; -extern bool cheatInfinitelives; -extern bool cheatSuperspeed; -extern bool cheatResponsive; #ifdef BETTERCAMERA extern unsigned int configCameraXSens; extern unsigned int configCameraYSens; diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 3b11a46c..4f6968f7 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -285,6 +285,12 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co return false; } +static void import_texture_rgba32(int tile) { + uint32_t width = rdp.texture_tile.line_size_bytes / 2; + uint32_t height = (rdp.loaded_texture[tile].size_bytes / 2) / rdp.texture_tile.line_size_bytes; + gfx_rapi->upload_texture(rdp.loaded_texture[tile].addr, width, height); +} + static void import_texture_rgba16(int tile) { uint8_t rgba32_buf[8192]; @@ -371,6 +377,41 @@ static void import_texture_ia16(int tile) { gfx_rapi->upload_texture(rgba32_buf, width, height); } +static void import_texture_i4(int tile) { + uint8_t rgba32_buf[32768]; + + for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes * 2; i++) { + uint8_t byte = rdp.loaded_texture[tile].addr[i / 2]; + uint8_t intensity = (byte >> (4 - (i % 2) * 4)) & 0xf; + rgba32_buf[4*i + 0] = SCALE_4_8(intensity); + rgba32_buf[4*i + 1] = SCALE_4_8(intensity); + rgba32_buf[4*i + 2] = SCALE_4_8(intensity); + rgba32_buf[4*i + 3] = 255; + } + + uint32_t width = rdp.texture_tile.line_size_bytes * 2; + uint32_t height = rdp.loaded_texture[tile].size_bytes / rdp.texture_tile.line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); +} + +static void import_texture_i8(int tile) { + uint8_t rgba32_buf[16384]; + + for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes; i++) { + uint8_t intensity = rdp.loaded_texture[tile].addr[i]; + rgba32_buf[4*i + 0] = intensity; + rgba32_buf[4*i + 1] = intensity; + rgba32_buf[4*i + 2] = intensity; + rgba32_buf[4*i + 3] = 255; + } + + uint32_t width = rdp.texture_tile.line_size_bytes; + uint32_t height = rdp.loaded_texture[tile].size_bytes / rdp.texture_tile.line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); +} + static void import_texture_ci4(int tile) { uint8_t rgba32_buf[32768]; @@ -426,7 +467,10 @@ static void import_texture(int tile) { int t0 = get_time(); if (fmt == G_IM_FMT_RGBA) { - if (siz == G_IM_SIZ_16b) { + if (siz == G_IM_SIZ_32b) { + import_texture_rgba32(tile); + } + else if (siz == G_IM_SIZ_16b) { import_texture_rgba16(tile); } else { abort(); @@ -449,6 +493,14 @@ static void import_texture(int tile) { } else { abort(); } + } else if (fmt == G_IM_FMT_I) { + if (siz == G_IM_SIZ_4b) { + import_texture_i4(tile); + } else if (siz == G_IM_SIZ_8b) { + import_texture_i8(tile); + } else { + abort(); + } } else { abort(); } @@ -976,7 +1028,6 @@ static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t wi } static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, uint32_t maskt, uint32_t shiftt, uint32_t cms, uint32_t masks, uint32_t shifts) { - SUPPORT_CHECK(siz != G_IM_SIZ_32b); if (tile == G_TX_RENDERTILE) { SUPPORT_CHECK(palette == 0); // palette should set upper 4 bits of color index in 4b mode @@ -1035,12 +1086,45 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t } uint32_t size_bytes = (lrs + 1) << word_size_shift; rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes; - assert(size_bytes <= 4096 && "bug: too big texture"); rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr; rdp.textures_changed[rdp.texture_to_load.tile_number] = true; } +static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) { + if (tile == 1) return; + SUPPORT_CHECK(tile == G_TX_LOADTILE); + SUPPORT_CHECK(uls == 0); + SUPPORT_CHECK(ult == 0); + + uint32_t word_size_shift; + switch (rdp.texture_to_load.siz) { + case G_IM_SIZ_4b: + word_size_shift = 0; // Or -1? It's unused in SM64 anyway. + break; + case G_IM_SIZ_8b: + word_size_shift = 0; + break; + case G_IM_SIZ_16b: + word_size_shift = 1; + break; + case G_IM_SIZ_32b: + word_size_shift = 2; + break; + } + + uint32_t size_bytes = (((lrs >> G_TEXTURE_IMAGE_FRAC) + 1) * ((lrt >> G_TEXTURE_IMAGE_FRAC) + 1)) << word_size_shift; + rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes; + + rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr; + rdp.texture_tile.uls = uls; + rdp.texture_tile.ult = ult; + rdp.texture_tile.lrs = lrs; + rdp.texture_tile.lrt = lrt; + + rdp.textures_changed[rdp.texture_to_load.tile_number] = true; +} + static uint8_t color_comb_component(uint32_t v) { switch (v) { case G_CCMUX_TEXEL0: @@ -1384,6 +1468,9 @@ static void gfx_run_dl(Gfx* cmd) { case G_LOADBLOCK: gfx_dp_load_block(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12)); break; + case G_LOADTILE: + gfx_dp_load_tile(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12)); + break; case G_SETTILE: gfx_dp_set_tile(C0(21, 3), C0(19, 2), C0(9, 9), C0(0, 9), C1(24, 3), C1(20, 4), C1(18, 2), C1(14, 4), C1(10, 4), C1(8, 2), C1(4, 4), C1(0, 4)); break;