diff --git a/features.h b/features.h index c538c95..5794114 100644 --- a/features.h +++ b/features.h @@ -48,8 +48,10 @@ enum { #define msu_curr_sample (*(uint32*)(g_ram+0x650)) #define msu_volume (*(uint8*)(g_ram+0x654)) #define msu_track (*(uint8*)(g_ram+0x655)) -#define hud_cur_item_x (*(uint8*)(g_ram+0x656)) #define hud_inventory_order ((uint8*)(g_ram + 0x225)) // 4x6 bytes +#define hud_cur_item_x (*(uint8*)(g_ram+0x656)) +#define hud_cur_item_l (*(uint8*)(g_ram+0x657)) +#define hud_cur_item_r (*(uint8*)(g_ram+0x658)) diff --git a/hud.c b/hud.c index e4643ae..513bb46 100644 --- a/hud.c +++ b/hud.c @@ -594,6 +594,21 @@ static void Hud_EquipItemBelow(uint8 *item) { // 8ddf00 } while (!Hud_DoWeHaveThisItem(*item)); } +int GetCurrentItemButtonIndex() { + if (enhanced_features0 & kFeatures0_SwitchLR) { + return (joypad1L_last & kJoypadL_X) ? 1 : + (joypad1L_last & kJoypadL_L) ? 2 : + (joypad1L_last & kJoypadL_R) ? 3 : 0; + } + return 0; +} + +uint8 *GetCurrentItemButtonPtr(int i) { + return (i == 0) ? &hud_cur_item : + (i == 1) ? &hud_cur_item_x : + (i == 2) ? &hud_cur_item_l : &hud_cur_item_r; +} + void Hud_NormalMenu() { // 8ddf15 timer_for_flashing_circle++; if (!BYTE(joypad1H_last)) @@ -624,8 +639,9 @@ void Hud_NormalMenu() { // 8ddf15 Hud_ReorderItem(1); } } else if (!BYTE(hud_tmp1)) { - // If the x button is down, then move the blue circle - uint8 *item_p = (joypad1L_last & kJoypadL_X && (enhanced_features0 & kFeatures0_SwitchLR)) ? &hud_cur_item_x : &hud_cur_item; + // If Special Key button is down, then move their circle + int btn_index = GetCurrentItemButtonIndex(); + uint8 *item_p = GetCurrentItemButtonPtr(btn_index); uint16 old_item = *item_p; if (filtered_joypad_H & kJoypadH_Up) { Hud_EquipItemAbove(item_p); @@ -912,22 +928,80 @@ static const ItemBoxGfx *Hud_GetIconForItem(int i) { return &kHudItemBoxGfxPtrs[i - 1][item_val]; } +static void CopyTilesForSwitchLR(int switch_lr) { +#define PV(a0,a1,a2,a3,a4,a5,a6,a7) ((a0 & 1) << 7 | (a0 >> 1 & 1) << 15 | (a1 & 1) << 6 | (a1 >> 1 & 1) << 14 | (a2 & 1) <<5 | (a2 >> 1&1) <<13 | (a3 & 1) << 4 | (a3>> 1 & 1) << 12 | (a4 & 1) << 3 | (a4 >> 1 & 1) << 11 | (a5 & 1) << 2 | (a5 >> 1 & 1) << 10 | (a6 & 1) << 1 | (a6 >> 1 & 1) << 9 | (a7 & 1) << 0 | (a7 >> 1 & 1) << 8) + + if (switch_lr == 3) { + static const uint16 kBytesForNewTile0xC_TopOfR[8] = { + PV(1,1,1,1,1,1,3,3), + PV(1,1,1,1,1,1,1,3), + PV(1,1,1,1,1,1,1,1), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,1,1,1,1,3) + }; + memcpy(&g_zenv.vram[0x7000 + 0xc * 8], kBytesForNewTile0xC_TopOfR, sizeof(kBytesForNewTile0xC_TopOfR)); + + static const uint16 kBytesForNewTile0xD_BottomofR[8] = { + PV(1,1,1,1,1,1,3,3), + PV(1,1,1,3,1,1,1,3), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,3,3,1,1,1), + PV(1,1,1,3,3,1,1,1) + }; + memcpy(&g_zenv.vram[0x7000 + 0xd * 8], kBytesForNewTile0xD_BottomofR, sizeof(kBytesForNewTile0xD_BottomofR));; + }else if (switch_lr == 2) { + static const uint16 kBytesForNewTile0xE_TopOfL[8] = { + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3) + }; + memcpy(&g_zenv.vram[0x7000 + 0xe * 8], kBytesForNewTile0xE_TopOfL, sizeof(kBytesForNewTile0xE_TopOfL)); + + static const uint16 kBytesForNewTile0xF_BottomofL[8] = { + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,3,3,3,3,3), + PV(1,1,1,1,1,1,1,1), + PV(1,1,1,1,1,1,1,1), + PV(1,1,1,1,1,1,1,1) + }; + memcpy(&g_zenv.vram[0x7000 + 0xf * 8], kBytesForNewTile0xF_BottomofL, sizeof(kBytesForNewTile0xF_BottomofL)); + } +#undef PV +} + +static const uint8 kSwitchLR_palettes[] = { 7, 3, 4, 4 }; + void Hud_DrawYButtonItems() { // 8de3d9 uint16 *dst = uvram_screen.row[0].col; int x = kNewStyleInventory ? 0 : 1; - bool is_x = (joypad1L_last & kJoypadL_X && (enhanced_features0 & kFeatures0_SwitchLR)); - uint8 palette = is_x ? 3 : 7; - Hud_DrawBox(dst, x, 5, 20 - x, 19, palette); + int btn_index = GetCurrentItemButtonIndex(); + CopyTilesForSwitchLR(btn_index); + Hud_DrawBox(dst, x, 5, 20 - x, 19, kSwitchLR_palettes[btn_index]); + static const uint16 kEquipmentLetterTiles[4][2] = { + {0x3CF0, 0x3CF1}, // Y + {0x2CF0, 0x2CF0 | 0x8000}, // X + {0x200E | 4 << 10, 0x200F | 4 << 10}, // L + {0x200C | 4 << 10, 0x200D | 4 << 10} // R + }; if (!kNewStyleInventory) { - if (palette == 3) { - dst[HUDXY(2, 6)] = 0x2CF0; - dst[HUDXY(2, 7)] = 0x2CF0 | 0x8000; - } else { - dst[HUDXY(2, 6)] = 0x3CF0; - dst[HUDXY(2, 7)] = 0x3CF1; - } + dst[HUDXY(2, 6)] = kEquipmentLetterTiles[btn_index][0]; + dst[HUDXY(2, 7)] = kEquipmentLetterTiles[btn_index][1]; } dst[HUDXY(x + 2, 5)] = 0x246E; dst[HUDXY(x + 3, 5)] = 0x246F; @@ -1128,20 +1202,18 @@ void Hud_DrawSelectedYButtonItem() { // 8deb3a uint16 *dst_org = uvram_screen.row[0].col; uint16 *dst_box = dst_org + (kNewStyleInventory ? 1 : 0); - - bool is_x = (joypad1L_last & kJoypadL_X && (enhanced_features0 & kFeatures0_SwitchLR)); - uint8 palette = is_x ? 3 : 7; - Hud_DrawBox(dst_box, 21, 5, 21 + 9, 10, palette); + + int btn_index = GetCurrentItemButtonIndex(); + int item = *GetCurrentItemButtonPtr(btn_index); + Hud_DrawBox(dst_box, 21, 5, 21 + 9, 10, kSwitchLR_palettes[btn_index]); // Display either the current item or the item assigned - // to the x key. - int item = is_x ? hud_cur_item_x : hud_cur_item; - + // to the x, l, or r key. if (item != 0) { uint16 *p = dst_org + kHudItemInVramPtr[Hud_GetItemPosition(item)]; Hud_Copy2x2(dst_box + HUDXY(25, 6), p); if (timer_for_flashing_circle & 0x10) - Hud_DrawFlashingCircle(p, palette); + Hud_DrawFlashingCircle(p, kSwitchLR_palettes[btn_index]); } const uint16 *src_p; @@ -1160,7 +1232,7 @@ void Hud_DrawSelectedYButtonItem() { // 8deb3a } else if (item == kHudItem_Shovel) { src_p = &kHudItemText[(13 - 1) * 16]; } else if (item == 0) { - src_p = is_x ? kNotAssignedItemText : &kHudItemText[(20 - 1) * 16]; + src_p = btn_index ? kNotAssignedItemText : &kHudItemText[(20 - 1) * 16]; } else { src_p = &kHudItemText[(item - 1) * 16]; } @@ -1434,25 +1506,31 @@ const uint16 *Hud_GetItemBoxPtr(int item) { void Hud_HandleItemSwitchInputs() { if (!(enhanced_features0 & kFeatures0_SwitchLR)) return; - if (filtered_joypad_L & (kJoypadL_L | kJoypadL_R)) { - int old_item = hud_cur_item; - for (int i = 0; ; i++) { - if (i >= kHudItemCount) { - hud_cur_item = 0; - break; + + bool direction; + + if (filtered_joypad_L & kJoypadL_L && (hud_cur_item_l == 0)) + direction = false; + else if (filtered_joypad_L & kJoypadL_R && (hud_cur_item_r == 0)) + direction = true; + else + return; + + uint8 item = hud_cur_item; + for (int i = 0; i < kHudItemCount; i++) { + if (!direction) + Hud_GotoPrevItem(&item, 1); + else + Hud_GotoNextItem(&item, 1); + if (Hud_DoWeHaveThisItem(item)) { + if (item != hud_cur_item) { + hud_cur_item = item; + sound_effect_2 = 32; + Hud_UpdateEquippedItem(); + Hud_UpdateItemBox(); + flag_update_hud_in_nmi++; } - if (filtered_joypad_L & kJoypadL_L) - Hud_GotoPrevItem(&hud_cur_item, 1); - else - Hud_GotoNextItem(&hud_cur_item, 1); - if (Hud_DoWeHaveThisItem(hud_cur_item)) - break; - } - if (hud_cur_item != old_item) { - sound_effect_2 = 32; - Hud_UpdateEquippedItem(); - Hud_UpdateItemBox(); - flag_update_hud_in_nmi++; + break; } } } diff --git a/hud.h b/hud.h index 4bf7887..060a826 100644 --- a/hud.h +++ b/hud.h @@ -56,5 +56,7 @@ void Hud_RestoreTorchBackground(); void Hud_RebuildIndoor(); void Hud_Rebuild(); const uint16 *Hud_GetItemBoxPtr(int item); +int GetCurrentItemButtonIndex(); +uint8 *GetCurrentItemButtonPtr(int i); void Hud_HandleItemSwitchInputs(); diff --git a/player.c b/player.c index ea6e683..18666d3 100644 --- a/player.c +++ b/player.c @@ -1985,16 +1985,20 @@ void Link_HandleYItem() { // 879b0e } uint8 old_down = joypad1H_last, old_pressed = filtered_joypad_H, old_bottle = link_item_bottle_index; - if ((link_item_in_hand | link_position_mode) == 0) { - // Is X held down? - if (joypad1L_last & kJoypadL_X && !(old_down & kJoypadH_Y) && hud_cur_item_x != 0) { - - if (hud_cur_item_x >= kHudItem_Bottle1) - link_item_bottle_index = hud_cur_item_x - kHudItem_Bottle1 + 1; - item = Hud_LookupInventoryItem(hud_cur_item_x); - // Pretend it's actually Y that's down - joypad1H_last = old_down | kJoypadH_Y; - filtered_joypad_H = old_pressed | ((filtered_joypad_L & kJoypadL_X) ? kJoypadH_Y : 0); + if ((link_item_in_hand | link_position_mode) == 0 && !(old_down & kJoypadH_Y)) { + // Is any special key held down? + int btn_index = GetCurrentItemButtonIndex(); + if (btn_index != 0) { + uint8 *cur_item_ptr = GetCurrentItemButtonPtr(btn_index); + if (*cur_item_ptr) { + if (*cur_item_ptr >= kHudItem_Bottle1) + link_item_bottle_index = *cur_item_ptr - kHudItem_Bottle1 + 1; + item = Hud_LookupInventoryItem(*cur_item_ptr); + // Pretend it's actually Y that's down + joypad1H_last = old_down | kJoypadH_Y; + static const uint8 kButtonIndexKeys[4] = { 0, kJoypadL_X, kJoypadL_L, kJoypadL_R }; + filtered_joypad_H = old_pressed | ((filtered_joypad_L & kButtonIndexKeys[btn_index]) ? kJoypadH_Y : 0); + } } } diff --git a/zelda3.ini b/zelda3.ini index 078303a..d43667c 100644 --- a/zelda3.ini +++ b/zelda3.ini @@ -85,9 +85,11 @@ MSUVolume = 100% [Features] # Item switch on L/R. Also allows reordering of items in inventory by pressing Y+direction -# Hold X inside of the item selection screen to reassign the X key into a separate item slot. +# Hold X,L,or R inside of the item selection screen to reassign an item into a separate item slot. # When X is assigned to an item, the Select key is used to enter the map. Press Select inside # of the Start menu to see the old select options. +# When L is assigned an item, Item cycle will cease for the L button +# this also applies for the R button. ItemSwitchLR = 0 # Allow turning while dashing