Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,359 changes: 683 additions & 676 deletions ASM/build/asm_symbols.txt

Large diffs are not rendered by default.

Binary file modified ASM/build/bundle.o
Binary file not shown.
1,318 changes: 667 additions & 651 deletions ASM/build/c_symbols.txt

Large diffs are not rendered by default.

32 changes: 30 additions & 2 deletions ASM/c/file_icons.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "hud_colors.h"
#include "triforce.h"
#include "ocarina_buttons.h"
#include "save.h"

#define ICON_SIZE 0x0C
#define MUSIC_WIDTH 0x06
Expand Down Expand Up @@ -172,6 +173,7 @@ static const variable_tile_data_t variable_tile_positions[NUM_VARIABLE] = {
{0, {0x4E, 0x2A}}, // Strength
{0, {0x5A, 0x2A}}, // Scale
};
static bool bronze_scale_marker = false;

typedef struct {
colorRGB8_t color;
Expand Down Expand Up @@ -380,8 +382,9 @@ static void populate_child_trade(const z64_file_t* file, variable_tile_t* tile);
static void populate_adult_trade(const z64_file_t* file, variable_tile_t* tile);
static void populate_magic(const z64_file_t* file, variable_tile_t* tile);
static void populate_upgrade_equip(const z64_file_t* file, variable_tile_t* tile, uint8_t value, uint8_t max, uint8_t base_tile);
static void populate_upgrade_scale(const z64_file_t* file, variable_tile_t* tile, uint8_t value, uint8_t base_tile);

static void populate_variable(const z64_file_t* file, variable_tile_info_t* info) {
void populate_variable(const z64_file_t* file, variable_tile_info_t* info) {
variable_tile_t* tile = info->tiles;

populate_upgrade_item( file, tile++, Z64_SLOT_OCARINA, Z64_ITEM_FAIRY_OCARINA);
Expand All @@ -390,7 +393,8 @@ static void populate_variable(const z64_file_t* file, variable_tile_info_t* info
populate_adult_trade( file, tile++);
populate_magic( file, tile++);
populate_upgrade_equip(file, tile++, file->strength_upgrade, 3, Z64_ITEM_GORONS_BRACELET);
populate_upgrade_equip(file, tile++, file->diving_upgrade, 2, Z64_ITEM_SILVER_SCALE);
extended_savecontext_static_t* extended = &(((extended_sram_file_t*)file)->additional_save_data.extended);
populate_upgrade_scale(file, tile++, extended->extended_scale, Z64_ITEM_SILVER_SCALE);
}


Expand Down Expand Up @@ -519,6 +523,11 @@ static void draw_variable(z64_disp_buf_t* db, const variable_tile_info_t* info,
color = WHITE;
color.a = color_product(color.a, alpha);
}
if (bronze_scale_marker) {
sprite_load(db, &item_digit_sprite, 0, 1);
sprite_draw(db, &item_digit_sprite, 0, get_left(variable_tile_positions[NUM_VARIABLE - 1].pos) + 4,
get_top(variable_tile_positions[NUM_VARIABLE - 1].pos) + 3, 6, 6);
}
}


Expand Down Expand Up @@ -934,3 +943,22 @@ static void populate_upgrade_equip(const z64_file_t* file, variable_tile_t* tile
tile->tile_index = base_tile + (value - 1);
}
}

static void populate_upgrade_scale(const z64_file_t* file, variable_tile_t* tile, uint8_t value, uint8_t base_tile) {
tile->tile_index = base_tile;
bronze_scale_marker = false;
if (value == 0) {
bronze_scale_marker = true;
tile->enabled = 0;
}
if (value == 1) {
tile->enabled = 0;
}
if (value == 2) {
tile->enabled = 1;
}
if (value == 3) {
tile->enabled = 1;
tile->tile_index++;
}
}
32 changes: 32 additions & 0 deletions ASM/c/item_draw_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,38 @@ void draw_gi_magic_spells(z64_game_t* game, uint32_t draw_id) {
gSPDisplayList(gfx->poly_xlu.p++, item_draw_table[draw_id].args[1].dlist);
gSPDisplayList(gfx->poly_xlu.p++, item_draw_table[draw_id].args[2].dlist);
}
static Gfx gGiBronzeScaleWaterColorDL[] = {
gsDPPipeSync(),
gsDPSetPrimColor(0, 0x60, 255, 255, 255, 255),
gsDPSetEnvColor(255, 123, 0, 255),
gsSPEndDisplayList(),
};

static Gfx gGiBronzeScaleColorDL[] = {
gsDPPipeSync(),
gsDPSetPrimColor(0, 0x80, 255, 255, 255, 255),
gsDPSetEnvColor(91, 51, 18, 255),
gsSPEndDisplayList(),
};

void draw_bronze_scale(z64_game_t* game, uint32_t draw_id) {

z64_gfx_t* gfx = game->common.gfx;

append_setup_dl_25_to_xlu(gfx);
gSPSegment(gfx->poly_xlu.p++, 0x08,
gen_double_tile(gfx,
0, game->common.state_frames * 2, -(game->common.state_frames * 2), 64, 64,
1, game->common.state_frames * 4, -(game->common.state_frames * 4), 32, 32));


gSPMatrix(gfx->poly_xlu.p++, append_sys_matrix(gfx), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);

gSPDisplayList(gfx->poly_xlu.p++, (Gfx*)gGiBronzeScaleColorDL);
gSPDisplayList(gfx->poly_xlu.p++, item_draw_table[draw_id].args[3].dlist);
gSPDisplayList(gfx->poly_xlu.p++, (Gfx*)gGiBronzeScaleWaterColorDL);
gSPDisplayList(gfx->poly_xlu.p++, item_draw_table[draw_id].args[0].dlist);
}

void draw_gi_scales(z64_game_t* game, uint32_t draw_id) {
z64_gfx_t* gfx = game->common.gfx;
Expand Down
1 change: 1 addition & 0 deletions ASM/c/item_draw_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ void draw_gi_flame(z64_disp_buf_t* dl, z64_game_t *game, colorRGBA8_t prim, colo
void draw_gi_xlu_with_flame(z64_game_t *game, uint32_t draw_id);
void draw_gi_deku_nut_with_flame(z64_game_t* game, uint32_t draw_id);
void draw_ice_trap(z64_game_t* game, uint32_t draw_id);
void draw_bronze_scale(z64_game_t* game, uint32_t draw_id);

#endif
1 change: 1 addition & 0 deletions ASM/c/item_draw_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ item_draw_table_entry_t item_draw_table[] = {
[0xA1] = { draw_gi_deku_nut_with_flame, { 0x06000E90, 0xC0C0C0FF, 0xC0C0C0FF } }, // Deku Nut Upgrade w/ Smoke Effect
[0xA2] = { draw_gi_magic_meter, { 0x06000000, 0x06000CC0, 0x06000F08, 0x060014E8, 0x286428FF, 0x000000FF } }, // Magic Meter Scroll 2
[0xA3] = { draw_ice_trap, { 0x04034380 } }, // Ice trap
[0xA4] = { draw_bronze_scale, { 0x06000AA0, 0x06000A40, 0x06000A80, 0x06000CC8 } }, // Bronze scale
};

void base_draw_gi_model(z64_game_t* game, uint32_t draw_id) {
Expand Down
16 changes: 16 additions & 0 deletions ASM/c/item_effects.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,19 @@ void unlock_ocarina_note(z64_file_t* save, int16_t arg1, int16_t arg2) {
break;
}
}

void give_progressive_scale(z64_file_t* save, int16_t arg1, int16_t arg2) {
switch(arg1) {
case 0: // Bronze scale
extended_savectx.extended_scale = 1;
break;
case 1: // Silver scale
extended_savectx.extended_scale = 2;
save->diving_upgrade = 1;
break;
case 2: // Gold scale
extended_savectx.extended_scale = 3;
save->diving_upgrade = 2;
break;
}
}
1 change: 1 addition & 0 deletions ASM/c/item_effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void give_bombchus(z64_file_t* save, int16_t arg1, int16_t arg2);
void trade_quest_upgrade(z64_file_t* save, int16_t item_id, int16_t arg2);
extern uint8_t KEYRING_BOSSKEY_CONDITION;
void unlock_ocarina_note(z64_file_t* save, int16_t arg1, int16_t arg2);
void give_progressive_scale(z64_file_t* save, int16_t arg1, int16_t arg2);

typedef enum dungeon {
DEKU_ID = 0,
Expand Down
6 changes: 4 additions & 2 deletions ASM/c/item_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ item_row_t item_table[GI_RANDO_MAX] = {
[GI_BOMB_BAG_40] = ITEM_ROW(0x53, GILDED_CHEST, 0x4F, -1, 0x005A, 0x00BF, 0x1A, no_upgrade, no_effect, -1, -1, NULL), // Biggest Bomb Bag
[GI_SILVER_GAUNTLETS] = ITEM_ROW(0x53, GILDED_CHEST, 0x51, -1, 0x005B, 0x012D, 0x49, no_upgrade, no_effect, -1, -1, NULL), // Silver Gauntlets
[GI_GOLD_GAUNTLETS] = ITEM_ROW(0x53, GILDED_CHEST, 0x52, -1, 0x005C, 0x012D, 0x4A, no_upgrade, no_effect, -1, -1, NULL), // Golden Gauntlets
[GI_SCALE_SILVER] = ITEM_ROW(0x53, GILDED_CHEST, 0x53, -1, 0x00CD, 0x00DB, 0x2A, no_upgrade, no_effect, -1, -1, NULL), // Silver Scale
[GI_SCALE_GOLDEN] = ITEM_ROW(0x53, GILDED_CHEST, 0x54, -1, 0x00CE, 0x00DB, 0x2B, no_upgrade, no_effect, -1, -1, NULL), // Golden Scale
[GI_SCALE_SILVER] = ITEM_ROW(0x53, GILDED_CHEST, 0x53, -1, 0x00CD, 0x00DB, 0x2A, no_upgrade, give_progressive_scale, 1, -1, NULL), // Silver Scale
[GI_SCALE_GOLDEN] = ITEM_ROW(0x53, GILDED_CHEST, 0x54, -1, 0x00CE, 0x00DB, 0x2B, no_upgrade, give_progressive_scale, 2, -1, NULL), // Golden Scale
[GI_STONE_OF_AGONY] = ITEM_ROW(0x53, GILDED_CHEST, 0x6F, -1, 0x0068, 0x00C8, 0x21, no_upgrade, no_effect, -1, -1, NULL), // Stone of Agony
[GI_GERUDOS_CARD] = ITEM_ROW(0x53, GILDED_CHEST, 0x70, -1, 0x007B, 0x00D7, 0x24, no_upgrade, no_effect, -1, -1, NULL), // Gerudo Membership Card

Expand Down Expand Up @@ -347,6 +347,8 @@ item_row_t item_table[GI_RANDO_MAX] = {
[GI_WATER_MEDALLION] = ITEM_ROW(0x53, GILDED_CHEST, 0x41, -1, 0x003D, 0x01B1, 0x98, no_upgrade, give_quest_item, 2, -1, NULL), // Water Medallion
[GI_SHADOW_MEDALLION] = ITEM_ROW(0x53, GILDED_CHEST, 0x41, -1, 0x0041, 0x01B2, 0x99, no_upgrade, give_quest_item, 4, -1, NULL), // Shadow Medallion
[GI_SPIRIT_MEDALLION] = ITEM_ROW(0x53, GILDED_CHEST, 0x41, -1, 0x003F, 0x01B3, 0x9A, no_upgrade, give_quest_item, 3, -1, NULL), // Spirit Medallion

[GI_SCALE_BRONZE] = ITEM_ROW(0x53, GILDED_CHEST, 0x54, -1, 0x90B6, 0x00DB, 0xA5, no_upgrade, give_progressive_scale, 0, -1, NULL), // Golden Scale
};

/* Determine which message to display based on the number of silver rupees collected.
Expand Down
6 changes: 4 additions & 2 deletions ASM/c/item_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,10 +341,12 @@ typedef enum GetItemID {
/* 0x012E */ GI_SHADOW_MEDALLION,
/* 0x012F */ GI_SPIRIT_MEDALLION,

/* 0x0130 */ GI_RANDO_MAX
/* 0x0130 */ GI_SCALE_BRONZE, // Bronze Scale

/* 0x0131 */ GI_RANDO_MAX
} GetItemId;

_Static_assert(GI_RANDO_MAX == 0x0130, "Remember to update the comment and the assert for the value of GI_RANDO_MAX when adding new items");
_Static_assert(GI_RANDO_MAX == 0x0131, "Remember to update the comment and the assert for the value of GI_RANDO_MAX when adding new items");

typedef enum {
/* 0 */ BROWN_CHEST, // big default chest
Expand Down
8 changes: 5 additions & 3 deletions ASM/c/item_upgrades.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "get_items.h"
#include "item_table.h"
#include "save.h"
#include "z64.h"

extern uint32_t FREE_BOMBCHU_DROPS;
Expand All @@ -17,7 +18,7 @@ typedef struct {
uint8_t magic : 2; // 0 = no magic, 1 = single magic, 2 = double magic
uint8_t sticks : 2; // 0 = no sticks, 1 = 10, 2 = 20, 3 = 30
uint8_t nuts : 2; // 0 = no nuts, 1 = 20, 2 = 30, 3 = 40
uint8_t scale : 2; // 0 = no scale, 1 = silver scale, 2 = gold scale
uint8_t scale : 3; // 0 = no scale, 1 = bronze_scale, 2 = silver scale, 3 = gold scale
Comment thread
GSKirox marked this conversation as resolved.
uint8_t wallet : 2; // 0 = 99, 1 = 200, 2 = 500, 3 = 999
uint8_t slingshot : 2; // 0 = no slingshot, 1 = 30, 2 = 40, 3 = 50
uint8_t bow : 2; // 0 = no bow, 1 = 30, 2 = 40, 3 = 50
Expand Down Expand Up @@ -84,8 +85,9 @@ uint16_t wallet_upgrade(z64_file_t* save, override_t override) {
}

uint16_t scale_upgrade(z64_file_t* save, override_t override) {
switch ((override.value.base.player == PLAYER_ID || !MW_PROGRESSIVE_ITEMS_ENABLE) ? save->diving_upgrade : MW_PROGRESSIVE_ITEMS_STATE[override.value.base.player].scale) {
case 0: return GI_SCALE_SILVER; // Silver Scale
switch ((override.value.base.player == PLAYER_ID || !MW_PROGRESSIVE_ITEMS_ENABLE) ? extended_savectx.extended_scale : MW_PROGRESSIVE_ITEMS_STATE[override.value.base.player].scale) {
case 0: return GI_SCALE_BRONZE; // Bronze Scale
case 1: return GI_SCALE_SILVER; // Silver Scale
default: return GI_SCALE_GOLDEN; // Gold Scale
}
}
Expand Down
2 changes: 2 additions & 0 deletions ASM/c/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "debug.h"
#include "inputviewer.h"
#include "message.h"
#include "swim.h"

void Gameplay_InitSkybox(z64_game_t* globalCtx, int16_t skyboxId);

Expand Down Expand Up @@ -69,6 +70,7 @@ void after_game_state_update() {
}
close_rando_display_buffer();
give_sage_gifts();
manage_swim();
}

void before_skybox_init(z64_game_t* game, int16_t skyboxId) {
Expand Down
1 change: 1 addition & 0 deletions ASM/c/save.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ typedef struct {
bool collected_dungeon_rewards[8];
override_t incoming_queue[3];
uint8_t password[6];
uint8_t extended_scale;
} extended_savecontext_static_t __attribute__ ((aligned (8)));


Expand Down
95 changes: 95 additions & 0 deletions ASM/c/swim.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "swim.h"

RespawnByScene respawnsByScene[] = {
{ 0x1D9, { { -1455, -20, 1384 }, 28761 }}, // Hyrule Field to Zora River (in water)
{ 0x311, { { 5852, -20, 3725 }, -20025 }}, // Zora River to Hyrule Field (in water)
{ 0x4DA, { { 1978, -36, -855 }, -16384 }}, // Zora River to Lost Woods
{ 0x1DD, { { 4082, 860, -1018 }, -32768 }}, // Lost Woods to Zora River
{ 0x219, { { -3276, -1033, 2908 }, 11228 }}, // Gerudo Valley to Lake Hylia
{ 0x3D4, { { -2361, 0, 610 }, 32768 }}, // Ice Cavern to Zora Fountain
{ 0x21D, { { -955, -1306, 6768 }, -32768 }}, // Water Temple to Lake Hylia
{ 0x328, { { -109, 11, -9 }, -29131 }}, // Lake Hylia to Zora Domain
{ 0x560, { { -912, -1326, 3391 }, 0 }}, // Zora Domain to Lake Hylia
{ 0x10E, { { -1500, 150, 1600 }, 32768}}, // Sapphire cutscene to Zora Fountain
{ 0x1A5, { { -224, -51, -117 }, 16384}}, // Caught by Gerudos as child
{ 0x199, { { 4129, 920, -1384 }, 49152}}, // Zora River from top of waterfall
{ 0x1FD, { { 0, 0, 1200 }, 0}}, // Hyrule Field from Market
};

void set_new_respawn() {
int32_t currentEntranceIndex = z64_game.entrance_index;
for (uint8_t i = 0; i < 13; i++) {
// Ensure we always respawn at a safe location.
if (currentEntranceIndex == respawnsByScene[i].scene_index) {
z64_Play_SetupRespawnPoint(&z64_game, 0x01, 0xDFF);
z64_file.respawn[RESPAWN_MODE_RETURN].pos = respawnsByScene[i].respawnInfo.pos;
z64_file.respawn[RESPAWN_MODE_RETURN].yaw = respawnsByScene[i].respawnInfo.yaw;
z64_file.respawn_flag = 2;
z64_game.scene_load_flag = 0x14;
return;
}
}

// Special case for Water Temple river area, so that player respawns at the start of the room.
if (z64_game.scene_index == 5 && z64_game.room_index == 21) {
z64_Play_SetupRespawnPoint(&z64_game, 0x01, 0xDFF);
z64_xyzf_t riverPos = {-3063, 380, -4066};
z64_file.respawn[RESPAWN_MODE_RETURN].pos = riverPos;
z64_file.respawn[RESPAWN_MODE_RETURN].yaw = 9010;
z64_file.respawn_flag = 2;
z64_game.scene_load_flag = 0x14;
return;
}

// Bottom of the Well respawn in the main room, mostly for advanced/no logic to avoid having to do the difficult glitch at the start if you fall into water.
if (z64_game.scene_index == 8) {
z64_Play_SetupRespawnPoint(&z64_game, 0x01, 0xDFF);
z64_xyzf_t botwPos = { 0, -12, 117 };
z64_file.respawn[RESPAWN_MODE_RETURN].pos = botwPos;
z64_file.respawn[RESPAWN_MODE_RETURN].yaw = 32768;
z64_file.respawn_flag = 2;
z64_game.scene_load_flag = 0x14;
return;
}

// Zoras river near waterfall, to have mercy if jumping for the rupees as adult.
if (z64_game.scene_index == 84 && z64_link.common.pos_world.x > 3800) {
z64_Play_SetupRespawnPoint(&z64_game, 0x01, 0xDFF);
z64_xyzf_t riverPos = { 4129, 920, -1384 };
z64_file.respawn[RESPAWN_MODE_RETURN].pos = riverPos;
z64_file.respawn[RESPAWN_MODE_RETURN].yaw = 49152;
z64_file.respawn_flag = 2;
z64_game.scene_load_flag = 0x14;
return;
}

// Normal case, just respawn at the last entrance.
z64_game.entrance_index = z64_file.entrance_index;
z64_game.fadeout_transition = 0x02;
z64_file.respawn_flag = -2;
z64_game.scene_load_flag = 0x14;
}

void manage_swim() {
// We found the first scale.
if (extended_savectx.extended_scale > 0) {
return;
}

// Iron boots are equipped.
if (z64_file.equip_boots == 2) {
return;
}

// Always allow to swim out of water temple to avoid softlocks.
if (z64_game.scene_index == 5 &&
z64_game.room_index == 0 &&
z64_link.common.pos_world.z > 700.0) {
return;
}

if (z64_link.state_flags_1 & 0x08000000) { // Swimming state flag.
PlaySFX(0x28CD); // NA_SE_EV_WATER_CONVECTION
set_new_respawn();
}
}
19 changes: 19 additions & 0 deletions ASM/c/swim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef SWIM_H
#define SWIM_H

#include "z64.h"
#include "save.h"

typedef struct {
/* 0x00 */ z64_xyzf_t pos;
/* 0x0C */ uint16_t yaw;
} SpecialRespawnInfo; // size = 0x10

typedef struct {
int32_t scene_index;
SpecialRespawnInfo respawnInfo;
} RespawnByScene;

void manage_swim();

#endif
2 changes: 1 addition & 1 deletion ASM/src/coop_state.asm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
COOP_CONTEXT:

COOP_VERSION:
.word 7 ; Increment this if layout of co-op state changes
.word 8 ; Increment this if layout of co-op state changes

PLAYER_ID:
.byte 0x00 ; Written by frontend
Expand Down
6 changes: 4 additions & 2 deletions ItemList.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,9 @@ class GetItemId(IntEnum):
GI_SHADOW_MEDALLION = 0x012E
GI_SPIRIT_MEDALLION = 0x012F

GI_RANDO_MAX = 0x0130
GI_SCALE_BRONZE = 0x0130

GI_RANDO_MAX = 0x0131

# Progressive: True -> Advancement
# False -> Priority
Expand Down Expand Up @@ -423,7 +425,7 @@ class GetItemId(IntEnum):
'Bow': ('Item', True, GetItemId.GI_PROGRESSIVE_BOW, None),
'Slingshot': ('Item', True, GetItemId.GI_PROGRESSIVE_SLINGSHOT, None),
'Progressive Wallet': ('Item', True, GetItemId.GI_PROGRESSIVE_WALLET, {'progressive': 3}),
'Progressive Scale': ('Item', True, GetItemId.GI_PROGRESSIVE_SCALE, {'progressive': 2}),
'Progressive Scale': ('Item', True, GetItemId.GI_PROGRESSIVE_SCALE, {'progressive': 3}),
'Deku Nut Capacity': ('Item', None, GetItemId.GI_PROGRESSIVE_NUT_CAPACITY, None),
'Deku Stick Capacity': ('Item', None, GetItemId.GI_PROGRESSIVE_STICK_CAPACITY, None),
'Bombchus': ('Item', True, GetItemId.GI_PROGRESSIVE_BOMBCHUS, None),
Expand Down
Loading