From 7b1cb9af9c8a7266e0ad64a3150e8a93ac5ad3ce Mon Sep 17 00:00:00 2001 From: briaguya Date: Sun, 29 May 2022 00:19:51 -0400 Subject: [PATCH 1/6] got the hookshots rendering --- .../libultraship/Lib/Fast3D/gfx_sdl2.cpp | 10 +++ soh/soh/Enhancements/randomizer.cpp | 71 ++++++++++++------- soh/soh/Enhancements/randomizer.h | 4 +- soh/soh/OTRGlobals.cpp | 8 +-- soh/soh/OTRGlobals.h | 1 + .../ovl_file_choose/z_file_choose.c | 67 ++++++++++++++++- .../ovl_file_choose/z_file_nameset_PAL.c | 2 +- 7 files changed, 130 insertions(+), 33 deletions(-) diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp index e80097c81..8d3c529cb 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp @@ -132,6 +132,8 @@ static int frameDivisor = 1; static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { SDL_Init(SDL_INIT_VIDEO); + SDL_EventState(SDL_DROPFILE, SDL_ENABLE); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); @@ -227,8 +229,11 @@ static void gfx_sdl_onkeyup(int scancode) { } } +extern "C" void LoadItemLocations(const char* spoilerFileName); + static void gfx_sdl_handle_events(void) { SDL_Event event; + char* dropped_filedir; while (SDL_PollEvent(&event)) { SohImGui::EventImpl event_impl; event_impl.sdl = { &event }; @@ -249,6 +254,11 @@ static void gfx_sdl_handle_events(void) { window_height = event.window.data2; } break; + case SDL_DROPFILE: + { + LoadItemLocations(event.drop.file); + break; + } case SDL_QUIT: exit(0); } diff --git a/soh/soh/Enhancements/randomizer.cpp b/soh/soh/Enhancements/randomizer.cpp index c9c44d203..6b0a934b0 100644 --- a/soh/soh/Enhancements/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer.cpp @@ -4,8 +4,8 @@ #include #include #include -#include -#include +#include +#include using json = nlohmann::json; @@ -643,41 +643,64 @@ s16 Randomizer::GetItemModelFromId(s16 itemId) { return itemIdToModel[itemId]; } -void Randomizer::LoadItemLocations() { +void Randomizer::LoadItemLocations(const char* spoilerFileName) { // bandaid until new save stuff happens - ParseItemLocations(""); + ParseItemLocations(spoilerFileName); for(auto itemLocation : gSaveContext.itemLocations) { this->itemLocations[itemLocation.check] = itemLocation.get; } } -void Randomizer::ParseItemLocations(std::string spoilerFileName) { +void Randomizer::ParseItemLocations(const char* spoilerFileName) { // todo pull this in from cvar or something - std::ifstream spoilerFileStream("spoiler.json"); + std::ifstream spoilerFileStream(spoilerFileName); if (!spoilerFileStream) return; - json spoilerFileJson; - spoilerFileStream >> spoilerFileJson; - json locationsJson = spoilerFileJson["locations"]; - int index = 0; - for (auto it = locationsJson.begin(); it != locationsJson.end(); ++it) { - if (it->is_structured()) { - json itemJson = *it; - for (auto itemit = itemJson.begin(); itemit != itemJson.end(); ++itemit) { - // todo handle prices - if (itemit.key() == "item") { - gSaveContext.itemLocations[index].check = SpoilerfileCheckNameToEnum[it.key()]; - gSaveContext.itemLocations[index].get = SpoilerfileGetNameToEnum[itemit.value()]; - } - } - } else { - gSaveContext.itemLocations[index].check = SpoilerfileCheckNameToEnum[it.key()]; - gSaveContext.itemLocations[index].get = SpoilerfileGetNameToEnum[it.value()]; + bool success = false; + + try { + json spoilerFileJson; + spoilerFileStream >> spoilerFileJson; + json locationsJson = spoilerFileJson["locations"]; + json hashJson = spoilerFileJson["file_hash"]; + + int index = 0; + for (auto it = hashJson.begin(); it != hashJson.end(); ++it) { + //gSaveContext.seedIcons[index] = gSeedTextures[it.value()]; + index++; } - index++; + index = 0; + for (auto it = locationsJson.begin(); it != locationsJson.end(); ++it) { + if (it->is_structured()) { + json itemJson = *it; + for (auto itemit = itemJson.begin(); itemit != itemJson.end(); ++itemit) { + // todo handle prices + if (itemit.key() == "item") { + + gSaveContext.itemLocations[index].check = SpoilerfileCheckNameToEnum[it.key()]; + gSaveContext.itemLocations[index].get = SpoilerfileGetNameToEnum[itemit.value()]; + } + } + } else { + gSaveContext.itemLocations[index].check = SpoilerfileCheckNameToEnum[it.key()]; + gSaveContext.itemLocations[index].get = SpoilerfileGetNameToEnum[it.value()]; + } + + index++; + } + + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + success = true; + } catch (const std::exception& e) { + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + return; + } + + if (success) { + CVar_SetS32("gRandomizer", 1); } } diff --git a/soh/soh/Enhancements/randomizer.h b/soh/soh/Enhancements/randomizer.h index 50da6b21e..3a8550a1a 100644 --- a/soh/soh/Enhancements/randomizer.h +++ b/soh/soh/Enhancements/randomizer.h @@ -21,8 +21,8 @@ class Randomizer { ~Randomizer(); s16 GetItemModelFromId(s16 itemId); - void LoadItemLocations(); - void ParseItemLocations(std::string spoilerfilename); + void LoadItemLocations(const char* spoilerFileName); + void ParseItemLocations(const char* spoilerFileName); s32 GetRandomizedItemId(GetItemID ogId, s16 actorId = -1, s16 sceneNum = -1, s16 actorParams = -1, s32 homePosX = 0, s32 homePosY = 0, s32 homePosZ = 0); }; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 791c1eb49..4799478bc 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1000,12 +1000,12 @@ extern "C" s16 GetItemModelFromId(s16 itemId) { return OTRGlobals::Instance->gRandomizer->GetItemModelFromId(itemId); } -extern "C" void LoadItemLocations() { - OTRGlobals::Instance->gRandomizer->LoadItemLocations(); +extern "C" void LoadItemLocations(const char* spoilerFileName) { + OTRGlobals::Instance->gRandomizer->LoadItemLocations(spoilerFileName); } -extern "C" void ParseItemLocations(const char* spoilerfilename) { - OTRGlobals::Instance->gRandomizer->ParseItemLocations(spoilerfilename); +extern "C" void ParseItemLocations(const char* spoilerFileName) { + OTRGlobals::Instance->gRandomizer->ParseItemLocations(spoilerFileName); } extern "C" s32 GetRandomizedItemId(GetItemID ogId, s16 sceneNum, s16 actorParams) { diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 77b4a92d2..c31e3e9af 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -74,6 +74,7 @@ int AudioPlayer_GetDesiredBuffered(void); void AudioPlayer_Play(const uint8_t* buf, uint32_t len); void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples); int Controller_ShouldRumble(size_t i); +void LoadItemLocations(const char* spoilerFileName); void ParseItemLocations(const char* spoilerfilename); s32 GetRandomizedItemId(GetItemID ogId, s16 sceneNum, s16 actorParams); s32 GetRandomizedItemIdFromActor(GetItemID ogId, s16 actorId); diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 2ef733324..13da4f664 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -4,6 +4,7 @@ #include "textures/title_static/title_static.h" #include "textures/parameter_static/parameter_static.h" +#include static s16 sUnused = 106; @@ -63,6 +64,7 @@ void FileChoose_InitModeUpdate(GameState* thisx) { this->configMode = CM_FADE_IN_START; this->nextTitleLabel = FS_TITLE_OPEN_FILE; osSyncPrintf("Sram Start─Load 》》》》》 "); + CVar_SetS32("gRandomizer", 0); Sram_VerifyAndLoadAllSaves(this, &this->sramCtx); osSyncPrintf("終了!!!\n"); } @@ -163,6 +165,65 @@ void FileChoose_FinishFadeIn(GameState* thisx) { } } +typedef struct { + char tex[512]; + uint16_t width; + uint16_t height; + uint8_t im_fmt; + uint8_t im_siz; +} Sprite; + +Sprite sprDPad = { gHookshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + +void SpriteLoad(FileChooseContext* this, Sprite* sprite) { + OPEN_DISPS(this->state.gfxCtx, "gfx.c", 12); + + if (sprite->im_siz == G_IM_SIZ_16b) { + gDPLoadTextureBlock(POLY_OPA_DISP++, sprite->tex, sprite->im_fmt, + G_IM_SIZ_16b, // @TEMP until I figure out how to use sprite->im_siz + sprite->width, sprite->height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + } else { + gDPLoadTextureBlock(POLY_OPA_DISP++, sprite->tex, sprite->im_fmt, + G_IM_SIZ_32b, // @TEMP until I figure out how to use sprite->im_siz + sprite->width, sprite->height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + } + + CLOSE_DISPS(this->state.gfxCtx, "gfx.c", 40); +} + +void SpriteDraw(FileChooseContext* this, Sprite* sprite, int left, int top, int width, int height) { + int width_factor = (1 << 10) * sprite->width / width; + int height_factor = (1 << 10) * sprite->height / height; + + OPEN_DISPS(this->state.gfxCtx, "gfx.c", 51); + + gSPWideTextureRectangle(POLY_OPA_DISP++, left << 2, top << 2, (left + width) << 2, (top + height) << 2, + G_TX_RENDERTILE, + 0, 0, width_factor, height_factor); + + CLOSE_DISPS(this->state.gfxCtx, "gfx.c", 62); +} + +void DrawSeedHashSprites(FileChooseContext* this) { + OPEN_DISPS(this->state.gfxCtx, "dpad.c", 60); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF); + + // Draw Seed Icons + u16 xStart = 64; + for (u8 i = 0; i < 5; i++) { + SpriteLoad(this, &sprDPad); + SpriteDraw(this, &sprDPad, xStart + (40 * i), 10, 24, 24); + } + + gDPPipeSync(POLY_OPA_DISP++); + + CLOSE_DISPS(this->state.gfxCtx, "dpad.c", 113); +} + /** * Update the cursor and wait for the player to select a button to change menus accordingly. * If an empty file is selected, enter the name entry config mode. @@ -814,6 +875,8 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) { s16 j; s16 deathCountSplit[3]; + DrawSeedHashSprites(this); + if (1) {} OPEN_DISPS(this->state.gfxCtx, "../z_file_choose.c", 1709); @@ -1458,7 +1521,7 @@ void FileChoose_LoadGame(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); gSaveContext.fileNum = this->buttonIndex; Sram_OpenSave(&this->sramCtx); - LoadItemLocations(); + // LoadItemLocations(); gSaveContext.gameMode = 0; SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext); this->state.running = false; @@ -1466,7 +1529,7 @@ void FileChoose_LoadGame(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); gSaveContext.fileNum = this->buttonIndex; Sram_OpenSave(&this->sramCtx); - LoadItemLocations(); + // LoadItemLocations(); gSaveContext.gameMode = 0; SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); this->state.running = false; diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c index 82f5c4b17..32a2c1f83 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c @@ -449,7 +449,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) { dayTime = ((void)0, gSaveContext.dayTime); - ParseItemLocations("blarg"); + // ParseItemLocations("blarg"); Sram_InitSave(this, &this->sramCtx); From 5c39e5239051d6cf5c5d21a19e42df6f528dd132 Mon Sep 17 00:00:00 2001 From: briaguya Date: Sun, 29 May 2022 01:18:01 -0400 Subject: [PATCH 2/6] make setup still works --- .../libultraship/Lib/Fast3D/gfx_sdl2.cpp | 2 + libultraship/libultraship/SohImGuiImpl.cpp | 5 +++ libultraship/libultraship/SohImGuiImpl.h | 1 + soh/include/z64save.h | 1 + soh/randomizerTypes.h | 7 ++++ soh/soh/Enhancements/randomizer.cpp | 39 ++++++++++++++++++- .../ovl_file_choose/z_file_choose.c | 18 ++++----- 7 files changed, 61 insertions(+), 12 deletions(-) diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp index 8d3c529cb..fb37646cd 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp @@ -256,7 +256,9 @@ static void gfx_sdl_handle_events(void) { break; case SDL_DROPFILE: { + #ifndef __linux__ LoadItemLocations(event.drop.file); + #endif break; } case SDL_QUIT: diff --git a/libultraship/libultraship/SohImGuiImpl.cpp b/libultraship/libultraship/SohImGuiImpl.cpp index 3efb91429..21a3013d4 100644 --- a/libultraship/libultraship/SohImGuiImpl.cpp +++ b/libultraship/libultraship/SohImGuiImpl.cpp @@ -240,6 +240,11 @@ namespace SohImGui { stbi_image_free(img_data); } + // thought this might be a way to work around the LoadItemLocations not defined issue + // void LoadItemLocations(const char* spoilerFileName) { + // CVar_SetString("gSpoilerFileName", spoilerFileName); + // } + void LoadInterfaceEditor(){//This function is necessary as without it IMGui wont load the updated float array. hearts_colors[0] = (float)CVar_GetS32("gCCHeartsPrimR", 255)/255; hearts_colors[1] = (float)CVar_GetS32("gCCHeartsPrimG", 70)/255; diff --git a/libultraship/libultraship/SohImGuiImpl.h b/libultraship/libultraship/SohImGuiImpl.h index 210a26db9..602f1098f 100644 --- a/libultraship/libultraship/SohImGuiImpl.h +++ b/libultraship/libultraship/SohImGuiImpl.h @@ -82,4 +82,5 @@ namespace SohImGui { void LoadInterfaceEditor(); ImTextureID GetTextureByID(int id); ImTextureID GetTextureByName(const std::string& name); + // void LoadItemLocations(const char* spoilerFileName); } diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 34cd54e9a..a17f7d37d 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -180,6 +180,7 @@ typedef struct { /* 0x1422 */ s16 sunsSongState; // controls the effects of suns song /* 0x1424 */ s16 healthAccumulator; ItemLocation itemLocations[512]; + Sprite seedIcons[5]; } SaveContext; // size = 0x1428 typedef enum { diff --git a/soh/randomizerTypes.h b/soh/randomizerTypes.h index b9fa7a833..28675f85f 100644 --- a/soh/randomizerTypes.h +++ b/soh/randomizerTypes.h @@ -1,5 +1,12 @@ #pragma once +typedef struct { + char tex[512]; + uint16_t width; + uint16_t height; + uint8_t im_fmt; + uint8_t im_siz; +} Sprite; typedef enum { LINKS_POCKET, diff --git a/soh/soh/Enhancements/randomizer.cpp b/soh/soh/Enhancements/randomizer.cpp index 6b0a934b0..e13697408 100644 --- a/soh/soh/Enhancements/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer.cpp @@ -6,11 +6,46 @@ #include #include #include +#include +#include using json = nlohmann::json; +std::unordered_map gSeedTextures; + Randomizer::Randomizer() { - //todo something? + gSeedTextures["Deku Stick"] = Sprite({ gHookshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Deku Nut"] = Sprite({ gDekuNutIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Bow"] = Sprite({ gFairyBowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Slingshot"] = Sprite({ gFairySlingshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Fairy Ocarina"] = Sprite({ gFairyOcarinaIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Bombchu"] = Sprite({ gBombchuIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Longshot"] = Sprite({ gLongshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Boomerang"] = Sprite({ gBoomerangIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Lens of Truth"] = Sprite({ gLensofTruthIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Beans"] = Sprite({ gMagicBeansIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Megaton Hammer"] = Sprite({ gMegatonHammerIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Bottled Fish"] = Sprite({ gFishIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Bottled Milk"] = Sprite({ gMilkFullIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Mask of Truth"] = Sprite({ gMaskofTruthIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["SOLD OUT"] = Sprite({ gSoldOutIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Cucco"] = Sprite({ gCuccoIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Mushroom"] = Sprite({ gOddMushroomIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Saw"] = Sprite({ gPoachersSawIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Frog"] = Sprite({ gEyeBallFrogIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Master Sword"] = Sprite({ gMasterSwordIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Mirror Shield"] = Sprite({ gMirrorShieldIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Kokiri Tunic"] = Sprite({ gKokiriTunicIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Hover Boots"] = Sprite({ gHoverBootsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Silver Gauntlets"] = Sprite({ gSilverGauntletsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Gold Scale"] = Sprite({ gGoldenScaleIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Stone of Agony"] = Sprite({ gStoneOfAgonyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Skull Token"] = Sprite({ gGoldSkulltulaIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Heart Container"] = Sprite({ gHeartContainerIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Boss Key"] = Sprite({ gBossKeyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Compass"] = Sprite({ gCompassIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Map"] = Sprite({ gDungeonMapIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + gSeedTextures["Big Magic"] = Sprite({ gBigMagicJarIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); } Randomizer::~Randomizer() { this->itemLocations.clear(); @@ -668,7 +703,7 @@ void Randomizer::ParseItemLocations(const char* spoilerFileName) { int index = 0; for (auto it = hashJson.begin(); it != hashJson.end(); ++it) { - //gSaveContext.seedIcons[index] = gSeedTextures[it.value()]; + gSaveContext.seedIcons[index] = gSeedTextures[it.value()]; index++; } diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 13da4f664..19bf38cc2 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -165,14 +165,6 @@ void FileChoose_FinishFadeIn(GameState* thisx) { } } -typedef struct { - char tex[512]; - uint16_t width; - uint16_t height; - uint8_t im_fmt; - uint8_t im_siz; -} Sprite; - Sprite sprDPad = { gHookshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; void SpriteLoad(FileChooseContext* this, Sprite* sprite) { @@ -215,8 +207,14 @@ void DrawSeedHashSprites(FileChooseContext* this) { // Draw Seed Icons u16 xStart = 64; for (u8 i = 0; i < 5; i++) { - SpriteLoad(this, &sprDPad); - SpriteDraw(this, &sprDPad, xStart + (40 * i), 10, 24, 24); + // gSaveContext.seedIcons[i]; + // hacky check to make sure we leaded the icons + if(gSaveContext.seedIcons[i].height) { + SpriteLoad(this, &gSaveContext.seedIcons[i]); + SpriteDraw(this, &gSaveContext.seedIcons[i], xStart + (40 * i), 10, 24, 24); + } + // SpriteLoad(this, &sprDPad); + // SpriteDraw(this, &sprDPad, xStart + (40 * i), 10, 24, 24); } gDPPipeSync(POLY_OPA_DISP++); From f400443c18a64b4ec0b974eb5e482bb61b0db66a Mon Sep 17 00:00:00 2001 From: briaguya Date: Sun, 29 May 2022 02:04:31 -0400 Subject: [PATCH 3/6] hash icons render now --- soh/soh/Enhancements/randomizer.cpp | 100 ++++++++++++------ .../ovl_file_choose/z_file_nameset_PAL.c | 14 ++- 2 files changed, 79 insertions(+), 35 deletions(-) diff --git a/soh/soh/Enhancements/randomizer.cpp b/soh/soh/Enhancements/randomizer.cpp index e13697408..7763d24d0 100644 --- a/soh/soh/Enhancements/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer.cpp @@ -14,39 +14,73 @@ using json = nlohmann::json; std::unordered_map gSeedTextures; Randomizer::Randomizer() { - gSeedTextures["Deku Stick"] = Sprite({ gHookshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Deku Nut"] = Sprite({ gDekuNutIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Bow"] = Sprite({ gFairyBowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Slingshot"] = Sprite({ gFairySlingshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Fairy Ocarina"] = Sprite({ gFairyOcarinaIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Bombchu"] = Sprite({ gBombchuIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Longshot"] = Sprite({ gLongshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Boomerang"] = Sprite({ gBoomerangIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Lens of Truth"] = Sprite({ gLensofTruthIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Beans"] = Sprite({ gMagicBeansIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Megaton Hammer"] = Sprite({ gMegatonHammerIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Bottled Fish"] = Sprite({ gFishIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Bottled Milk"] = Sprite({ gMilkFullIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Mask of Truth"] = Sprite({ gMaskofTruthIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["SOLD OUT"] = Sprite({ gSoldOutIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Cucco"] = Sprite({ gCuccoIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Mushroom"] = Sprite({ gOddMushroomIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Saw"] = Sprite({ gPoachersSawIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Frog"] = Sprite({ gEyeBallFrogIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Master Sword"] = Sprite({ gMasterSwordIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Mirror Shield"] = Sprite({ gMirrorShieldIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Kokiri Tunic"] = Sprite({ gKokiriTunicIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Hover Boots"] = Sprite({ gHoverBootsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Silver Gauntlets"] = Sprite({ gSilverGauntletsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Gold Scale"] = Sprite({ gGoldenScaleIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Stone of Agony"] = Sprite({ gStoneOfAgonyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Skull Token"] = Sprite({ gGoldSkulltulaIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Heart Container"] = Sprite({ gHeartContainerIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Boss Key"] = Sprite({ gBossKeyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Compass"] = Sprite({ gCompassIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Map"] = Sprite({ gDungeonMapIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); - gSeedTextures["Big Magic"] = Sprite({ gBigMagicJarIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }); + // this isn't as clean as i'd like it to be but it's working + Sprite dekuStickSprite = { gHookshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Deku Stick"] = dekuStickSprite; + Sprite dekuNutSprite = { gDekuNutIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Deku Nut"] = dekuNutSprite; + Sprite bowSprite = { gFairyBowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Bow"] = bowSprite; + Sprite slingshotSprite = { gFairySlingshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Slingshot"] = slingshotSprite; + Sprite fairyOcarinaSprite = { gFairyOcarinaIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Fairy Ocarina"] = fairyOcarinaSprite; + Sprite bombchuSprite = { gBombchuIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Bombchu"] = bombchuSprite; + Sprite longshotSprite = { gLongshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Longshot"] = longshotSprite; + Sprite boomerangSprite = { gBoomerangIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Boomerang"] = boomerangSprite; + Sprite lensOfTruthSprite = { gLensofTruthIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Lens of Truth"] = lensOfTruthSprite; + Sprite magicBeansSprite = { gMagicBeansIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Beans"] = magicBeansSprite; + Sprite megatonHammerSprite = { gMegatonHammerIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Megaton Hammer"] = megatonHammerSprite; + Sprite fishSprite = { gFishIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Bottled Fish"] = fishSprite; + Sprite milkSprite = { gMilkFullIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Bottled Milk"] = milkSprite; + Sprite maskOfTruthSprite = { gMaskofTruthIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Mask of Truth"] = maskOfTruthSprite; + Sprite soldOutSprite = { gSoldOutIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["SOLD OUT"] = soldOutSprite; + Sprite cuccoSprite = { gCuccoIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Cucco"] = cuccoSprite; + Sprite oddMushroomSprite = { gOddMushroomIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Mushroom"] = oddMushroomSprite; + Sprite sawSprite = { gPoachersSawIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Saw"] = sawSprite; + Sprite frogSprite = { gEyeBallFrogIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Frog"] = frogSprite; + Sprite masterSwordSprite = { gMasterSwordIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Master Sword"] = masterSwordSprite; + Sprite mirrorShieldSprite = { gMirrorShieldIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Mirror Shield"] = mirrorShieldSprite; + Sprite kokiriTunicSprite = { gKokiriTunicIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Kokiri Tunic"] = kokiriTunicSprite; + Sprite hoverBootsSprite = { gHoverBootsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Hover Boots"] = hoverBootsSprite; + Sprite silverGauntletsSprite = { gSilverGauntletsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Silver Gauntlets"] = silverGauntletsSprite; + Sprite goldenScaleSprite = { gGoldenScaleIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Gold Scale"] = goldenScaleSprite; + Sprite stoneOfAgonySprite = { gStoneOfAgonyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Stone of Agony"] = stoneOfAgonySprite; + Sprite skullTokenSprite = { gGoldSkulltulaIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Skull Token"] = skullTokenSprite; + Sprite heartContainerSprite = { gHeartContainerIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Heart Container"] = heartContainerSprite; + Sprite bossKeySprite = { gBossKeyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Boss Key"] = bossKeySprite; + Sprite compassSprite = { gCompassIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Compass"] = compassSprite; + Sprite mapSprite = { gDungeonMapIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Map"] = mapSprite; + Sprite bigMagicSprite = { gBigMagicJarIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b }; + gSeedTextures["Big Magic"] = bigMagicSprite; } + Randomizer::~Randomizer() { this->itemLocations.clear(); } @@ -693,7 +727,7 @@ void Randomizer::ParseItemLocations(const char* spoilerFileName) { if (!spoilerFileStream) return; - bool success = false; + bool success = false; try { json spoilerFileJson; diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c index 32a2c1f83..aa1ebe886 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c @@ -448,8 +448,18 @@ void FileChoose_DrawNameEntry(GameState* thisx) { } dayTime = ((void)0, gSaveContext.dayTime); - - // ParseItemLocations("blarg"); + + // hacky function for testing + // while drag and drop is broken on linux + // enter "rando" as file name + if(this->fileNames[1][0] == '5' && + this->fileNames[1][1] == '$' && + this->fileNames[1][2] == '1' && + this->fileNames[1][3] == '\'' && + this->fileNames[1][4] == '2') + { + ParseItemLocations("spoiler.json"); + } Sram_InitSave(this, &this->sramCtx); From c7772a12f24080ef749325fd00e930aafbfb7fd9 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Sun, 29 May 2022 09:53:24 -0400 Subject: [PATCH 4/6] added direct3d drag support --- .../libultraship/Lib/Fast3D/gfx_dxgi.cpp | 185 ++++++++++-------- .../libultraship/Lib/Fast3D/gfx_sdl2.cpp | 54 ++--- 2 files changed, 129 insertions(+), 110 deletions(-) diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp index 49abe0b28..0df0690a6 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp @@ -54,8 +54,8 @@ static struct { std::string game_name; HMODULE dxgi_module; - HRESULT (__stdcall *CreateDXGIFactory1)(REFIID riid, void **factory); - HRESULT (__stdcall *CreateDXGIFactory2)(UINT flags, REFIID iid, void **factory); + HRESULT(__stdcall* CreateDXGIFactory1)(REFIID riid, void** factory); + HRESULT(__stdcall* CreateDXGIFactory2)(UINT flags, REFIID iid, void** factory); bool process_dpi_awareness_done; @@ -87,8 +87,8 @@ static struct { static void load_dxgi_library(void) { dxgi.dxgi_module = LoadLibraryW(L"dxgi.dll"); - *(FARPROC *)&dxgi.CreateDXGIFactory1 = GetProcAddress(dxgi.dxgi_module, "CreateDXGIFactory1"); - *(FARPROC *)&dxgi.CreateDXGIFactory2 = GetProcAddress(dxgi.dxgi_module, "CreateDXGIFactory2"); + *(FARPROC*)&dxgi.CreateDXGIFactory1 = GetProcAddress(dxgi.dxgi_module, "CreateDXGIFactory1"); + *(FARPROC*)&dxgi.CreateDXGIFactory2 = GetProcAddress(dxgi.dxgi_module, "CreateDXGIFactory2"); } template @@ -106,25 +106,26 @@ static void run_as_dpi_aware(Fun f) { // From windef.h, missing in MinGW. DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); - #define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1) - #define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2) - #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3) - #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) - #define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5) +#define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1) +#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2) +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3) +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) +#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5) - DPI_AWARENESS_CONTEXT (WINAPI *SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext); - *(FARPROC *)&SetThreadDpiAwarenessContext = GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetThreadDpiAwarenessContext"); + DPI_AWARENESS_CONTEXT(WINAPI * SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext); + *(FARPROC*)&SetThreadDpiAwarenessContext = GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetThreadDpiAwarenessContext"); DPI_AWARENESS_CONTEXT old_awareness_context = nullptr; if (SetThreadDpiAwarenessContext != nullptr) { old_awareness_context = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - } else { + } + else { // Solution for Windows 8.1 and newer, but before Windows 10 1607. // SetProcessDpiAwareness must be called before any drawing related API is called. if (!dxgi.process_dpi_awareness_done) { HMODULE shcore_module = LoadLibraryW(L"SHCore.dll"); if (shcore_module != nullptr) { - HRESULT (WINAPI *SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS value); - *(FARPROC *)&SetProcessDpiAwareness = GetProcAddress(shcore_module, "SetProcessDpiAwareness"); + HRESULT(WINAPI * SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS value); + *(FARPROC*)&SetProcessDpiAwareness = GetProcAddress(shcore_module, "SetProcessDpiAwareness"); if (SetProcessDpiAwareness != nullptr) { SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); // Ignore result, will fail if already called or manifest already specifies dpi awareness. @@ -162,13 +163,15 @@ static void toggle_borderless_window_full_screen(bool enable, bool call_callback if (dxgi.last_maximized_state) { SetWindowPos(dxgi.h_wnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); ShowWindow(dxgi.h_wnd, SW_MAXIMIZE); - } else { + } + else { SetWindowPos(dxgi.h_wnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_FRAMECHANGED); ShowWindow(dxgi.h_wnd, SW_RESTORE); } dxgi.is_full_screen = false; - } else { + } + else { // Save if window is maximized or not WINDOWPLACEMENT window_placement; window_placement.length = sizeof(WINDOWPLACEMENT); @@ -212,59 +215,68 @@ static void onkeyup(WPARAM w_param, LPARAM l_param) { } } +extern "C" void LoadItemLocations(const char* spoilerFileName); + static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_param, LPARAM l_param) { SohImGui::EventImpl event_impl; event_impl.win32 = { h_wnd, static_cast(message), static_cast(w_param), static_cast(l_param) }; SohImGui::Update(event_impl); switch (message) { - case WM_SIZE: - dxgi.current_width = (uint32_t)(l_param & 0xffff); - dxgi.current_height = (uint32_t)(l_param >> 16); - break; - case WM_DESTROY: - exit(0); - case WM_PAINT: - if (dxgi.in_paint) { - dxgi.recursive_paint_detected = true; - return DefWindowProcW(h_wnd, message, w_param, l_param); - } else { - if (dxgi.run_one_game_iter != nullptr) { - dxgi.in_paint = true; - dxgi.run_one_game_iter(); - dxgi.in_paint = false; - if (dxgi.recursive_paint_detected) { - dxgi.recursive_paint_detected = false; - InvalidateRect(h_wnd, nullptr, false); - UpdateWindow(h_wnd); - } + case WM_SIZE: + dxgi.current_width = (uint32_t)(l_param & 0xffff); + dxgi.current_height = (uint32_t)(l_param >> 16); + break; + case WM_DESTROY: + exit(0); + case WM_PAINT: + if (dxgi.in_paint) { + dxgi.recursive_paint_detected = true; + return DefWindowProcW(h_wnd, message, w_param, l_param); + } + else { + if (dxgi.run_one_game_iter != nullptr) { + dxgi.in_paint = true; + dxgi.run_one_game_iter(); + dxgi.in_paint = false; + if (dxgi.recursive_paint_detected) { + dxgi.recursive_paint_detected = false; + InvalidateRect(h_wnd, nullptr, false); + UpdateWindow(h_wnd); } } + } + break; + case WM_ACTIVATEAPP: + if (dxgi.on_all_keys_up != nullptr) { + dxgi.on_all_keys_up(); + } + break; + case WM_KEYDOWN: + onkeydown(w_param, l_param); + break; + case WM_KEYUP: + onkeyup(w_param, l_param); + break; + case WM_DROPFILES: + char fileName[256]; + DragQueryFileA((HDROP)w_param, 0, fileName, 256); + LoadItemLocations(fileName); + break; + case WM_SYSKEYDOWN: + if ((w_param == VK_RETURN) && ((l_param & 1 << 30) == 0)) { + toggle_borderless_window_full_screen(!dxgi.is_full_screen, true); break; - case WM_ACTIVATEAPP: - if (dxgi.on_all_keys_up != nullptr) { - dxgi.on_all_keys_up(); - } - break; - case WM_KEYDOWN: - onkeydown(w_param, l_param); - break; - case WM_KEYUP: - onkeyup(w_param, l_param); - break; - case WM_SYSKEYDOWN: - if ((w_param == VK_RETURN) && ((l_param & 1 << 30) == 0)) { - toggle_borderless_window_full_screen(!dxgi.is_full_screen, true); - break; - } else { - return DefWindowProcW(h_wnd, message, w_param, l_param); - } - default: + } + else { return DefWindowProcW(h_wnd, message, w_param, l_param); + } + default: + return DefWindowProcW(h_wnd, message, w_param, l_param); } return 0; } -void gfx_dxgi_init(const char *game_name, bool start_in_fullscreen) { +void gfx_dxgi_init(const char* game_name, bool start_in_fullscreen) { LARGE_INTEGER qpc_init, qpc_freq; QueryPerformanceCounter(&qpc_init); QueryPerformanceFrequency(&qpc_freq); @@ -287,29 +299,29 @@ void gfx_dxgi_init(const char *game_name, bool start_in_fullscreen) { wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = gfx_dxgi_wnd_proc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = nullptr; - wcex.hIcon = nullptr; - wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wcex.lpszMenuName = nullptr; - wcex.lpszClassName = WINCLASS_NAME; - wcex.hIconSm = nullptr; + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = gfx_dxgi_wnd_proc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = nullptr; + wcex.hIcon = nullptr; + wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcex.lpszMenuName = nullptr; + wcex.lpszClassName = WINCLASS_NAME; + wcex.hIconSm = nullptr; ATOM winclass = RegisterClassExW(&wcex); - run_as_dpi_aware([&] () { + run_as_dpi_aware([&]() { // We need to be dpi aware when calculating the size - RECT wr = {0, 0, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT}; + RECT wr = { 0, 0, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT }; AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); dxgi.h_wnd = CreateWindowW(WINCLASS_NAME, w_title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, wr.right - wr.left, wr.bottom - wr.top, nullptr, nullptr, nullptr, nullptr); - }); + }); load_dxgi_library(); @@ -319,6 +331,8 @@ void gfx_dxgi_init(const char *game_name, bool start_in_fullscreen) { if (start_in_fullscreen) { toggle_borderless_window_full_screen(true, false); } + + DragAcceptFiles(dxgi.h_wnd, TRUE); } static void gfx_dxgi_set_fullscreen_changed_callback(void (*on_fullscreen_changed)(bool is_now_fullscreen)) { @@ -354,7 +368,7 @@ static void gfx_dxgi_main_loop(void (*run_one_game_iter)(void)) { } } -static void gfx_dxgi_get_dimensions(uint32_t *width, uint32_t *height) { +static void gfx_dxgi_get_dimensions(uint32_t* width, uint32_t* height) { *width = dxgi.current_width; *height = dxgi.current_height; } @@ -409,8 +423,8 @@ static bool gfx_dxgi_start_frame(void) { dxgi.frame_timestamp += FRAME_INTERVAL_US_NUMERATOR; if (dxgi.frame_stats.size() >= 2) { - DXGI_FRAME_STATISTICS *first = &dxgi.frame_stats.begin()->second; - DXGI_FRAME_STATISTICS *last = &dxgi.frame_stats.rbegin()->second; + DXGI_FRAME_STATISTICS* first = &dxgi.frame_stats.begin()->second; + DXGI_FRAME_STATISTICS* last = &dxgi.frame_stats.rbegin()->second; uint64_t sync_qpc_diff = last->SyncQPCTime.QuadPart - first->SyncQPCTime.QuadPart; UINT sync_vsync_diff = last->SyncRefreshCount - first->SyncRefreshCount; UINT present_vsync_diff = last->PresentRefreshCount - first->PresentRefreshCount; @@ -455,7 +469,8 @@ static bool gfx_dxgi_start_frame(void) { vsyncs_to_wait = 1; } dxgi.frame_timestamp = FRAME_INTERVAL_US_DENOMINATOR * (last_end_us + vsyncs_to_wait * estimated_vsync_interval_us); - } else { + } + else { // Drop frame //printf("Dropping frame\n"); dxgi.dropped_frame = true; @@ -477,7 +492,8 @@ static bool gfx_dxgi_start_frame(void) { } if (diff_left < diff_right) { vsyncs_to_wait = floor(vsyncs_to_wait); - } else { + } + else { vsyncs_to_wait = ceil(vsyncs_to_wait); } if (vsyncs_to_wait == 0) { @@ -493,7 +509,8 @@ static bool gfx_dxgi_start_frame(void) { dxgi.use_timer = true; } dxgi.length_in_vsync_frames = vsyncs_to_wait; - } else { + } + else { dxgi.length_in_vsync_frames = 1; dxgi.use_timer = true; } @@ -558,10 +575,11 @@ static void gfx_dxgi_set_frame_divisor(int divisor) { dxgi.frame_divisor = divisor; } -void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only)) { +void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1* adapter, bool test_only)) { if (dxgi.CreateDXGIFactory2 != nullptr) { ThrowIfFailed(dxgi.CreateDXGIFactory2(debug ? DXGI_CREATE_FACTORY_DEBUG : 0, __uuidof(IDXGIFactory2), &dxgi.factory)); - } else { + } + else { ThrowIfFailed(dxgi.CreateDXGIFactory1(__uuidof(IDXGIFactory2), &dxgi.factory)); } @@ -592,7 +610,7 @@ void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*crea SetWindowTextW(dxgi.h_wnd, w_title); } -ComPtr gfx_dxgi_create_swap_chain(IUnknown *device) { +ComPtr gfx_dxgi_create_swap_chain(IUnknown* device) { bool win8 = IsWindows8OrGreater(); // DXGI_SCALING_NONE is only supported on Win8 and beyond bool dxgi_13 = dxgi.CreateDXGIFactory2 != nullptr; // DXGI 1.3 introduced waitable object @@ -609,12 +627,12 @@ ComPtr gfx_dxgi_create_swap_chain(IUnknown *device) { swap_chain_desc.Flags = dxgi_13 ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0; swap_chain_desc.SampleDesc.Count = 1; - run_as_dpi_aware([&] () { + run_as_dpi_aware([&]() { // When setting size for the buffers, the values that DXGI puts into the desc (that can later be retrieved by GetDesc1) // have been divided by the current scaling factor. By making this call dpi aware, no division will be performed. // The same goes for IDXGISwapChain::ResizeBuffers(), however that function is currently only called from the message handler. ThrowIfFailed(dxgi.factory->CreateSwapChainForHwnd(device, dxgi.h_wnd, &swap_chain_desc, nullptr, nullptr, &dxgi.swap_chain)); - }); + }); ThrowIfFailed(dxgi.factory->MakeWindowAssociation(dxgi.h_wnd, DXGI_MWA_NO_ALT_ENTER)); ComPtr swap_chain2; @@ -622,7 +640,8 @@ ComPtr gfx_dxgi_create_swap_chain(IUnknown *device) { ThrowIfFailed(swap_chain2->SetMaximumFrameLatency(1)); dxgi.waitable_object = swap_chain2->GetFrameLatencyWaitableObject(); WaitForSingleObject(dxgi.waitable_object, INFINITE); - } else { + } + else { ComPtr device1; ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&device1))); ThrowIfFailed(device1->SetMaximumFrameLatency(1)); @@ -646,7 +665,7 @@ void ThrowIfFailed(HRESULT res) { } } -void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message) { +void ThrowIfFailed(HRESULT res, HWND h_wnd, const char* message) { if (FAILED(res)) { char full_message[256]; sprintf(full_message, "%s\n\nHRESULT: 0x%08X", message, res); diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp index fb37646cd..adca7eb0f 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp @@ -30,7 +30,7 @@ #define GFX_API_NAME "SDL2 - OpenGL" -static SDL_Window *wnd; +static SDL_Window* wnd; static SDL_GLContext ctx; static int inverted_scancode_table[512]; static int vsync_enabled = 0; @@ -105,7 +105,8 @@ static void set_fullscreen(bool on, bool call_callback) { window_width = mode.w; window_height = mode.h; SDL_ShowCursor(false); - } else { + } + else { window_width = DESIRED_SCREEN_WIDTH; window_height = DESIRED_SCREEN_HEIGHT; } @@ -129,7 +130,7 @@ static int frameDivisor = 1; #define FRAME_INTERVAL_US_DENOMINATOR 3 #define FRAME_INTERVAL_US_NUMERATOR (FRAME_INTERVAL_US_NUMERATOR_ * frameDivisor) -static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { +static void gfx_sdl_init(const char* game_name, bool start_in_fullscreen) { SDL_Init(SDL_INIT_VIDEO); SDL_EventState(SDL_DROPFILE, SDL_ENABLE); @@ -148,7 +149,7 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { int len = sprintf(title, "%s (%s)", game_name, GFX_API_NAME); wnd = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); + window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); if (start_in_fullscreen) { set_fullscreen(true, false); @@ -202,7 +203,7 @@ static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) { } } -static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) { +static void gfx_sdl_get_dimensions(uint32_t* width, uint32_t* height) { *width = window_width; *height = window_height; } @@ -210,7 +211,8 @@ static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) { static int translate_scancode(int scancode) { if (scancode < 512) { return inverted_scancode_table[scancode]; - } else { + } + else { return 0; } } @@ -241,28 +243,26 @@ static void gfx_sdl_handle_events(void) { switch (event.type) { #ifndef TARGET_WEB // Scancodes are broken in Emscripten SDL2: https://bugzilla.libsdl.org/show_bug.cgi?id=3259 - case SDL_KEYDOWN: - gfx_sdl_onkeydown(event.key.keysym.scancode); - break; - case SDL_KEYUP: - gfx_sdl_onkeyup(event.key.keysym.scancode); - break; + case SDL_KEYDOWN: + gfx_sdl_onkeydown(event.key.keysym.scancode); + break; + case SDL_KEYUP: + gfx_sdl_onkeyup(event.key.keysym.scancode); + break; #endif - case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { - window_width = event.window.data1; - window_height = event.window.data2; - } - break; - case SDL_DROPFILE: - { - #ifndef __linux__ - LoadItemLocations(event.drop.file); - #endif - break; + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + window_width = event.window.data1; + window_height = event.window.data2; } - case SDL_QUIT: - exit(0); + break; + case SDL_DROPFILE: + { + LoadItemLocations(event.drop.file); + break; + } + case SDL_QUIT: + exit(0); } } } @@ -332,4 +332,4 @@ struct GfxWindowManagerAPI gfx_sdl = { gfx_sdl_set_framedivisor }; -#endif +#endif \ No newline at end of file From 3a84be3a48baa9b2b9255146279bccabfdcc3a5b Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Sun, 29 May 2022 13:00:14 -0400 Subject: [PATCH 5/6] added link's pocket medallion/gem --- soh/include/z64save.h | 2 +- soh/soh/Enhancements/randomizer.cpp | 19 ++++-- soh/src/code/title_setup.c | 2 +- soh/src/code/z_play.c | 60 ++++++++++++++++++- .../ovl_file_choose/z_file_choose.c | 5 +- 5 files changed, 78 insertions(+), 10 deletions(-) diff --git a/soh/include/z64save.h b/soh/include/z64save.h index a17f7d37d..ad4c6e5c5 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -179,7 +179,7 @@ typedef struct { /* 0x1420 */ s16 worldMapArea; /* 0x1422 */ s16 sunsSongState; // controls the effects of suns song /* 0x1424 */ s16 healthAccumulator; - ItemLocation itemLocations[512]; + ItemLocation itemLocations[266]; Sprite seedIcons[5]; } SaveContext; // size = 0x1428 diff --git a/soh/soh/Enhancements/randomizer.cpp b/soh/soh/Enhancements/randomizer.cpp index 7763d24d0..c18f28693 100644 --- a/soh/soh/Enhancements/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer.cpp @@ -713,11 +713,20 @@ s16 Randomizer::GetItemModelFromId(s16 itemId) { } void Randomizer::LoadItemLocations(const char* spoilerFileName) { - // bandaid until new save stuff happens - ParseItemLocations(spoilerFileName); + if (strcmp(spoilerFileName, "") != 0) { + // bandaid until new save stuff happens + ParseItemLocations(spoilerFileName); - for(auto itemLocation : gSaveContext.itemLocations) { - this->itemLocations[itemLocation.check] = itemLocation.get; + for (auto itemLocation : gSaveContext.itemLocations) { + this->itemLocations[itemLocation.check] = itemLocation.get; + } + } else { + u16 index = 0; + for (auto itemLocation : this->itemLocations) { + gSaveContext.itemLocations[index].check = itemLocation.first; + gSaveContext.itemLocations[index].get = itemLocation.second; + index++; + } } } @@ -1026,7 +1035,7 @@ RandomizerCheck Randomizer::GetCheckFromSceneAndParams(s16 sceneNum, s16 actorPa } case 84: switch (actorParams) { - case 0x0406: + case 1030: return ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH; case 2822: return ZR_NEAR_DOMAIN_FREESTANDING_POH; diff --git a/soh/src/code/title_setup.c b/soh/src/code/title_setup.c index 131c97627..1e709dc12 100644 --- a/soh/src/code/title_setup.c +++ b/soh/src/code/title_setup.c @@ -4,7 +4,7 @@ void TitleSetup_InitImpl(GameState* gameState) { osSyncPrintf("ゼルダ共通データ初期化\n"); // "Zelda common data initalization" SaveContext_Init(); gameState->running = false; - SET_NEXT_GAMESTATE(gameState, FileChoose_Init, TitleContext); + SET_NEXT_GAMESTATE(gameState, Title_Init, TitleContext); } void TitleSetup_Destroy(GameState* gameState) { diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 632ed41f6..15f8f71c0 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -193,11 +193,67 @@ void Gameplay_Destroy(GameState* thisx) { gGlobalCtx = NULL; } +void GiveLinksPocketMedallion(GlobalContext* globalCtx) { + if (gSaveContext.n64ddFlag) { + RandomizerGet get = gSaveContext.itemLocations[LINKS_POCKET].get; + + s16 item; + + u8 medallion = 0; + + switch (get) { + case FOREST_MEDALLION: + item = ITEM_MEDALLION_FOREST; + medallion = 1; + break; + case FIRE_MEDALLION: + item = ITEM_MEDALLION_FIRE; + medallion = 1; + break; + case WATER_MEDALLION: + item = ITEM_MEDALLION_WATER; + medallion = 1; + break; + case SHADOW_MEDALLION: + item = ITEM_MEDALLION_SHADOW; + medallion = 1; + break; + case SPIRIT_MEDALLION: + item = ITEM_MEDALLION_SPIRIT; + medallion = 1; + break; + case LIGHT_MEDALLION: + item = ITEM_MEDALLION_LIGHT; + medallion = 1; + break; + case KOKIRI_EMERALD: + item = ITEM_KOKIRI_EMERALD; + break; + case GORON_RUBY: + item = ITEM_GORON_RUBY; + break; + case ZORA_SAPPHIRE: + item = ITEM_ZORA_SAPPHIRE; + break; + } + + if (medallion == 1) { + gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST]; + + if (item == ITEM_MEDALLION_WATER) { + func_8006D0AC(globalCtx); + } + } else { + gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_KOKIRI_EMERALD + QUEST_KOKIRI_EMERALD]; + } + } +} + void Gameplay_Init(GameState* thisx) { GlobalContext* globalCtx = (GlobalContext*)thisx; GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; gGlobalCtx = globalCtx; - //globalCtx->state.gfxCtx = NULL; + // globalCtx->state.gfxCtx = NULL; u32 zAlloc; u32 zAllocAligned; size_t zAllocSize; @@ -207,6 +263,8 @@ void Gameplay_Init(GameState* thisx) { u8 tempSetupIndex; s32 pad[2]; + GiveLinksPocketMedallion(globalCtx); + if (gSaveContext.entranceIndex == -1) { gSaveContext.entranceIndex = 0; globalCtx->state.running = false; diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 19bf38cc2..eaf08721e 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -1519,7 +1519,6 @@ void FileChoose_LoadGame(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); gSaveContext.fileNum = this->buttonIndex; Sram_OpenSave(&this->sramCtx); - // LoadItemLocations(); gSaveContext.gameMode = 0; SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext); this->state.running = false; @@ -1527,12 +1526,14 @@ void FileChoose_LoadGame(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); gSaveContext.fileNum = this->buttonIndex; Sram_OpenSave(&this->sramCtx); - // LoadItemLocations(); + gSaveContext.gameMode = 0; SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); this->state.running = false; } + LoadItemLocations(""); + gSaveContext.respawn[0].entranceIndex = -1; gSaveContext.respawnFlag = 0; gSaveContext.seqId = (u8)NA_BGM_DISABLED; From ee8bb45cb337d4062009bcc5d7caaf8a53b03b4e Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Sun, 29 May 2022 13:27:37 -0400 Subject: [PATCH 6/6] gohma's HC & heart containers in general are randomized now Also makes it so gohma's warp warps you without a cutscene --- soh/soh/Enhancements/randomizer.cpp | 5 +++ .../actors/ovl_Door_Warp1/z_door_warp1.c | 9 +++-- .../actors/ovl_Item_B_Heart/z_item_b_heart.c | 36 ++++++++++++------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/soh/soh/Enhancements/randomizer.cpp b/soh/soh/Enhancements/randomizer.cpp index c18f28693..1144315dd 100644 --- a/soh/soh/Enhancements/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer.cpp @@ -1022,6 +1022,11 @@ RandomizerCheck Randomizer::GetCheckFromSceneAndParams(s16 sceneNum, s16 actorPa } switch(sceneNum) { + case 17: + switch (actorParams) { + case 0x1F: + return DEKU_TREE_QUEEN_GOHMA_HEART; + } case 40: switch(actorParams) { case 22944: diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index ee503dd43..a2a256731 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -515,8 +515,13 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, GlobalContext* globalCtx) { Flags_SetEventChkInf(7); Flags_SetEventChkInf(9); Item_Give(globalCtx, ITEM_KOKIRI_EMERALD); - globalCtx->nextEntranceIndex = 0xEE; - gSaveContext.nextCutsceneIndex = 0xFFF1; + if (gSaveContext.n64ddFlag) { + globalCtx->nextEntranceIndex = 0x0457; + gSaveContext.nextCutsceneIndex = 0; + } else { + globalCtx->nextEntranceIndex = 0xEE; + gSaveContext.nextCutsceneIndex = 0xFFF1; + } } else { globalCtx->nextEntranceIndex = 0x457; gSaveContext.nextCutsceneIndex = 0; diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index e9a5e9181..7650f7c17 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -59,7 +59,12 @@ void ItemBHeart_Update(Actor* thisx, GlobalContext* globalCtx) { Flags_SetCollectible(globalCtx, 0x1F); Actor_Kill(&this->actor); } else { - func_8002F434(&this->actor, globalCtx, GI_HEART_CONTAINER_2, 30.0f, 40.0f); + if (gSaveContext.n64ddFlag) { + s16 getItemId = GetRandomizedItemId(GI_HEART_CONTAINER_2, globalCtx->sceneNum, 0x1F); + func_8002F434(&this->actor, globalCtx, getItemId, 30.0f, 40.0f); + } else { + func_8002F434(&this->actor, globalCtx, GI_HEART_CONTAINER_2, 30.0f, 40.0f); + } } } @@ -93,19 +98,24 @@ void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx) { actorIt = actorIt->next; } - if (flag) { - func_80093D84(globalCtx->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 551), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL); - gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL); + if (gSaveContext.n64ddFlag) { + GetItem_Draw(globalCtx, + GetItemModelFromId(GetRandomizedItemId(GI_HEART_CONTAINER_2, globalCtx->sceneNum, 0x1F))); } else { - func_80093D18(globalCtx->state.gfxCtx); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 557), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL); - gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL); + if (flag) { + func_80093D84(globalCtx->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 551), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL); + gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL); + } else { + func_80093D18(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 557), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL); + gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL); + } } CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 561); -} +} \ No newline at end of file