ref: c9c6843f7d74f3c448f623e58b5364cf73bd0eb9
parent: 825f449e5860ac0e8b617afa0535d529d968470d
author: xander-haj <[email protected]>
date: Thu Oct 27 15:23:39 EDT 2022
Can now assign items to L and R (#171)
--- a/features.h
+++ b/features.h
@@ -48,8 +48,10 @@
#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))
--- a/hud.c
+++ b/hud.c
@@ -594,6 +594,21 @@
} 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 @@
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 @@
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 @@
uint16 *dst_org = uvram_screen.row[0].col;
uint16 *dst_box = dst_org + (kNewStyleInventory ? 1 : 0);
+
+ int btn_index = GetCurrentItemButtonIndex();
+ int item = *GetCurrentItemButtonPtr(btn_index);
+ Hud_DrawBox(dst_box, 21, 5, 21 + 9, 10, kSwitchLR_palettes[btn_index]);
- 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);
-
// 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 @@
} 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 @@
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;
}
}
}
--- a/hud.h
+++ b/hud.h
@@ -56,5 +56,7 @@
void Hud_RebuildIndoor();
void Hud_Rebuild();
const uint16 *Hud_GetItemBoxPtr(int item);
+int GetCurrentItemButtonIndex();
+uint8 *GetCurrentItemButtonPtr(int i);
void Hud_HandleItemSwitchInputs();
--- a/player.c
+++ b/player.c
@@ -1985,16 +1985,20 @@
}
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);
+ }
}
}
--- a/zelda3.ini
+++ b/zelda3.ini
@@ -85,9 +85,11 @@
[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