5 Commits

Author SHA1 Message Date
e11a5bd96a Fix credits spacing 2025-01-01 14:58:55 -06:00
Lexi Rose
71ae68db77 Merge pull request #221 from aerinon/SancAndQuitFix
fix: sanc & quit fix
2024-10-25 14:16:06 -05:00
aerinon
fb35c96e11 fix: sanc & quit fix 2024-10-25 12:45:44 -06:00
Lexi Rose
758449b7b9 Merge pull request #220 from spannerisms/real
tourney stuff
2024-10-11 09:18:05 -07:00
spannerisms
27a19ce299 tourney stuff 2024-10-10 23:33:20 -04:00
172 changed files with 4686 additions and 20377 deletions

5
.gitignore vendored
View File

@@ -1,6 +1,3 @@
tournament.asm
/build
/.idea
/__pycache__
/.vscode
build.sh
/.idea

View File

@@ -34,7 +34,7 @@ db $20, $19, $08, $31 ; year/month/day
;================================================================================
!ROM_VERSION_LOW ?= 1 ; ROM version (two 16-bit integers)
!ROM_VERSION_HIGH ?= 5 ;
!ROM_VERSION_HIGH ?= 4 ;
org $80FFE0 ; Unused hardware vector
RomVersion:
@@ -50,31 +50,9 @@ dw !ROM_VERSION_HIGH
function hexto555(h) = ((((h&$FF)/8)<<10)|(((h>>8&$FF)/8)<<5)|(((h>>16&$FF)/8)<<0))
; Feature flags, run asar with -DFEATURE_X=1 to enable
!FEATURE_FIX_BASEROM ?= 0
;================================================================================
!MULTIWORLD_ITEM = "$7EF4D2"
!MULTIWORLD_ITEM_FROM = "$7EF4D3"
!MULTIWORLD_ROOMID = "$7EF4D4"
!MULTIWORLD_ROOMDATA = "$7EF4D6"
!MULTIWORLD_SCOUT_LOCATION = "$7EF4D7"
!MULTIWORLD_SCOUTREPLY_LOCATION = "$7EF4D8"
!MULTIWORLD_SCOUTREPLY_ITEM = "$7EF4D9"
!MULTIWORLD_SCOUTREPLY_PLAYER = "$7EF4DA"
!MULTIWORLD_RECEIVING_ITEM = "$7EC057" ; 0 = default | 1 = receiving
!MULTIWORLD_HUD_CHARACTER_DATA = "$7EC058" ; 0x40 bytes
!MULTIWORLD_ITEM_PLAYER_ID = "$7EC098" ; 0 = disabled
!MULTIWORLD_SPRITEITEM_PLAYER_ID = "$7EC099"
!MULTIWORLD_HUD_TIMER = "$7EC09A"
!MULTIWORLD_HUD_DELAY = "#120"
!MULTIWORLD_ITEM_ID = "$7EC09B" ; for lua scripts?
!Dungeon_ChestData = "$01E96C"
!FLAG_OW_MIXED = $04
!FLAG_OW_CROSSED = $02
!FLAG_OW_BONKDROP = $02
incsrc hooks.asm
incsrc spriteswap.asm
incsrc hashalphabethooks.asm
@@ -83,6 +61,7 @@ incsrc ram.asm
incsrc sram.asm
incsrc registers.asm
incsrc vanillalabels.asm
incsrc overworldmap.asm ; Overwrites some code in bank $8A
org $A08000 ; bank $20
incsrc itemdowngrade.asm
@@ -119,7 +98,6 @@ incsrc doorframefixes.asm
incsrc music.asm
incsrc roomloading.asm
incsrc icepalacegraphics.asm
incsrc follower.asm
warnpc $A18000
org $9C8000 ; text tables for translation
@@ -166,22 +144,18 @@ incsrc decryption.asm
incsrc hashalphabet.asm
incsrc inverted.asm
incsrc invertedmaps.asm
incsrc invertedmaps2.asm
incsrc bonktreemaps.asm
incsrc newhud.asm
incsrc save.asm
incsrc password.asm
incsrc enemy_adjustments.asm
;incsrc hudtext.asm
incsrc hudtext.asm
incsrc servicerequest.asm
incsrc elder.asm
incsrc toast.asm
incsrc fastcredits.asm
incsrc msu.asm
incsrc menu/overworldmap.asm ; Overwrites some code in bank $8A
incsrc dungeonmap.asm
incsrc hextodec.asm
incsrc multiworld.asm
incsrc textrenderer.asm
warnpc $A58000
@@ -190,8 +164,6 @@ ItemReceiptGraphicsROM:
; we need some empty space here so that 0000 can mean nothing
fillbyte $00 : fill 32
incbin "data/customitems.4bpp"
PreloadedGraphicsROM:
incbin "data/preloadedgfx.4bpp"
warnpc $A2B000
org $A2B000
incsrc itemdatatables.asm ; Statically mapped
@@ -199,17 +171,6 @@ incsrc decompresseditemgraphics.asm
incsrc newitems.asm
incsrc utilities.asm
incsrc inventory.asm
incsrc menu/hudalpha.asm
warnpc $A38000
org $B98000
incsrc crystalswitchbook.asm
incsrc mimicdash.asm
incsrc gloom.asm
incsrc special_weapons.asm
incsrc variable_ganon_vulnerability.asm
incsrc pseudoflute.asm
warnpc $BA8000
org $A38000
incsrc stats/credits.asm ; Statically mapped
@@ -218,15 +179,8 @@ incsrc stats/statConfig.asm
FontTable:
incsrc stats/fonttable.asm
incsrc doorrando/doorrando.asm ; bank 27/A7
;bank 28/A8 for keydropshuffle / standing items
incsrc keydrop/standing_items.asm ; bank 28/A8
incsrc owrando.asm ; bank 2A/AA
incsrc enemizer/main.asm ; bank 36/B6
org $B08000 ; bank #$30
org $B08000 ; bank $30
incsrc tables.asm
warnpc $B18000
org $B48000
incsrc spc.asm
@@ -253,7 +207,7 @@ warnpc $B1A000
org $B1A000
GFX_HUD_Items:
incbin "menu/drsheetdc.2bppc"
incbin "data/c2807_v4.gfx"
warnpc $B1A800
org $B1A800
@@ -317,11 +271,6 @@ incsrc data/kanjireplacements.asm ; Overwrites text gfx data and masks in bank $
org $B28000
Extra_Text_Table:
incsrc itemtext.asm
warnpc $B2E000
org $B2DFD0 ; PC 0x195FD0
incsrc multiworldplayernames.asm
warnpc $B30000
incsrc externalhooks.asm
;================================================================================
@@ -349,12 +298,7 @@ warnpc $B08000
;$22 Unused
;$23 Stats & Credits
;$24 Code Bank
;$26 Multiworld data
;$27 DR Code Bank
;$28 Keydrop / Standing Items Code bank
;$29 External hooks (rest of bank not used)
;$2A Reserved for OWR
;$2B Reserved for "outlet data" ~5.8k
;$2E Reserved for Tournament Use
;$2F Static RNG (rest is reserved for tournament use)
;$30 Main Configuration Table
@@ -362,8 +306,6 @@ warnpc $B08000
;$32 Text Bank
;$33 Graphics Bank
;$36 reserved for Enemizer
;$37 Room data if needed for DR/Pottery/Enemizer
;$39 GwaaKiwi Code Bank
;$3A reserved for downstream use
;$3B reserved for downstream use
;$3F reserved for internal debugging

View File

@@ -1,15 +0,0 @@
# z3randomizer
Zelda 3 Randomizer Template ASM
How to create the bps patch:
* Assemble the ROM with asar (recommend to use a copy of original rom)
`asar LTTP_RND_GeneralBugfixes.asm copy_original_rom.sfc`
(copy_orignal_rom.sfc is now assembled_rom.sfc)
* Use flips to create a bps file
`flips original_rom.sfc assembled_rom.sfc base2current.bps`
* Update RANDOMIZERBASEHASH in DR with the md5 sum of assembled_rom.sfc. And put base2current.bps in the data directory.

View File

@@ -153,7 +153,7 @@ RestoreBgEther:
INX #2 : CPX.b #$10 : BNE -
BRA ++
++
JML Palette_RestoreFixedColor-7 ; Bank0E.asm : 3936 vanilla restore routine after loop which RTLs
JML $82FF51 ; Bank0E.asm : 3936 vanilla restore routine after loop which RTLs
;================================================================================
DDMConditionalLightning:
LDA.l DisableFlashing
@@ -161,7 +161,7 @@ DDMConditionalLightning:
BNE +
LDA.w Scrap
LDX.b #$02
JML FlashGanonTowerPalette_next_thunder-2 ; Bank0E.asm : 4738 vanilla loop equivalent to below beginning at LDY #$00
JML $87FA7F ; Bank0E.asm : 4738 vanilla loop equivalent to below beginning at LDY #$00
+
LDA.b Scrap00 : LDX.b #$02 : LDY.b #$00
-
@@ -172,7 +172,7 @@ DDMConditionalLightning:
LDA.w $F523, Y : LDA.l PaletteBuffer+$F0, X
INY #2
INX #2 : CPX.b #$10 : BNE -
JML FlashGanonTowerPalette_bright_white ; Bank0E.asm : 4754 both branches converge here
JML $87FAAC ; Bank0E.asm : 4754 both branches converge here
;================================================================================
ConditionalGTFlash:
LDA.l DisableFlashing : REP #$20 : BNE +
@@ -222,17 +222,17 @@ LoadElectroPalette:
LDA.w #$0404 : STA.b Scrap0E
LDA.w #$001B : STA.b Scrap02
SEP #$10
LDX.b Scrap0C : LDA.l SwordPaletteOffsets, X : AND.w #$00FF : ADC.w #$D630
LDX.b Scrap0C : LDA.l $9BEBB4, X : AND.w #$00FF : ADC.w #$D630
REP #$10 : LDX.w #$01B2 : LDY.w #$0002
JSR ConditionalLoadGearPalette
SEP #$10
LDX.b Scrap0D
LDA.l ShieldPaletteOffsets, X : AND.w #$00FF : ADC.w #$D648
LDA.l $9BEBC1, X : AND.w #$00FF : ADC.w #$D648
REP #$10 : LDX.w #$01B8 : LDY.w #$0003
JSR ConditionalLoadGearPalette
SEP #$10
LDX.b Scrap0E
LDA.l LinkMailPalettesOffsets, X : AND.w #$00FF : ASL A : ADC.w #$D308
LDA.l $9BEC06, X : AND.w #$00FF : ASL A : ADC.w #$D308
REP #$10 : LDX.w #$01E2 : LDY.w #$000E
JSR ConditionalLoadGearPalette
SEP #$30

Binary file not shown.

BIN
asar.dll

Binary file not shown.

421
asar.py
View File

@@ -1,421 +0,0 @@
#!/usr/bin/env python3
"""
python interface for asar.dll
by randomdude999
Usage: import asar, call asar.init, call asar.patch, then use the various
functions to get info about the patch
"""
import ctypes
import enum
import sys
from ctypes import c_int, c_char_p, POINTER
c_int_ptr = POINTER(c_int)
__all__ = ["errordata", "writtenblockdata", "mappertype", "version",
"apiversion", "init", "reset", "patch", "maxromsize", "close",
"geterrors", "getwarnings", "getprints", "getalllabels",
"getlabelval", "getdefine", "getalldefines", "resolvedefines",
"math", "getwrittenblocks", "getmapper", "getsymbolsfile"]
_target_api_ver = 303
_asar = None
class AsarArithmeticError(ArithmeticError):
pass
class errordata(ctypes.Structure):
_fields_ = [("fullerrdata", c_char_p),
("rawerrdata", c_char_p),
("block", c_char_p),
("filename", c_char_p),
("line", c_int),
("callerfilename", c_char_p),
("callerline", c_int),
("errid", c_int)]
def __repr__(self):
return "<asar error: {!r}>".format(self.fullerrdata.decode())
# for internal use only. getalllabels() returns a dict.
class _labeldata(ctypes.Structure):
_fields_ = [("name", c_char_p),
("location", c_int)]
# for internal use only. getalldefines() returns a dict.
class _definedata(ctypes.Structure):
_fields_ = [("name", c_char_p),
("contents", c_char_p)]
class writtenblockdata(ctypes.Structure):
_fields_ = [("pcoffset", c_int),
("snesoffset", c_int),
("numbytes", c_int)]
def __repr__(self):
return "<written block ${:06x} 0x{:x} size:{}>".format(
self.snesoffset, self.pcoffset, self.numbytes)
# internal use only. patch() accepts a dict.
class _memoryfile(ctypes.Structure):
_fields_ = [("path", c_char_p),
("buffer", c_char_p),
("length", ctypes.c_size_t)]
# internal use only. patch() accepts a dict.
class _warnsetting(ctypes.Structure):
_fields_ = [("warnid", c_char_p),
("enabled", ctypes.c_bool)]
# For internal use only.
class _patchparams(ctypes.Structure):
_fields_ = [("structsize", c_int),
("patchloc", c_char_p),
("romdata", c_char_p),
("buflen", c_int),
("romlen", c_int_ptr),
("includepaths", POINTER(c_char_p)),
("numincludepaths", c_int),
("should_reset", ctypes.c_bool),
("additional_defines", POINTER(_definedata)),
("additional_define_count", c_int),
("stdincludesfile", c_char_p),
("stddefinesfile", c_char_p),
("warning_settings", POINTER(_warnsetting)),
("warning_setting_count", c_int),
("memory_files", POINTER(_memoryfile)),
("memory_file_count", c_int),
("override_checksum_gen", ctypes.c_bool),
("generate_checksum", ctypes.c_bool)]
class mappertype(enum.Enum):
invalid_mapper = 0
lorom = 1
hirom = 2
sa1rom = 3
bigsa1rom = 4
sfxrom = 5
exlorom = 6
exhirom = 7
norom = 8
def _getall(func):
"""Helper that does the work common to all the getall* functions."""
count = c_int()
raw_errs = func(ctypes.byref(count))
errs = []
for i in range(count.value):
errs.append(raw_errs[i])
return errs
class _AsarDLL:
def __init__(self, dllname):
dll = ctypes.CDLL(dllname)
self.dll = dll
self.funcs = {}
try:
# argument/return type setup
# (also verifies that those functions are exported from the DLL)
# this is directly from asardll.h
# setup_func(name, argtypes, returntype)
self.setup_func("version", (), c_int)
self.setup_func("apiversion", (), c_int)
self.setup_func("init", (), ctypes.c_bool)
self.setup_func("reset", (), ctypes.c_bool)
self.setup_func("patch", (c_char_p, c_char_p, c_int, c_int_ptr),
ctypes.c_bool)
self.setup_func("patch_ex", (POINTER(_patchparams),), ctypes.c_bool)
self.setup_func("maxromsize", (), c_int)
self.setup_func("close", (), None)
self.setup_func("geterrors", (c_int_ptr,), POINTER(errordata))
self.setup_func("getwarnings", (c_int_ptr,), POINTER(errordata))
self.setup_func("getprints", (c_int_ptr,), POINTER(c_char_p))
self.setup_func("getalllabels", (c_int_ptr,), POINTER(_labeldata))
self.setup_func("getlabelval", (c_char_p,), c_int)
self.setup_func("getdefine", (c_char_p,), c_char_p)
self.setup_func("getalldefines", (c_int_ptr,), POINTER(_definedata))
self.setup_func("resolvedefines", (c_char_p, ctypes.c_bool),
c_char_p)
self.setup_func("math", (c_char_p, POINTER(c_char_p)),
ctypes.c_double)
self.setup_func("getwrittenblocks", (c_int_ptr,),
POINTER(writtenblockdata))
self.setup_func("getmapper", (), c_int)
self.setup_func("getsymbolsfile", (c_char_p,), c_char_p)
except AttributeError:
raise OSError("Asar DLL is missing some functions")
api_ver = dll.asar_apiversion()
if api_ver < _target_api_ver or \
(api_ver // 100) > (_target_api_ver // 100):
raise OSError("Asar DLL version "+str(api_ver)+" unsupported")
def setup_func(self, name, argtypes, restype):
"""Setup argument and return types for a function.
name: name of the function in the DLL. "asar_" is added automatically
argtypes and restype: see ctypes documentation
"""
func = getattr(self.dll, "asar_" + name)
func.argtypes = argtypes
func.restype = restype
def init(dll_path=None):
"""Load the Asar DLL.
You must call this before calling any other Asar functions. Raises OSError
if there was something wrong with the DLL (not found, wrong version,
doesn't have all necessary functions).
You can pass a custom DLL path if you want. If you don't, some common names
for the asar dll are tried.
"""
global _asar
if _asar is not None:
return
if dll_path is not None:
_asar = _AsarDLL(dll_path)
else:
if sys.platform == "win32":
libnames = ["./asar.dll", "asar", "./asar-x64.dll", "asar-x64"]
elif sys.platform == "darwin":
libnames = ["./libasar.dylib", "libasar"]
else:
libnames = ["./libasar.so", "libasar"]
for x in libnames:
try:
_asar = _AsarDLL(x)
except OSError:
continue
if _asar is None:
# Nothing in the search path is valid
raise OSError("Could not find asar DLL")
if not _asar.dll.asar_init():
_asar = None
return False
else:
return True
def close():
"""Free all of Asar's structures and unload the module.
Only asar.init() may be called after calling this.
"""
global _asar
if _asar is None:
return
_asar.dll.asar_close()
_asar = None
def version():
"""Return the version, in the format major*10000+minor*100+bugfix*1.
This means that 1.2.34 would be returned as 10234.
"""
return _asar.dll.asar_version()
def apiversion():
"""Return the API version, in the format major*100+minor.
Minor is incremented on backwards compatible changes; major is incremented
on incompatible changes. Does not have any correlation with the Asar
version. It's not very useful directly, since asar.init() verifies this
automatically.
"""
return _asar.dll.asar_apiversion()
def reset():
"""Clear out errors, warnings, printed statements and the file cache.
Not really useful, since asar.patch() already does this.
"""
return _asar.dll.asar_reset()
def patch(patch_name, rom_data, includepaths=[], should_reset=True,
additional_defines={}, std_include_file=None, std_define_file=None,
warning_overrides={}, memory_files={}, override_checksum=None):
"""Applies a patch.
Returns (success, new_rom_data). If success is False you should call
geterrors() to see what went wrong. rom_data is assumed to be headerless.
If includepaths is specified, it lists additional include paths for asar
to search.
should_reset specifies whether asar should clear out all defines, labels,
etc from the last inserted file. Setting it to False will make Asar act
like the currently patched file was directly appended to the previous one.
additional_defines specifies extra defines to give to the patch
(similar to the -D option).
std_include_file and std_define_file specify files where to look for extra
include paths and defines, respectively.
warning_overrides is a dict of str (warning ID) -> bool. It overrides
enabling/disabling specific warnings.
memory_files is a dict of str (file name) -> bytes (file contents). It
specifies memory files to use.
override_checksum specifies whether to override checksum generation. True
forces Asar to update the ROM's checksum, False forces Asar to not update
it.
"""
romlen = c_int(len(rom_data))
rom_ptr = ctypes.create_string_buffer(bytes(rom_data), maxromsize())
pp = _patchparams()
pp.structsize = ctypes.sizeof(_patchparams)
pp.patchloc = patch_name.encode()
pp.romdata = ctypes.cast(rom_ptr, c_char_p)
pp.buflen = maxromsize()
pp.romlen = ctypes.pointer(romlen)
# construct an array type of len(includepaths) elements and initialize
# it with elements from includepaths
pp.includepaths = (c_char_p*len(includepaths))(*includepaths)
pp.numincludepaths = len(includepaths)
defines = (_definedata * len(additional_defines))()
for i, (k, v) in enumerate(additional_defines.items()):
defines[i].name = k.encode()
defines[i].contents = v.encode()
pp.additional_defines = defines
pp.additional_define_count = len(additional_defines)
pp.should_reset = should_reset
pp.stdincludesfile = std_include_file.encode() if std_include_file else None
pp.stddefinesfile = std_define_file.encode() if std_define_file else None
warnsettings = (_warnsetting * len(warning_overrides))()
for i, (k, v) in enumerate(warning_overrides.items()):
warnsettings[i].warnid = k.encode()
warnsettings[i].enabled = v
pp.warning_settings = warnsettings
pp.warning_setting_count = len(warnsettings)
memoryfiles = (_memoryfile * len(memory_files))()
for i, (k, v) in enumerate(memory_files.items()):
memoryfiles[i].path = k.encode()
memoryfiles[i].buffer = v
memoryfiles[i].length = len(v)
pp.memory_files = memoryfiles
pp.memory_file_count = len(memory_files)
if override_checksum is not None:
pp.override_checksum_gen = True
pp.generate_checksum = override_checksum
else:
pp.override_checksum_gen = False
pp.generate_checksum = False
result = _asar.dll.asar_patch_ex(ctypes.byref(pp))
return result, rom_ptr.raw[:romlen.value]
def maxromsize():
"""Return the maximum possible size of the output ROM."""
return _asar.dll.asar_maxromsize()
def geterrors():
"""Get a list of all errors."""
return _getall(_asar.dll.asar_geterrors)
def getwarnings():
"""Get a list of all warnings."""
return _getall(_asar.dll.asar_getwarnings)
def getprints():
"""Get a list of all printed data."""
return [x.decode() for x in _getall(_asar.dll.asar_getprints)]
def getalllabels():
"""Get a dictionary of label name -> SNES address."""
labeldatas = _getall(_asar.dll.asar_getalllabels)
return {x.name.decode(): x.location for x in labeldatas}
def getlabelval(name):
"""Get the ROM location of one label. None means "not found"."""
val = _asar.dll.asar_getlabelval(name.encode())
return None if (val == -1) else val
def getdefine(name):
"""Get the value of a define."""
return _asar.dll.asar_getdefine(name.encode()).decode()
def getalldefines():
"""Get the names and values of all defines."""
definedatas = _getall(_asar.dll.asar_getalldefines)
return {x.name.decode(): x.contents.decode() for x in definedatas}
def resolvedefines(data, learnnew):
"""Parse all defines in the given data.
Returns the data with all defines evaluated.
learnnew controls whether it'll learn new defines in this string if it
finds any. Note that it may emit errors.
"""
return _asar.dll.asar_resolvedefines(data, learnnew)
def math(to_calculate):
"""Parse a string containing math.
It automatically assumes global scope (no namespaces), and has access to
all functions and labels from the last call to asar.patch(). If there was
an error, ArithmeticError is raised with the message returned by Asar.
"""
error = ctypes.c_char_p()
result = _asar.dll.asar_math(to_calculate.encode(), ctypes.byref(error))
if not bool(error):
# Null pointer, means no error
return result
else:
raise AsarArithmeticError(error.value.decode())
def getwrittenblocks():
"""Get a list of all the blocks written to the ROM."""
return _getall(_asar.dll.asar_getwrittenblocks)
def getmapper():
"""Get the ROM mapper currently used by Asar."""
return mappertype(_asar.dll.asar_getmapper())
def getsymbolsfile(fmt="wla"):
"""Generates the contents of a symbols file for in a specific format.
Returns the textual contents of the symbols file.
format specified the format of the symbols file that gets generated.
"""
return _asar.dll.asar_getsymbolsfile(fmt.encode()).decode()

0
bin/linux/asar Normal file → Executable file
View File

Binary file not shown.

Binary file not shown.

0
bin/macos/asar Normal file → Executable file
View File

View File

@@ -1,249 +0,0 @@
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/stat.h>
const int MAXLENGTH = 0x300;
struct section {
int mode;
int length;
unsigned char data[2];
int datalength;
};
int find_duplicate(off_t loc, off_t size, unsigned char buf[], struct section *out) {
int i, j;
struct section result;
result.mode = 4;
result.length = 0;
for (i = 0; i < loc && i < 0x10000; i++) {
if (buf[i] != buf[loc]) {
continue;
}
for (j = 0; j < MAXLENGTH; j++) {
if (buf[i + j] != buf[loc + j]) {
break;
}
}
if (j > result.length) {
result.length = j;
result.data[0] = i & 0xFF;
result.data[1] = (i >> 8) & 0xFF;
result.datalength = 2;
}
}
if (result.length < 4) {
return -1;
}
*out = result;
return 0;
}
int find_repeat_byte(off_t loc, off_t size, unsigned char buf[], struct section *out) {
int i;
for (i = 0; i < MAXLENGTH && loc + i < size; i++) {
if (buf[loc + i] != buf[loc]) {
break;
}
}
if (i > 2) {
struct section result;
result.mode = 1;
result.length = i;
result.data[0] = buf[loc];
result.datalength = 1;
*out = result;
return 0;
}
return -1;
}
int find_repeat_word(off_t loc, off_t size, unsigned char buf[], struct section *out) {
int i;
for (i = 0; i < MAXLENGTH && loc + i + 1 < size; i += 1) {
if (buf[loc + i] != buf[loc + (i & 1)]) {
break;
}
}
if (i > 3) {
struct section result;
result.mode = 2;
result.length = i;
result.data[0] = buf[loc];
result.data[1] = buf[loc + 1];
result.datalength = 2;
*out = result;
return 0;
}
return -1;
}
int find_incrementing_byte(off_t loc, off_t size, unsigned char buf[], struct section *out) {
int i;
for (i = 0; i < MAXLENGTH && loc + i < size; i++) {
if (buf[loc] + i < i) {
break;
}
if (buf[loc + i] != buf[loc] + i) {
break;
}
}
if (i > 2) {
struct section result;
result.mode = 3;
result.length = i;
result.data[0] = buf[loc];
result.datalength = 1;
*out = result;
return 0;
}
return -1;
}
int get_section(off_t loc, off_t size, unsigned char buf[], struct section *out) {
struct section best, current;
best.length = 0;
if (!find_repeat_byte(loc, size, buf, &current)) {
if (current.length > best.length) {
best = current;
}
}
if (!find_repeat_word(loc, size, buf, &current)) {
if (current.length > best.length) {
best = current;
}
}
if (!find_incrementing_byte(loc, size, buf, &current)) {
if (current.length > best.length) {
best = current;
}
}
if (!find_duplicate(loc, size, buf, &current)) {
if (current.length > best.length) {
best = current;
}
}
if (best.length > 0) {
// printf("byte %06X: mode %d length %02X\n", loc, best.mode, best.length);
*out = best;
return 0;
} else {
return -1;
}
}
int write_section(struct section section, unsigned char data[], unsigned char buf[], int loc) {
int nloc = loc;
int len = section.length - 1;
if (len > 0x1F) {
buf[nloc++] = 0xE0 | (section.mode << 2) | (len >> 8);
buf[nloc++] = len & 0xFF;
} else {
buf[nloc++] = (section.mode << 5) | len;
}
for (int i = 0; i < section.datalength; i++) {
buf[nloc++] = data[i];
}
return nloc;
}
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: %s infile outfile [start [length]]\n", argv[0]);
return 1;
}
off_t seek = 0;
if (argc > 3) {
seek = strtol(argv[3], NULL, 0);
}
FILE *inptr;
if ((inptr = fopen(argv[1], "rb")) == NULL) {
printf("%s does not exist.\n", argv[1]);
return 1;
}
int fd = fileno(inptr);
if (fd < 0) {
printf("Error stating file: %s\n", argv[1]);
return 1;
}
struct stat buf;
if (fstat(fd, &buf) != 0) {
printf("Error stating file: %s\n", argv[1]);
return 1;
}
off_t size = buf.st_size - seek;
if (argc > 4) {
size = strtol(argv[4], NULL, 0);
}
unsigned char inbuf[size];
fseek(inptr, seek, SEEK_SET);
if (fread(inbuf, 1, size, inptr) < size) {
printf("Error reading file: %s\n", argv[1]);
return 1;
}
fclose(inptr);
unsigned char outbuf[size * 2];
unsigned char m0data[MAXLENGTH];
int oloc = 0;
struct section m0;
m0.mode = 0;
m0.length = 0;
int i;
off_t loc = 0;
while (loc < size) {
struct section section;
if (!get_section(loc, size, inbuf, &section)) {
if (m0.length > 0) {
m0.datalength = m0.length;
oloc = write_section(m0, m0data, outbuf, oloc);
m0.length = 0;
}
oloc = write_section(section, section.data, outbuf, oloc);
loc += section.length;
} else {
if (m0.length == MAXLENGTH) {
m0.datalength = m0.length;
oloc = write_section(m0, m0data, outbuf, oloc);
m0.length = 0;
}
m0data[m0.length++] = inbuf[loc];
loc += 1;
}
}
if (m0.length > 0) {
m0.datalength = m0.length;
oloc = write_section(m0, m0data, outbuf, oloc);
m0.length = 0;
}
outbuf[oloc++] = 0xFF;
FILE *outptr;
if ((outptr = fopen(argv[2], "wb")) == NULL) {
printf("Error opening file: %s\n", argv[2]);
return 1;
}
if (fwrite(outbuf, 1, oloc, outptr) < oloc) {
printf("Error writing to file: %s\n", argv[2]);
return 1;
}
fclose(outptr);
printf("Input file: %lX bytes. Compressed: %X bytes.\n", size, oloc);
return 0;
}

View File

@@ -1,155 +0,0 @@
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/stat.h>
struct section {
int mode;
int length;
unsigned char data[2];
int datalength;
};
int read_section(unsigned char buf[], int loc, struct section *out) {
int nloc = loc;
unsigned char header = buf[nloc++];
if (header == 0xFF) {
return -1;
}
struct section result;
result.data[0] = buf[loc];
result.datalength = 1;
if ((header & 0xE0) == 0xE0) {
result.mode = (header & 0x1C) >> 2;
result.length = (((header & 0x03) << 8) | buf[nloc++]) + 1;
} else {
result.mode = (header & 0xE0) >> 5;
result.length = (header & 0x1F) + 1;
}
switch (result.mode) {
case 0:
result.datalength = 0;
break;
case 1:
result.datalength = 1;
break;
case 2:
result.datalength = 2;
break;
case 3:
result.datalength = 1;
break;
case 4:
result.datalength = 2;
break;
}
for (int i = 0; i < result.datalength; i++) {
result.data[i] = buf[nloc++];
}
*out = result;
return nloc;
}
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: %s infile outfile [start [length]]\n", argv[0]);
return 1;
}
off_t seek = 0;
if (argc > 3) {
seek = strtol(argv[3], NULL, 0);
}
FILE *inptr;
if ((inptr = fopen(argv[1], "rb")) == NULL) {
printf("%s does not exist.\n", argv[1]);
return 1;
}
int fd = fileno(inptr);
if (fd < 0) {
printf("Error stating file: %s\n", argv[1]);
return 1;
}
struct stat buf;
if (fstat(fd, &buf) != 0) {
printf("Error stating file: %s\n", argv[1]);
return 1;
}
off_t size = buf.st_size - seek;
if (argc > 4) {
size = strtol(argv[4], NULL, 0);
}
fseek(inptr, seek, SEEK_SET);
unsigned char inbuf[size];
if (fread(inbuf, 1, size, inptr) < size) {
printf("Error reading file: %s\n", argv[1]);
return 1;
}
fclose(inptr);
unsigned char outbuf[size * 256];
int oloc = 0;
struct section section;
int i;
off_t loc = 0;
while ((loc = read_section(inbuf, loc, &section)) >= 0) {
if (section.mode == 0) {
for (i = 0; i < section.length; i++) {
outbuf[oloc++] = inbuf[loc++];
}
} else if (section.mode == 1) {
for (i = 0; i < section.length; i++) {
outbuf[oloc++] = section.data[0];
}
} else if (section.mode == 2) {
for (i = 0; i < section.length; i++) {
outbuf[oloc++] = section.data[0];
if (++i < section.length) {
outbuf[oloc++] = section.data[1];
}
}
} else if (section.mode == 3) {
for (i = 0; i < section.length; i++) {
outbuf[oloc++] = (section.data[0] + i) & 0xff;
}
} else if (section.mode == 4) {
int offset = section.data[0] | (section.data[1] << 8);
for (i = 0; i < section.length; i++) {
outbuf[oloc++] = outbuf[offset + i];
}
}
}
FILE *outptr;
if ((outptr = fopen(argv[2], "wb")) == NULL) {
printf("Error opening file: %s\n", argv[2]);
return 1;
}
if (fwrite(outbuf, 1, oloc, outptr) < oloc) {
printf("Error writing to file: %s\n", argv[2]);
return 1;
}
fclose(outptr);
printf("Input file: %lX bytes. Decompressed: %X bytes.\n", size, oloc);
return 0;
}

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -2,22 +2,23 @@
; Randomize Book of Mudora
;--------------------------------------------------------------------------------
LoadLibraryItemGFX:
INC.w SkipBeeTrapDisguise
LDA.l LibraryItem_Player : STA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
%GetPossiblyEncryptedItem(LibraryItem, SpriteItemValues)
STA.w SprSourceItemId, X
JML RequestStandingItemVRAMSlot
%GetPossiblyEncryptedItem(LibraryItem, SpriteItemValues)
JSL.l AttemptItemSubstitution
JSL.l ResolveLootIDLong
STA.w SpriteID, X
JSL.l PrepDynamicTile_loot_resolved
RTL
;--------------------------------------------------------------------------------
DrawLibraryItemGFX:
PHA
LDA.w SprItemReceipt, X
JSL DrawPotItem
PLA
PHA
LDA.w SpriteID, X
JSL.l DrawDynamicTile
PLA
RTL
;--------------------------------------------------------------------------------
SetLibraryItem:
LDY.w SprSourceItemId, X
JSL ItemSet_Library ; contains thing we wrote over
LDY.w SpriteID, X
JSL.l ItemSet_Library ; contains thing we wrote over
RTL
;--------------------------------------------------------------------------------
@@ -26,81 +27,75 @@ RTL
; Randomize Bonk Keys
;--------------------------------------------------------------------------------
LoadBonkItemGFX:
LDA.b #$08 : STA.w SpriteOAMProp, X ; thing we wrote over
LDA.b #$08 : STA.w SpriteOAMProp, X ; thing we wrote over
LoadBonkItemGFX_inner:
INC.w SkipBeeTrapDisguise
JSR LoadBonkItem_Player : STA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
JSR LoadBonkItem
STA.w SprSourceItemId, X
JSL RequestStandingItemVRAMSlot
LDA.b #$00 : STA.l RedrawFlag
JSR LoadBonkItem
JSL.l AttemptItemSubstitution
JSL.l ResolveLootIDLong
STA.w SpriteItemType, X
STA.w SpriteID, X
JSL.l PrepDynamicTile
PHA : PHX
LDA.w SpriteID,X : TAX
LDA.l SpriteProperties_standing_width,X : BNE +
LDA.b #$00 : STA.l SpriteOAM : STA.l SpriteOAM+8
+
PLX : PLA
RTL
;--------------------------------------------------------------------------------
DrawBonkItemGFX:
PHA
LDA.w SprRedrawFlag, X : BEQ .skipInit
JSL LoadBonkItemGFX_inner
LDA.w SprRedrawFlag, X : CMP.b #$02 : BEQ .skipInit
PHA
LDA.l RedrawFlag : BEQ .skipInit
JSL.l LoadBonkItemGFX_inner
BRA .done ; don't draw on the init frame
.skipInit
LDA.w SpriteID,X
JSL.l DrawDynamicTileNoShadow
.skipInit
LDA.w SprItemReceipt,X
JSL DrawPotItem
.done
PLA
.done
PLA
RTL
;--------------------------------------------------------------------------------
GiveBonkItem:
LDA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_ITEM_PLAYER_ID
LDA.w SprSourceItemId, X
JSR AbsorbKeyCheck : BCC .notKey
PHY : LDY.b #$24 : JSL AddInventory : PLY ; do inventory processing for a small key
LDA.l CurrentSmallKeys : INC A : STA.l CurrentSmallKeys
LDA.b #$2F : JSL Sound_SetSfx3PanLong
JSR LoadBonkItem
JSR.w AbsorbKeyCheck : BCC .notKey
.key
PHY : LDY.b #$24 : JSL.l AddInventory : PLY ; do inventory processing for a small key
LDA.l CurrentSmallKeys : INC A : STA.l CurrentSmallKeys
LDA.b #$2F : JSL.l Sound_SetSfx3PanLong
LDA.b #$01 : STA.l UpdateHUDFlag
RTL
RTL
.notKey
PHY : TAY : JSL Link_ReceiveItem : PLY
PHY : TAY : JSL.l Link_ReceiveItem : PLY
RTL
;--------------------------------------------------------------------------------
LoadBonkItem:
LDA.b RoomIndex ; check room ID - only bonk keys in 2 rooms so we're just checking the lower byte
CMP.b #$73 : BNE + ; Desert Bonk Key
LDA.l BonkKey_Desert
BRA ++
+ : CMP.b #$8C : BNE + ; GTower Bonk Key
LDA.l BonkKey_GTower
BRA ++
+
LDA.b #$24 ; default to small key
++
RTS
;--------------------------------------------------------------------------------
LoadBonkItem_Player:
LDA.b RoomIndex ; check room ID - only bonk keys in 2 rooms so we're just checking the lower byte
CMP.b #$73 : BNE + ; Desert Bonk Key
LDA.l BonkKey_Desert_Player
BRA ++
+ : CMP.b #$8C : BNE + ; GTower Bonk Key
LDA.l BonkKey_GTower_Player
BRA ++
+
LDA.b #$00
++
LDA.b RoomIndex ; check room ID - only bonk keys in 2 rooms so we're just checking the lower byte
CMP.b #115 : BNE + ; Desert Bonk Key
LDA.l BonkKey_Desert
BRA ++
+ : CMP.b #140 : BNE + ; GTower Bonk Key
LDA.l BonkKey_GTower
BRA ++
+
LDA.b #$24 ; default to small key
++
RTS
;--------------------------------------------------------------------------------
AbsorbKeyCheck:
PHA
CMP.b #$24 : BEQ .key
CMP.b #$A0 : BCC .not_key
CMP.b #$B0 : BCS .not_key
AND.b #$0F : ASL
CMP.w DungeonID : BNE .not_key
.key
PLA
SEC
RTS
.not_key
PLA
CLC
PHA
CMP.b #$24 : BEQ .key
CMP.b #$A0 : BCC .not_key
CMP.b #$B0 : BCS .not_key
AND.b #$0F : ASL
CMP.w DungeonID : BNE .not_key
.key
PLA
SEC
RTS
.not_key
PLA
CLC
RTS

View File

@@ -8,7 +8,7 @@ ModifyBoots:
+ : CMP.b #$02 : BNE +
PLA : AND.l AbilityFlags : AND.b #$FB : RTL ; no boots
+ : LDA.l FakeBoots : CMP.b #$01 : BNE +
LDA.b LinkSlipping : BEQ ++ : LDA.b PitTileActField : BNE + ; hover check
LDA.b LinkSlipping : BEQ ++ : LDA.b $59 : BNE + ; hover check
++ : PLA : AND.l AbilityFlags : ORA.b #$04 : RTL ; yes boots, not hovering
+
PLA
@@ -17,15 +17,15 @@ RTL
;--------------------------------------------------------------------------------
AddBonkTremors:
PHA
LDA.b LinkIncapacitatedTimer : BNE + ; Check for incapacitated Link
JSL IncrementBonkCounter
LDA.b $46 : BNE + ; Check for incapacitated Link
JSL.l IncrementBonkCounter
+
LDA.l BootsModifier : CMP.b #$01 : BEQ +
LDA.l BootsEquipment : BNE + ; Check for Boots
PLA : RTL
+
PLA
JSL AddDashTremor : JSL Player_ApplyRumbleToSprites ; things we wrote over
JSL.l AddDashTremor : JSL.l Player_ApplyRumbleToSprites ; things we wrote over
RTL
;--------------------------------------------------------------------------------
BonkBreakableWall:
@@ -36,7 +36,7 @@ BonkBreakableWall:
PLP : PLX : LDA.w #$0000 : RTL
+
PLP : PLX
LDA.w LinkDashing : AND.w #$00FF ; things we wrote over
LDA.w $0372 : AND.w #$00FF ; things we wrote over
RTL
;--------------------------------------------------------------------------------
BonkRockPile:
@@ -51,10 +51,10 @@ GravestoneHook:
LDA.l BootsModifier : CMP.b #$01 : BEQ +
LDA.l BootsEquipment : BEQ .done ; Check for Boots
+
LDA.w LinkDashing : BEQ .done ; things we wrote over
JML moveGravestone
LDA.w $0372 : BEQ .done ; things we wrote over
JML.l moveGravestone
.done
JML GravestoneHook_continue
JML.l GravestoneHook_continue
;--------------------------------------------------------------------------------
JumpDownLedge:
LDA.l BootsModifier : CMP.b #$01 : BEQ +
@@ -74,22 +74,3 @@ BonkRecoil:
+
LDA.b #$24 : STA.b LinkRecoilZ ; things we wrote over
RTL
;--------------------------------------------------------------------------------
BonkRecoilStop:
LDA.l BootsModifier : CMP.b #$01 : BEQ .return
LDA.l BootsEquipment : BNE .return
LDA.b LinkState : CMP.b #$02 : BNE .return
LDA.b LinkPosZ : BMI .return : CMP.b #$09 : BCC .return
LDA.b FrameCounter : AND.b #$01 : BNE .return
REP #$20
LDA.w $0114 : CMP.w #$0020 : SEP #$20 : BNE .return
LDA.b LinkRecoilY : BEQ ++ : BMI +
DEC : BRA ++
+ INC
++ STA.b LinkRecoilY
LDA.b LinkRecoilX : BEQ ++ : BMI +
DEC : BRA ++
+ INC
++ STA.b LinkRecoilX
.return
JML LinkHop_FindArbitraryLandingSpot

View File

@@ -1,5 +1,12 @@
;================================================================================
;--------------------------------------------------------------------------------
AssignKiki:
LDA.b #$00 : STA.l FollowerDropped ; defuse bomb
LDA.b #$0A : STA.l FollowerIndicator ; assign kiki as follower
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; Name: AllowSQ
; Returns: Accumulator = 0 if S&Q is disallowed, 1 if allowed
@@ -41,10 +48,10 @@ DecideIfBunnyByScreenIndex:
; superbunny work
LDA.b IndoorsFlag : BNE .done
LDA.l MoonPearlEquipment : BNE .done
PHX : LDX.b OverworldIndex : LDA.l OWTileWorldAssoc, X : PLX : PHA
LDA.b OverworldIndex : AND.b #$40 : PHA
LDA.l InvertedMode : BNE .inverted
.normal
PLA : EOR.b #$40
PLA : EOR #$40
BRA .done
.inverted
PLA
@@ -53,7 +60,7 @@ RTL
;--------------------------------------------------------------------------------
FixBunnyOnExitToLightWorld:
LDA.w BunnyFlag : BEQ +
JSL DecideIfBunny : BEQ +
JSL.l DecideIfBunny : BEQ +
STZ.b LinkState ; set player mode to Normal
STZ.w BunnyFlag : STZ.b BunnyFlagDP ; return player graphics to normal
+
@@ -73,9 +80,12 @@ FixAga2Bunny:
++
JSL DecideIfBunny : BNE +
JSR MakeBunny
LDA.b #$04 : STA.w MusicControlRequest ; play bunny music
BRA .done
+
.done
JML Overworld_DetermineAndSetMusic
LDA.b #$09 : STA.w MusicControlRequest ; what we wrote over
.done
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
@@ -103,7 +113,7 @@ FixFrogSmith:
STA.l FollowerIndicator
JSL Tagalong_LoadGfx
.done
RTL
RTS
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
@@ -173,56 +183,13 @@ RTL
;--------------------------------------------------------------------------------
; Fix pedestal pull overlay
PedestalPullOverlayFix:
LDA.b #$09 : STA.w AncillaGeneralF, X ; the thing we wrote over
LDA.b #$09 : STA.w AncillaGeneral, X ; the thing we wrote over
LDA.b IndoorsFlag : BNE +
LDA.b OverworldIndex : CMP.b #$80 : BNE +
LDA.b OverlayID : CMP.b #$97
+
RTL
PostFixMirrorGfxPrep:
LDA.b #$01 : STA.w OWTransitionFlag
JML HandleFollowersAfterMirroring ; what we wrote over
; warning, this is called on frames after PostFixMirrorGfxPrep but for
; several frames after, so we use OWTransitionFlag to run something once
PostFixMirrorGfx:
STA.w SubModuleInterface ; what we wrote over
LDA.w OWTransitionFlag : CMP.b #$01 : BNE .done
LDA.b #$08 : STA.w OWTransitionFlag
JML FollowerGfxRedraw
.done
RTL
PostFixOAMGfx:
JSL FollowerGfxRedraw
REP #$30 : LDA.w #$2000 ; what we wrote over
RTL
;--------------------------------------------------------------------------------
; Fix losing VRAM gfx when using quake
PostNMIUpdateBGCharHalf:
STA.w DMAENABLE : SEP #$10 ; what we wrote over
LDA.w VRAMTileMapIndex : CMP.b #$46 : BNE .return ; checks to see if this is the last VRAM write
LDA.b LinkState : CMP.b #$08 : BCC + : CMP.b #$0A+1 : BCS + ; skip if we're mid-medallion
RTL
+ JSL DynamicDropGFXClear
JSL HeartPieceSetRedraw ; set redraw flag for items
.return
RTL
; Force redraws of items following map checks
PostOverworldGfxLoad:
INC.b GameSubMode : STZ.b INIDISPQ ; what we wrote over
JSL DynamicDropGFXClear
JSL HeartPieceSetRedraw
RTL
PostUnderworldMap:
JSL DynamicDropGFXClear
JSL HeartPieceSetRedraw
LDA.l $7EC229 ; what we wrote over
RTL
;--------------------------------------------------------------------------------
FixJingleGlitch:
LDA.b GameSubMode
@@ -268,10 +235,10 @@ ParadoxCaveGfxFix:
CPX.w #$1E00 : BEQ .uploadLine
.uploadLine
LDA.b #$01 : STA.w DMAENABLE
LDA.b #$01 : STA.w MDMAEN
.skipLine
JML FollowerGfxRedraw
RTL
.skipMostOfLine
; Set line length to 192 bytes (the first 6 8x8 tiles in the line)
@@ -279,75 +246,9 @@ ParadoxCaveGfxFix:
BRA .uploadLine
;--------------------------------------------------------------------------------
SetItemRiseTimer:
LDA.w ItemReceiptMethod : CMP.b #$01 : BNE .not_from_chest
LDA.b #$38 : STA.w AncillaTimer, X
RTL
.not_from_chest
JSL.l ItemIsJunk
BEQ .default
.junk
LDA.l JunkItemTimer : AND.b #$3F : STA.w AncillaTimer, X
RTL
.default
TYA : STA.w AncillaTimer, X ; What we wrote over
RTL
;--------------------------------------------------------------------------------
ItemIsJunk:
PHX
LDA.l JunkItemTimer : BIT.b #$3F : BEQ .not_junk
BIT.b #$80 : BNE .check
LDA.l !MULTIWORLD_ITEM_PLAYER_ID : BNE .check
LDA.l !MULTIWORLD_RECEIVING_ITEM : BNE .check
BRA .not_junk
.check
LDA.l JunkItemTimer : AND.b #$40
BEQ +
LDA.b #JunkItems_triforce_end-JunkItems_end
+
CLC : ADC.b #JunkItems_end-JunkItems-1
LDA.w AncillaGet, X
TAX
-
CMP.l JunkItems, X : BEQ .junk
DEX : BPL -
.not_junk
PLX
LDA.b #$00
RTL
.junk
PLX
LDA.b #$01
RTL
LDA.w ItemReceiptMethod : CMP #$01 : BNE .not_from_chest
LDA.b #$38 : STA.w AncillaTimer, X
RTL
.not_from_chest
TYA : STA.w AncillaTimer, X ; What we wrote over
RTL
JunkItems:
db $27 ; Bomb
db $28 ; 3 bombs
db $31 ; 10 bombs
db $34 ; 1 rupee
db $35 ; 5 rupees
db $36 ; 20 rupees
db $40 ; 100 rupees
db $41 ; 50 rupees
db $42 ; Heart
db $43 ; Arrow
db $44 ; 10 arrows
db $45 ; Small magic
db $46 ; 300 rupees
db $47 ; 20 rupees green
db $59 ; Rupoor
db $D1 ; Apples
db $D2 ; Fairy
db $D3 ; Chicken
db $D4 ; Big Magic
db $D5 ; 5 Arrows
db $D6 ; Good Bee
.end
db $6B ; Power Star
db $6C ; Triforce Piece
.triforce_end
;--------------------------------------------------------------------------------

115
build.py
View File

@@ -1,115 +0,0 @@
import os
import sys
import hashlib
from asar import init as asar_init, close as asar_close, patch as asar_patch, geterrors as asar_errors, getprints as asar_prints, getwarnings as asar_warnings
JAP10HASH = '03a63945398191337e896e5771f77173'
try:
from yaml import CLoader as Loader
except ImportError:
from yaml import Loader
def int16_as_bytes(value):
value = value & 0xFFFF
return [value & 0xFF, (value >> 8) & 0xFF]
def int32_as_bytes(value):
value = value & 0xFFFFFFFF
return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF]
def is_bundled():
return getattr(sys, 'frozen', False)
def local_path(path):
if local_path.cached_path:
return os.path.join(local_path.cached_path, path)
elif is_bundled():
if hasattr(sys, "_MEIPASS"):
# we are running in a PyInstaller bundle
local_path.cached_path = sys._MEIPASS # pylint: disable=protected-access,no-member
else:
# cx_Freeze
local_path.cached_path = os.path.dirname(os.path.abspath(sys.argv[0]))
else:
# we are running in a normal Python environment
import __main__
local_path.cached_path = os.path.dirname(os.path.abspath(__main__.__file__))
return os.path.join(local_path.cached_path, path)
local_path.cached_path = None
def make_new_base2current(old_rom_data, new_rom_data):
from collections import OrderedDict
import json
# extend to 2 mb
old_rom_data.extend(bytearray([0x00]) * (2097152 - len(old_rom_data)))
out_data = OrderedDict()
for idx, old in enumerate(old_rom_data):
new = new_rom_data[idx]
if old != new:
out_data[idx] = [int(new)]
for offset in reversed(list(out_data.keys())):
if offset - 1 in out_data:
out_data[offset-1].extend(out_data.pop(offset))
with open('../base2current.json', 'wt') as outfile:
json.dump([{key: value} for key, value in out_data.items()], outfile, separators=(",", ":"))
basemd5 = hashlib.md5()
basemd5.update(new_rom_data)
return "New Rom Hash: " + basemd5.hexdigest()
if __name__ == '__main__':
try:
asar_init()
print("Asar DLL initialized")
print("Opening Base rom")
with open('../alttp.sfc', 'rb') as stream:
old_rom_data = bytearray(stream.read())
if len(old_rom_data) % 0x400 == 0x200:
old_rom_data = old_rom_data[0x200:]
basemd5 = hashlib.md5()
basemd5.update(old_rom_data)
if JAP10HASH != basemd5.hexdigest():
raise Exception("Base rom is not 'Zelda no Densetsu - Kamigami no Triforce (J) (V1.0)'")
print("Patching Base Rom")
result, new_rom_data = asar_patch(os.path.abspath('LTTP_RND_GeneralBugfixes.asm'), old_rom_data)
if result:
with open('../working.sfc', 'wb') as stream:
stream.write(new_rom_data)
print("Success\n")
print(make_new_base2current(old_rom_data, new_rom_data))
prints = asar_prints()
for p in prints:
print(p)
else:
errors = asar_errors()
print("\nErrors: " + str(len(errors)))
for error in errors:
print (error)
warnings = asar_warnings()
print("\nWarnings: " + str(len(warnings)))
for w in warnings:
print(w)
asar_close()
except:
import traceback
traceback.print_exc()

View File

@@ -1,8 +1,5 @@
#!/bin/bash
rm ../alttp.sfc
cp ~/dev/kwyn/orig/z3.sfc ../alttp.sfc
asar --symbols=wla LTTP_RND_GeneralBugfixes.asm ../alttp.sfc
flips ~/dev/kwyn/orig/z3.sfc ../alttp.sfc ../base2current.bps
md5sum ../alttp.sfc | tee /dev/tty | cut -d ' ' -f 1 | xargs -I '{}' sed -i "s/RANDOMIZERBASEHASH = '.\+'/RANDOMIZERBASEHASH = '{}'/g" ~/dev/kwyn/doors/Rom.py
cp ../base2current.bps ~/dev/kwyn/doors/data
rm ../working.sfc
cp ../alttp.sfc ../working.sfc
./bin/macos/asar LTTP_RND_GeneralBugfixes.asm ../working.sfc

View File

@@ -5,60 +5,6 @@
; Filtered Joypad 1 Register: [AXLR | ????]
; Filtered Joypad 1 Register: [BYST | udlr] [AXLR | ????]
InvertDPad_DPadOnly:
LDA.w JOY1L : STA.b Scrap00
LDA.w JOY1H
BIT.b #$0C : BEQ + : EOR.b #$0C : + ; swap up/down
BIT.b #$03 : BEQ + : EOR.b #$03 : + ; swap left/right
STA.b Scrap01
JML InvertDPadReturn
InvertDPad_ButtonsOnly:
REP #$20 ; set 16-bit accumulator
LDA.w JOY1L
BIT.w #$8040 : BEQ + : EOR.w #$8040 : + ; swap X/B
BIT.w #$4080 : BEQ + : EOR.w #$4080 : + ; swap Y/A
STA.b Scrap00
SEP #$20 ; set 8-bit accumulator
JML InvertDPadReturn
InvertDPad_Both:
REP #$20 ; set 16-bit accumulator
LDA.w JOY1L
BIT.w #$8040 : BEQ + : EOR.w #$8040 : + ; swap X/B
BIT.w #$4080 : BEQ + : EOR.w #$4080 : + ; swap Y/A
BIT.w #$0C00 : BEQ + : EOR.w #$0C00 : + ; swap up/down
BIT.w #$0300 : BEQ + : EOR.w #$0300 : + ; swap left/right
STA.b Scrap00
SEP #$20 ; set 8-bit accumulator
JML InvertDPadReturn
InvertDPad_SwapSides:
REP #$20 ; set 16-bit accumulator
LDA.w JOY1L
BIT.w #$0840 : BEQ + : EOR.w #$0840 : + ; swap X/up
BIT.w #$0180 : BEQ + : EOR.w #$0180 : + ; swap A/right
BIT.w #$4200 : BEQ + : EOR.w #$4200 : + ; swap Y/left
BIT.w #$8400 : BEQ + : EOR.w #$8400 : + ; swap B/down
STA.b Scrap00
SEP #$20 ; set 8-bit accumulator
JML InvertDPadReturn
InvertDPad_DPadLROnly:
LDA.w JOY1L : STA.b Scrap00
LDA.w JOY1H
BIT.b #$03 : BEQ + : EOR.b #$03 : + ; swap left/right
STA.b Scrap00
JML InvertDPadReturn
InvertDPad_DPadUDOnly:
LDA.w JOY1L : STA.b Scrap00
LDA.w JOY1H
BIT.b #$0C : BEQ + : EOR.b #$0C : + ; swap up/down
STA.b Scrap00
JML InvertDPadReturn
InvertDPad:
LDA.l OneMindPlayerCount : BEQ .crowd_control
@@ -73,27 +19,53 @@ InvertDPad:
LDA.b #$80 : STA.w WRIO ; reset this so latch can read it, otherwise RNG breaks
JML InvertDPadReturn
JML.l InvertDPadReturn
.crowd_control
LDA.l ControllerInverter : BNE +
LDA.w JOY1L : STA.b Scrap00
LDA.w JOY1H : STA.b Scrap01
JML InvertDPadReturn
+ DEC : BNE +
JMP InvertDPad_DPadOnly
+ DEC : BNE +
JMP InvertDPad_ButtonsOnly
+ DEC : BNE +
JMP InvertDPad_Both
+ DEC : BNE +
JMP InvertDPad_SwapSides
+ DEC : BNE +
JMP InvertDPad_DPadLROnly
+ JMP InvertDPad_DPadUDOnly
JML.l InvertDPadReturn
+ DEC : BEQ .dpadOnly
DEC : BEQ .buttonsOnly
DEC : BEQ .invertBoth
.swapSides
REP #$20 ; set 16-bit accumulator
LDA.w JOY1L
BIT.w #$0840 : BEQ + : EOR.w #$0840 : + ; swap X/up
BIT.w #$0180 : BEQ + : EOR.w #$0180 : + ; swap A/right
BIT.w #$4200 : BEQ + : EOR.w #$4200 : + ; swap Y/left
BIT.w #$8400 : BEQ + : EOR.w #$8400 : + ; swap B/down
STA.b Scrap00
SEP #$20 ; set 8-bit accumulator
JML.l InvertDPadReturn
.invertBoth
REP #$20 ; set 16-bit accumulator
LDA.w JOY1L
BIT.w #$8040 : BEQ + : EOR.w #$8040 : + ; swap X/B
BIT.w #$4080 : BEQ + : EOR.w #$4080 : + ; swap Y/A
BIT.w #$0C00 : BEQ + : EOR.w #$0C00 : + ; swap up/down
BIT.w #$0300 : BEQ + : EOR.w #$0300 : + ; swap left/right
STA.b Scrap00
SEP #$20 ; set 8-bit accumulator
JML.l InvertDPadReturn
.buttonsOnly
REP #$20 ; set 16-bit accumulator
LDA.w JOY1L
BIT.w #$8040 : BEQ + : EOR.w #$8040 : + ; swap X/B
BIT.w #$4080 : BEQ + : EOR.w #$4080 : + ; swap Y/A
STA.b Scrap00
SEP #$20 ; set 8-bit accumulator
JML.l InvertDPadReturn
.dpadOnly
LDA.w JOY1L : STA.b Scrap00
LDA.w JOY1H
BIT.b #$0C : BEQ + : EOR.b #$0C : + ; swap up/down
BIT.b #$03 : BEQ + : EOR.b #$03 : + ; swap left/right
STA.b Scrap01
JML.l InvertDPadReturn
.onemind_controller_offset
db 0 ; player 0 - JOY1L - joy1d1
@@ -103,6 +75,8 @@ InvertDPad:
db 2 ; player 4 - JOY2L - joy2d1
db 6 ; player 5 - JOY4L - joy2d2
;--------------------------------------------------------------------------------
HandleOneMindController:
@@ -145,5 +119,5 @@ HandleOneMindController:
.no_onemind
STZ.b NMIDoneFlag
JML MainGameLoop ; reset frame loop
JML $808034 ; reset frame loop

View File

@@ -1,52 +0,0 @@
pushpc
org $87A46E
JSL CheckBookTriggerSwitch
BCS +
skip 15
+
org $8296A8
JSL FinishPegChange
pullpc
FinishPegChange:
LDA.b #$20
TRB.w $037A
STZ.b $B0
STZ.b $11
RTL
CheckBookTriggerSwitch:
LDA.l CrystalSwitchBook
BEQ +
LDA.b $10
CMP.b #$07
BNE +
LDA.l $7EC172
EOR.b #$01
STA.l $7EC172
LDA.b #$16
STA.b $11
LDA.b #$20
TSB.w $037A
LDA.b #$25
JSL $8DBB8A
SEC
BRA .done
+ CLC
.done
; what we wrote over
LDA.b $3A
AND.b #$BF
STA.b $3A
RTL

View File

@@ -3,7 +3,6 @@
!INERT = $00
!INIT = $08
!ALIVE = $09
!OAMPROPS = $09
!CUCCO_ENRAGED = $23
CuccoStorm:
@@ -13,7 +12,6 @@ CuccoStorm:
LDA.b GameMode : CMP.b #$09 : BNE + ; only if outdoors
LDA.l LoopFrames : AND.b #$7F : BNE + ; check every 128 frames
.activate
-
;==== Find a Cucco
@@ -42,11 +40,7 @@ CuccoStorm:
PLY
CPY.b #$FF : BEQ + ; fail if no slots found
LDA.b #!CUCCO : STA.w SpriteTypeTable, Y
LDA.b #!ALIVE : STA.w SpriteAITable, Y
PHX
TYX : JSL ResetSpriteProperties
PLX
LDA.b #!OAMPROPS : STA.w SpriteOAMProp, Y
LDA.b #!INIT : STA.w SpriteAITable, Y
LDA.b LinkPosY : STA.w SpritePosYLow, Y
LDA.b LinkPosY+1 : STA.w SpritePosYHigh, Y
LDA.b LinkPosX : STA.w SpritePosXLow, Y

View File

@@ -2,33 +2,23 @@
; Dark World Spawn Location Fix & Master Sword Grove Fix
;--------------------------------------------------------------------------------
DarkWorldSaveFix:
JSL MasterSwordFollowerClear
JML StatSaveCounter
LDA.b #$70 : PHA : PLB ; thing we wrote over - data bank change
JSL.l MasterSwordFollowerClear
JML.l StatSaveCounter
;--------------------------------------------------------------------------------
DoWorldFix:
LDA.l InvertedMode : BEQ +
JMP DoWorldFix_Inverted
+
LDA.l Bugfix_MirrorlessSQToLW : BEQ .skip_mirror_check
LDA.l FollowerIndicator : CMP.b #$04 : BNE + ; if old man following, skip mirror/aga check
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ +
LDA.l OldManRetrievalWorld
BRA .noMirror
+ LDA.l MirrorEquipment : AND.b #$02 : BEQ .noMirror ; check if we have the mirror
LDA.l FollowerIndicator : CMP.b #$04 : BEQ .setLightWorld ; check if old man is following
LDA.l MirrorEquipment : BEQ .noMirror ; check if we have the mirror
.skip_mirror_check ; alt entrance point
LDA.l ProgressIndicator : CMP.b #$03 : BCS .done ; check if agahnim 1 is alive
.setLightWorld
.setLightWorld
LDA.b #$00
.noMirror
STA.l CurrentWorld ; set flag to light world
LDA.l SmithDeleteOnSave : BEQ .transform
LDA.l FollowerIndicator
CMP.b #$07 : BEQ .clear ; clear frog
CMP.b #$08 : BEQ .clear ; clear dwarf - consider flute implications
BRA .done
.clear
LDA.b #$00 : STA.l FollowerIndicator : BRA .done ; clear follower
.transform
LDA.l FollowerIndicator : CMP.b #$07 : BNE .done : INC : STA.l FollowerIndicator ; convert frog to dwarf
.done
RTL
@@ -41,7 +31,7 @@ SetDeathWorldChecked:
LDA.w DungeonID : CMP.b #$FF : BNE .dungeon
LDA.b RoomIndex : ORA.b RoomIndex+1 : BNE ++
LDA.l GanonPyramidRespawn : BNE .pyramid ; if flag is set, force respawn at pyramid on death to ganon
++
++
.outdoors
JMP DoWorldFix
@@ -59,27 +49,18 @@ RTL
;================================================================================
DoWorldFix_Inverted:
LDA.l Bugfix_MirrorlessSQToLW : BEQ .skip_mirror_check
LDA.l FollowerIndicator : CMP.b #$04 : BNE + ; if old man following, skip mirror/aga check
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ +
LDA.l OldManRetrievalWorld
BRA .setWorld
+ LDA.l MirrorEquipment : AND.b #$02 : BEQ .noMirror ; check if we have the mirror
LDA.l FollowerIndicator : CMP.b #$04 : BEQ .setDarkWorld ; check if old man is following
LDA.l MirrorEquipment : BEQ .setDarkWorld ; check if we have the mirror
.skip_mirror_check ; alt entrance point
LDA.l ProgressIndicator : CMP.b #$03 : BCS .done ; check if agahnim 1 is alive
.noMirror
.setDarkWorld
LDA.b #$40
.setWorld
STA.l CurrentWorld ; set flag to dark world
LDA.l SmithDeleteOnSave : BEQ .transform
LDA.l FollowerIndicator
CMP.b #$07 : BEQ .clear ; clear frog
CMP.b #$08 : BEQ .clear ; clear dwarf - consider flute implications
BRA .done
.clear
LDA.b #$00 : STA.l FollowerIndicator : BRA .done ; clear follower
.transform
LDA.l FollowerIndicator : CMP.b #$07 : BNE .done : INC : STA.l FollowerIndicator ; convert frog to dwarf
.setDarkWorld
LDA.b #$40 : STA.l CurrentWorld ; set flag to dark world
LDA.l FollowerIndicator
CMP.b #$07 : BEQ .clear ; clear frog
CMP.b #$08 : BEQ .clear ; clear dwarf - consider flute implications
BRA .done
.clear
LDA.b #$00 : STA.l FollowerIndicator ; clear follower
.done
RTL
;--------------------------------------------------------------------------------
@@ -90,7 +71,7 @@ SetDeathWorldChecked_Inverted:
LDA.l GanonPyramidRespawn : BNE .castle ; if flag is set, force respawn at pyramid on death to ganon
++
.outdoors
JMP DoWorldFix_Inverted
JMP DoWorldFix
.dungeon
LDA.l MosaicLevel : BNE .dontfix ; this is a sanc & quit
@@ -109,22 +90,10 @@ RTL
;--------------------------------------------------------------------------------
FakeWorldFix:
LDA.l FixFakeWorld : BEQ +
PHX
LDX.b OverworldIndex : LDA.l OWTileWorldAssoc, X : STA.l CurrentWorld
PLX
LDA.b OverworldIndex : AND.b #$40 : STA.l CurrentWorld
+
RTL
;--------------------------------------------------------------------------------
GetCurrentWorldForLoad:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ .default
LDA.l FollowerIndicator : CMP.b #$04 : BNE .default
LDA.l InvertedMode : BEQ +
LDA.b #$40
+ RTL
.default
LDA.l CurrentWorld
RTL
;--------------------------------------------------------------------------------
MasterSwordFollowerClear:
LDA.l FollowerIndicator
CMP.b #$0E : BNE .exit ; clear master sword follower
@@ -133,9 +102,7 @@ MasterSwordFollowerClear:
RTL
;--------------------------------------------------------------------------------
FixAgahnimFollowers:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ +
LDA.b #$00 : STA.l FollowerIndicator ; clear follower
+
LDA.b #$00 : STA.l FollowerIndicator ; clear follower
JML PrepDungeonExit ; thing we wrote over
;--------------------------------------------------------------------------------
@@ -152,23 +119,17 @@ RefreshRainAmmo:
+ CMP.b #$03 : BNE + ; Uncle
%SetMinimum(CurrentMagic,MagicFiller,RainDeathRefillMagic_Uncle)
%SetMinimum(BombsEquipment,BombsFiller,RainDeathRefillBombs_Uncle)
LDA.l ArrowMode : BEQ ++
LDA.l BowEquipment : BEQ +++
++ %SetMinimum(CurrentArrows,ArrowsFiller,RainDeathRefillArrows_Uncle)
+++ BRA .done
%SetMinimum(CurrentArrows,ArrowsFiller,RainDeathRefillArrows_Uncle)
BRA .done
+ CMP.b #$02 : BNE + ; Cell
%SetMinimum(CurrentMagic,MagicFiller,RainDeathRefillMagic_Cell)
%SetMinimum(BombsEquipment,BombsFiller,RainDeathRefillBombs_Cell)
LDA.l ArrowMode : BEQ ++
LDA.l BowEquipment : BEQ .done
++ %SetMinimum(CurrentArrows,ArrowsFiller,RainDeathRefillArrows_Cell)
%SetMinimum(CurrentArrows,ArrowsFiller,RainDeathRefillArrows_Cell)
BRA .done
+ CMP.b #$04 : BNE + ; Mantle
%SetMinimum(CurrentMagic,MagicFiller,RainDeathRefillMagic_Mantle)
%SetMinimum(BombsEquipment,BombsFiller,RainDeathRefillBombs_Mantle)
LDA.l ArrowMode : BEQ ++
LDA.l BowEquipment : BEQ .done
++ %SetMinimum(CurrentArrows,ArrowsFiller,RainDeathRefillArrows_Mantle)
%SetMinimum(CurrentArrows,ArrowsFiller,RainDeathRefillArrows_Mantle)
+
.done
RTL

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

View File

@@ -142,13 +142,13 @@ TransferItemToVRAM:
STA.w $2116
LDX.b #$01
STX.w DMAENABLE
STX.w $420B
ADC.w #$0100
STA.w $2116
INX
STX.w DMAENABLE
STX.w $420B
STZ.w ItemGFXPtr
STZ.w ItemGFXTarget
@@ -198,14 +198,10 @@ DecompressAllItemGraphics:
STA.l $4200 ; already 0 from the LDA above
LDX.b #$5D+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$5C+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$5B+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$5A+$73 : JSR AddGfxSheetToBigBuffer
JSR AddCherryPickGfxToBigBuffer
LDX.b #$01 : STX.w $06FA
LDX.b #$06+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$07+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$5D+$73 : JSR FastSpriteDecomp
LDX.b #$5C+$73 : JSR FastSpriteDecomp
LDX.b #$5B+$73 : JSR FastSpriteDecomp
LDX.b #$5A+$73 : JSR FastSpriteDecomp
REP #$30
PLX
@@ -223,21 +219,6 @@ DecompressAllItemGraphics:
RTL
;===================================================================================================
AddGfxSheetToBigBuffer:
SEP #$30
LDA.l GFXSheetPointers_background_bank,X : PHA : PLB
LDA.l GFXSheetPointers_background_high,X : XBA
LDA.l GFXSheetPointers_background_low,X
CPX.b #$73 : !BLT FastSpriteDecomp
CPX.b #$73+$0C : !BGE FastSpriteDecomp
.uncompressed
JMP Direct3BPPConvert
;===================================================================================================
; I normally hate macros like this... but I don't feel like constantly rewriting this
;===================================================================================================
@@ -265,6 +246,12 @@ endmacro
; so might as well rewrite it to be fast
;===================================================================================================
FastSpriteDecomp:
SEP #$30
LDA.l $80CFC0,X : PHA : PLB ; bank
LDA.l $80D09F,X : XBA ; high
LDA.l $80D17E,X ; low
REP #$10
TAY
@@ -499,86 +486,12 @@ macro DoPlanesA(offset)
XBA
ORA.b Decomp3BPPScratch
PHY
LDY.w $06FA : BEQ +
AND.w #$00FF ; idk why this line works but some sheets we pull in aren't correct without it
+
PLY
STA.w BigDecompressionBuffer+$10+<offset>+<offset>,X
endmacro
;===================================================================================================
macro DoIndirectPlanesA(offset)
LDA.b Scrap00 : ADC.w #<offset>+<offset> : STA.b Scrap02
LDA.b (Scrap02),Y
STA.l BigDecompressionBuffer+<offset>+<offset>,X
DEC.b Scrap02
ORA.b (Scrap02),Y
AND.w #$FF00
STA.b Decomp3BPPScratch
LDA.b Scrap00 : ADC.w #$10+<offset> : STA.b Scrap02
LDA.b (Scrap02),Y
AND.w #$00FF
TSB.b Decomp3BPPScratch
XBA
ORA.b Decomp3BPPScratch
PHY
LDY.w $06FA : BEQ +
AND.w #$00FF ; idk why this line works but some sheets we pull in aren't correct without it
+
PLY
STA.l BigDecompressionBuffer+$10+<offset>+<offset>,X
endmacro
;===================================================================================================
Direct3BPPConvert:
REP #$31
STA.b Scrap00
LDY.w #$0000
LDX.b DecompBufferOffset
.next_3bpp_tile
%DoIndirectPlanesA(0) ; 8 times
%DoIndirectPlanesA(1)
%DoIndirectPlanesA(2)
%DoIndirectPlanesA(3)
%DoIndirectPlanesA(4)
%DoIndirectPlanesA(5)
%DoIndirectPlanesA(6)
%DoIndirectPlanesA(7)
; carry will always be clear
; don't worry
TXA
ADC.w #32
TAX
; just trust me
TYA
ADC.w #24
TAY
CMP.w #24*64
BCS .done
JMP .next_3bpp_tile
.done
STX.b DecompBufferOffset
SEP #$30
RTS
;===================================================================================================
Unrolled3BPPConvert:
LDA.b #$7F
PHA
@@ -623,57 +536,4 @@ Unrolled3BPPConvert:
;===================================================================================================
macro CherryPickGfx(source,dest,length)
LDX.w #BigDecompressionBuffer+<source>
LDY.w #BigDecompressionBuffer+<dest>
LDA.w #<length>-1
MVN BigDecompressionBuffer>>16,BigDecompressionBuffer>>16
LDX.w #BigDecompressionBuffer+<source>+$200
LDY.w #BigDecompressionBuffer+<dest>+$200
LDA.w #<length>-1
MVN BigDecompressionBuffer>>16,BigDecompressionBuffer>>16
endmacro
;===================================================================================================
AddCherryPickGfxToBigBuffer:
; this is mostly to load and rearrange follower gfx to save on space
; assumes DecompBufferOffset left off at $A000 (#BigDecompressionBuffer+$2000)
; adjustments will be needed if anything prior to this changes
LDX.b #$01 : STX.w $06FA
LDX.b #$35+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$55+$73 : JSR AddGfxSheetToBigBuffer
REP #$30
%CherryPickGfx($2400,$2140,$40) ; move old man head
%CherryPickGfx($2D40,$20C0,$40) ; move zelda body
LDA.b DecompBufferOffset : SEC : SBC.w #$0C00 : STA.b DecompBufferOffset
SEP #$30
LDX.b #$11+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$15+$73 : JSR AddGfxSheetToBigBuffer
REP #$30
%CherryPickGfx($2940,$2180,$80) ; move locksmith head/body
%CherryPickGfx($2D00,$0440,$40) ; move frog
%CherryPickGfx($31C0,$0500,$40) ; move purple chest
LDA.b DecompBufferOffset : SEC : SBC.w #$1000 : STA.b DecompBufferOffset
SEP #$30
LDX.b #$59+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$58+$73 : JSR AddGfxSheetToBigBuffer
REP #$30
%CherryPickGfx($2880,$0480,$40) ; move kiki head
%CherryPickGfx($2900,$04C0,$40) ; move kiki body
%CherryPickGfx($30C0,$0540,$40) ; move big bomb
%CherryPickGfx($2C40,$0180,$40) ; move duck
LDA.b DecompBufferOffset : SEC : SBC.w #$1000 : STA.b DecompBufferOffset
SEP #$30
LDX.b #$4D+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$50+$73 : JSR AddGfxSheetToBigBuffer
REP #$30
%CherryPickGfx($2880,$0580,$40) ; move smith
%CherryPickGfx($3140,$0140,$40) ; move chicken
LDA.b DecompBufferOffset : SEC : SBC.w #$1000 : STA.b DecompBufferOffset
SEP #$30
STZ.w $06FA
RTS

View File

@@ -4,7 +4,7 @@ LoadStaticDecryptionKey:
PHB : PHA : PHX : PHY : PHP
REP #$30 ; set 16-bit accumulator & index registers
LDX.w #StaticDecryptionKey ; Source
LDY.w #KeyBase ; Target
LDY.w #KeyBase ; Target
LDA.w #$000F ; Length
MVN $307F
@@ -24,14 +24,14 @@ RetrieveValueFromEncryptedTable:
LDY.b Scrap0A : PHY : LDY.b Scrap0C : PHY : LDY.b Scrap0E : PHY
AND.w #$FFF8 : TAY
LDA.b [Scrap00], Y : STA.l CryptoBuffer : INY #2
LDA.b [Scrap00], Y : STA.l CryptoBuffer+2 : INY #2
LDA.b [Scrap00], Y : STA.l CryptoBuffer+4 : INY #2
LDA.b [Scrap00], Y : STA.l CryptoBuffer+6
LDA.b [$00], Y : STA.l CryptoBuffer : INY #2
LDA.b [$00], Y : STA.l CryptoBuffer+2 : INY #2
LDA.b [$00], Y : STA.l CryptoBuffer+4 : INY #2
LDA.b [$00], Y : STA.l CryptoBuffer+6
LDA.w #$0002 : STA.b Scrap04 ;set block size
JSL XXTEA_Decode
JSL.l XXTEA_Decode
PLA : STA.b Scrap0E : PLA : STA.b Scrap0C : PLA : STA.b Scrap0A
PLA : STA.b Scrap08 : PLA : STA.b Scrap06 : PLA : STA.b Scrap04
@@ -53,7 +53,7 @@ ChestDataPayload = $01EABC ; ChestData+$0150
GetChestData:
LDA.l IsEncrypted : BNE .encrypted
INC.b Scrap0E : LDX.w #$FFFD ; what we wrote over
JML Dungeon_OpenKeyedObject_nextChest
JML.l Dungeon_OpenKeyedObject_nextChest
.encrypted
INC.b Scrap0E : LDX.w #$FFFE
@@ -78,10 +78,10 @@ JML Dungeon_OpenKeyedObject_nextChest
LDA.l ChestData, X : ASL A : BCC .smallChest
JML Dungeon_OpenKeyedObject_bigChest ;(bank01.asm line #13783)
JML.l Dungeon_OpenKeyedObject_bigChest ;(bank01.asm line #13783)
.smallChest
JML Dungeon_OpenKeyedObject_smallChest
JML.l Dungeon_OpenKeyedObject_smallChest
.couldntFindChest
JML Dungeon_OpenKeyedObject_couldntFindChest
JML.l Dungeon_OpenKeyedObject_couldntFindChest
;--------------------------------------------------------------------------------

View File

@@ -21,7 +21,7 @@ macro LoadDialogAddress(address)
PHB : PHK : PLB
SEP #$20 ; set 8-bit accumulator
REP #$10 ; set 16-bit index registers
PEI.b (Scrap00)
PEI.b ($00)
LDA.b Scrap02 : PHA
STZ.w TextID : STZ.w TextID+1 ; reset decompression buffer
LDA.b #$01 : STA.l AltTextFlag ; set flag
@@ -44,7 +44,7 @@ endmacro
macro CopyDialogIndirect()
REP #$20 : LDA.l DialogOffsetPointer : TAX : LDY.w #$0000 : SEP #$20 ; copy 2-byte offset pointer to X and set Y to 0
?loop:
LDA.b [Scrap00], Y ; load the next character from the pointer
LDA.b [$00], Y ; load the next character from the pointer
STA.l DialogBuffer, X ; write to the buffer
INX : INY
CMP.b #$7F : BNE ?loop
@@ -148,12 +148,8 @@ FreeDungeonItemNotice:
LDA.w DungeonID : CMP.w #$0003 : BCS +
.self_notice
SEP #$20
LDA.l FreeItemText : AND.b #$40 : BEQ ++
LDA.b #$00 : STA.l DialogOffsetPointer : STA.l DialogOffsetPointer+1
JMP .skip
++
%CopyDialog(Notice_Self)
JMP .done
%CopyDialog(Notice_Self)
JMP.w .done
+
SEP #$20
LDA.l ScratchBufferNV+1
@@ -232,7 +228,7 @@ RTL
;--------------------------------------------------------------------------------
DialogResetSelectionIndex:
JSL Attract_DecompressStoryGfx ; what we wrote over
JSL.l Attract_DecompressStoryGfx ; what we wrote over
STZ.w MessageCursor
RTL
;--------------------------------------------------------------------------------
@@ -255,7 +251,7 @@ DialogFairyThrow:
ORA.l BottleContentsTwo : ORA.l BottleContentsThree : ORA.l BottleContentsFour : BNE .normal
.noInventory
LDA.w SpriteActivity, X : !ADD.b #$08 : STA.w SpriteActivity, X
LDA.w SpriteActivity, X : !ADD #$08 : STA.w SpriteActivity, X
LDA.b #$51
LDY.b #$01
RTL
@@ -265,14 +261,14 @@ RTL
RTL
;--------------------------------------------------------------------------------
DialogGanon1:
LDA.b #$01 : JSL CheckConditionPass
JSL.l CheckGanonVulnerability
REP #$20
LDA.w #$018C
BCC +
LDA.w #$016D
+ STA.w TextID
SEP #$20
JSL Sprite_ShowMessageMinimal_Alt
JSL.l Sprite_ShowMessageMinimal_Alt
RTL
;--------------------------------------------------------------------------------
; #$0192 - no bow
@@ -284,68 +280,31 @@ RTL
; s = silver arrow bow
; p = 2nd progressive bow
DialogGanon2:
LDA.b #$01 : JSL CheckConditionPass
JSL.l CheckGanonVulnerability
REP #$20
BCS +
LDA.w #$018D : JMP .done
+
LDA.l GanonVulnerabilityItem : AND.w #$00FF
BEQ .silver_arrows
CMP.w #$0001 : BEQ .silver_arrows
CMP.w #$0004 : BEQ .bombs
CMP.w #$0005 : BEQ .powder
CMP.w #$0010 : BEQ .bee
REP #$20
BCS +
LDA.w #$018D : BRA ++
+
LDA.l BowTracking
PHX : TAX
LDA.l EquipmentWRAM-1, X
PLX
AND.w #$00FF : BNE .have
BRA .dont_have
.silver_arrows
LDA.l BowTracking
BIT.w #$0080 : BEQ .dont_have ; no bow
BIT.w #$0040 : BNE .have ; have silvers
BIT.w #$0020 : BNE +
LDA.w #$0194 : BRA .done ; have p bow
+ LDA.w #$0193 : BRA .done ; don't have p bow
.dont_have
LDA.w #$0192 : BRA .done
.have
LDA.w #$0195 : BRA .done
.bombs
LDA.l BombsEquipment : AND.w #$00FF : BNE .have
LDA.l InfiniteBombs : AND.w #$00FF : BNE .have
BRA .dont_have
.powder
LDA.l InventoryTracking : BIT.w #$0010 : BNE .have
BRA .dont_have
.bee
LDA.l BottleContentsOne : AND.w #$00FF
CMP.w #$0007 : BEQ .have
CMP.w #$0008 : BEQ .have
LDA.l BottleContentsTwo : AND.w #$00FF
CMP.w #$0007 : BEQ .have
CMP.w #$0008 : BEQ .have
LDA.l BottleContentsThree : AND.w #$00FF
CMP.w #$0007 : BEQ .have
CMP.w #$0008 : BEQ .have
LDA.l BottleContentsFour : AND.w #$00FF
CMP.w #$0007 : BEQ .have
CMP.w #$0008 : BEQ .have
BRA .dont_have
.done
STA.w TextID
SEP #$20
JSL Sprite_ShowMessageMinimal_Alt
BIT.w #$0080 : BNE + ; branch if bow
LDA.w #$0192 : BRA ++
+
BIT.w #$0040 : BEQ + ; branch if no silvers
LDA.w #$0195 : BRA ++
+
BIT.w #$0020 : BNE + ; branch if p bow
LDA.w #$0194 : BRA ++
+
BIT.w #$0080 : BEQ + ; branch if no bow
LDA.w #$0193 : BRA ++
+
LDA.w #$016E
++
STA.w TextID
SEP #$20
JSL.l Sprite_ShowMessageMinimal_Alt
RTL
;--------------------------------------------------------------------------------
DialogEtherTablet:
@@ -407,13 +366,13 @@ DialogBombShopGuy:
+
TYA
LDY.b #$01
JSL Sprite_ShowMessageUnconditional
JSL.l Sprite_ShowMessageUnconditional
RTL
;---------------------------------------------------------------------------------------------------
AgahnimAsksAboutPed:
; seems light_speed option to change some aga text is unused for now
BRA .vanilla
LDA.l GanonVulnerableMode
CMP.b #$06 : BNE .vanilla
LDA.l OverworldEventDataWRAM+$80 ; check ped flag
AND.b #$40
@@ -423,7 +382,7 @@ AgahnimAsksAboutPed:
STA.w TextID
.vanilla
JML Sprite_ShowMessageMinimal
JML $85FA8E ; Sprite_ShowMessageMinimal
;--------------------------------------------------------------------------------
Main_ShowTextMessage_Alt:
; Are we in text mode? If so then end the routine.
@@ -515,7 +474,7 @@ Sprite_ShowSolicitedMessageIfPlayerFacing_Alt:
; Make sure that the sprite is facing towards the player, otherwise
; talking can't happen. (What sprites actually use this???)
LDA.l Sprite_ShowSolicitedMessage_Direction, X : PLX : CMP.b LinkDirection : BNE .not_facing_each_other
LDA.l $85E1A3, X : PLX : CMP.b LinkDirection : BNE .not_facing_each_other
PHY
@@ -572,7 +531,7 @@ Sprite_ShowSolicitedMessageIfPlayerFacing_PreserveMessage:
; Make sure that the sprite is facing towards the player, otherwise
; talking can't happen. (What sprites actually use this???)
LDA.l Sprite_ShowSolicitedMessage_Direction, X : PLX : CMP.b LinkDirection : BNE .not_facing_each_other
LDA.l $85E1A3, X : PLX : CMP.b LinkDirection : BNE .not_facing_each_other
PLA : XBA : PLA

View File

@@ -8,7 +8,7 @@
StoreLastOverworldDoorID:
TXA : INC
STA.l PreviousOverworldDoor
LDA.l Overworld_Entrance_ID, X : STA.w EntranceIndex
LDA.l $9BBB73, X : STA.w EntranceIndex
RTL
;--------------------------------------------------------------------------------
@@ -37,54 +37,3 @@ WalkDownIntoTavern:
CMP.b #$43
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; TurnAroundOnUnderworld
;--------------------------------------------------------------------------------
TurnAroundOnUnderworld:
LDA.b LinkPushDirection : BEQ .done
; turn around if ($010E == #$43) != ($7F5099 == #$43)
LDX.b #$00
LDA.b #$43 : CMP.w EntranceIndex : BEQ +
INX
+
CMP.l PreviousOverworldDoor : BEQ +
DEX
+
CPX.b #$00 : BEQ .done
LDA.b LinkPushDirection : EOR.b #$0C : STA.b LinkPushDirection
.done
JML Underworld_LoadCustomTileAttributes ; what we overwrote
;--------------------------------------------------------------------------------
; TurnUpOnOverworld
;--------------------------------------------------------------------------------
TurnUpOnOverworld:
LDA.l EntranceTavernBack : CMP.b #$43 : BEQ .done
LDA.b #$08 : STA.b LinkPushDirection ; only fix this glitch if exit not vanilla
.done
JML Link_HandleMovingAnimation_FullLongEntry ; what we overwrote
;--------------------------------------------------------------------------------
; WalkUpOnOverworld
;--------------------------------------------------------------------------------
WalkUpOnOverworld:
LDA.b LinkPosY : CMP.w #$091B : BNE .normal ; hardcoded Y coordinate
STZ.b LinkDirection
RTL
.normal
LDA.w #$0002 : STA.b LinkDirection ; what we overwrote
RTL
;--------------------------------------------------------------------------------
; CheckStairsAdjustment
;--------------------------------------------------------------------------------
CheckStairsAdjustment:
LDA.b RoomIndex
CMP.w #$0124 ; vanilla check, rooms $0124 to $0127 have a lower exit position (currently ER ignores the entrance location)
BCC .done
LDA.w #$FFFF-1
CMP.w TileMapEntranceDoors ; tavern back ($0696 == #$FFFF) should always have carry cleared
.done
RTL
; if carry cleared, shift position up

View File

@@ -1,51 +0,0 @@
pushpc
org $9E9463
JSL CheckKholdShellCoordinates
BCC Sprite_A3_KholdstareShell_link_not_close
BRA Sprite_A3_KholdstareShell_link_close
NOP #13
Sprite_A3_KholdstareShell_link_close = $9E9478
Sprite_A3_KholdstareShell_link_not_close = $9E9480
pullpc
CheckKholdShellCoordinates:
LDA.w SpritePosXHigh, X
XBA
LDA.w SpritePosXLow, X ; full 16 bit X coordinate of sprite
REP #$21 ; carry is guaranteed clear
SBC.w #$0020
CMP.b LinkPosX
BCS .not_colliding
ADC.w #$0040 ; carry is guaranteed clear
CMP.b LinkPosX
BCC .not_colliding
SEP #$20
LDA.w SpritePosYHigh, X
XBA
LDA.w SpritePosYLow, X ; full 16 bit Y coordinate of sprite
REP #$21 ; carry is guaranteed clear
SBC.w #$001F ; could go to 27 and still let link squeeze in
CMP.b LinkPosY
BCS .not_colliding
ADC.w #$0037 ; carry is guaranteed clear
CMP.b LinkPosY
BCC .not_colliding
SEP #$20 ; collision detected
SEC
RTL
.not_colliding
SEP #$30
CLC
RTL

View File

@@ -1,59 +0,0 @@
; Free RAM notes
; Normal doors use $AB-AC for scrolling indicator
; Normal doors use $FE to store the trap door indicator
; Normal doors use $045e to store Y coordinate when transitioning to in-room stairs
; Normal doors use $045f to determine the order in which supertile quadrants are drawn
; Straight stairs use $046d to store X coordinate on animation start
; Spiral doors use $045e to store stair type
; Gfx uses $b1 to for sub-sub-sub-module thing
; Hooks into various routines
incsrc drhooks.asm
;Main Code
org $A78000 ;138000
db $44, $52 ;DR
DRMode:
dw 0
; xxpg rmse
; xxxx xBDM
; x - unused
; p - use the original palette for the dungeon rooms instead of the DR table
; g - fix the EG glitch in more places (should be off for no logic)
; r - The collection rate flag
; m - Whether to display keys Map Info
; s - Start with Mirror Scroll
; e - GT minibosses marked as defeated instead of spawning heart container in all dungeons
; B - Big Key doors can displayed and be opened on the "south" side in addition
; D - Enabled spawning as a bunny in the Dark World underworld
; M - hides the total number in the collection rate
DRFlags:
dw 0
DRScroll:
db 0
OffsetTable:
dw -8, 8
org $A78010
DRVersionInfo:
dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000
org $A78020
incsrc normal.asm
incsrc scroll.asm
incsrc spiral.asm
incsrc gfx.asm
incsrc keydoors.asm
incsrc overrides.asm
incsrc edges.asm
incsrc math.asm
incsrc hudadditions.asm
incsrc dr_lobby.asm
incsrc entrance_fixes.asm
incsrc bugfix/kholdstare_shell_collision.asm
warnpc $A79C00
incsrc doortables.asm
warnpc $A88000

View File

@@ -1,699 +0,0 @@
org $A79C00
KeyDoorOffset:
; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler
dw $0000,$0001,$0003,$0000,$0006,$0000,$000b,$0000,$0000,$0000,$000c,$000d,$0010,$0011,$0012,$0000
dw $0000,$0015,$0018,$001c,$001e,$0025,$0027,$0000,$0000,$002b,$002d,$0033,$0035,$0038,$0039,$003d
dw $003f,$0040,$0043,$0045,$0047,$0000,$004f,$0000,$0053,$0000,$0055,$005b,$0000,$0000,$005f,$0000
dw $0060,$0062,$0064,$0065,$0066,$0068,$006e,$0074,$007a,$007c,$007e,$0081,$0000,$0082,$0086,$0088
dw $0089,$008a,$0000,$008b,$008e,$0092,$0096,$0000,$0000,$0099,$009d,$00a2,$00a5,$00a6,$00a8,$00aa
dw $00ab,$00ad,$00af,$00b2,$0000,$0000,$00b5,$00b9,$00bf,$00c5,$00c9,$00ca,$00cc,$00ce,$00d1,$00d5
dw $00d6,$00dc,$00e3,$00e9,$00ec,$00ed,$00ee,$00f2,$00f5,$0000,$00f7,$00f8,$00fc,$00ff,$0102,$0000
dw $0000,$0103,$0106,$0107,$010a,$010c,$010e,$0112,$0000,$0000,$0000,$0114,$0117,$011b,$011e,$0121
dw $0000,$0123,$0000,$0124,$0127,$0128,$0000,$012c,$0000,$0000,$0000,$012e,$0133,$0139,$013e,$0000
dw $013f,$0140,$0141,$0146,$0000,$0149,$014b,$014d,$014f,$0150,$0000,$0153,$0156,$015a,$015d,$0161
dw $0163,$0164,$0166,$016a,$016c,$016d,$0000,$0000,$0170,$0176,$017c,$0182,$0184,$0000,$0185,$0186
dw $0188,$018b,$018f,$0197,$019c,$019d,$019e,$01a3,$01a4,$01a6,$01aa,$01ad,$01b3,$0000,$01bb,$01be
dw $01bf,$01c2,$01ca,$01d2,$01d9,$01da,$01dd,$01e3,$01e6,$01e7,$0000,$01ec,$01ed,$0000,$01f0,$0000
dw $01f1,$01f3,$01f7,$0000,$0000,$01f8,$01fa,$0000,$01fd,$0200,$0203,$0204,$0206,$0000,$0000,$0000
dw $0207
org $A79E00
SpiralOffset:
; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler
db $00,$01,$02,$00,$03,$00,$00,$04,$00,$05,$07,$00,$08,$00,$0b,$00
db $00,$0c,$00,$00,$00,$0d,$0e,$0f,$00,$00,$11,$00,$13,$14,$15,$00
db $00,$00,$00,$00,$00,$00,$16,$19,$1b,$00,$00,$00,$00,$00,$00,$00
db $00,$1c,$00,$00,$1f,$00,$00,$00,$20,$00,$21,$00,$00,$00,$00,$22
db $23,$24,$25,$00,$00,$26,$00,$00,$00,$00,$27,$00,$29,$2a,$2b,$00
db $00,$00,$00,$2c,$2d,$00,$00,$00,$00,$00,$00,$00,$2e,$2f,$00,$30
db $00,$00,$00,$35,$36,$00,$37,$00,$00,$00,$38,$3a,$3b,$00,$3c,$00
db $3d,$40,$41,$00,$00,$00,$42,$45,$00,$00,$00,$00,$00,$00,$00,$49
db $4a,$00,$00,$00,$00,$00,$00,$4b,$00,$00,$00,$00,$4f,$00,$53,$00
db $00,$54,$00,$55,$00,$00,$00,$56,$57,$58,$00,$00,$00,$00,$59,$00
db $5a,$00,$5b,$00,$00,$5c,$5d,$00,$00,$00,$00,$5e,$00,$00,$5f,$00
db $60,$00,$00,$00,$00,$63,$64,$00,$00,$00,$00,$00,$65,$00,$66,$00
db $67,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $6a,$6d,$6e,$00,$00,$00,$00,$00,$00,$00,$6f,$00,$00,$00,$00,$00
db $70
org $A79F00
DoorOffset:
db $00,$01,$02,$00,$03,$00,$04,$00,$00,$00,$00,$00,$9A,$05,$99,$00
db $00,$06,$07,$08,$09,$0A,$0B,$00,$00,$0C,$0D,$0E,$00,$0F,$10,$11
db $12,$13,$14,$15,$16,$00,$17,$00,$98,$00,$18,$19,$00,$00,$1A,$00
db $1B,$00,$1C,$1D,$1E,$1F,$20,$21,$22,$23,$24,$25,$00,$26,$27,$00
db $96,$28,$97,$29,$2A,$2B,$2C,$00,$00,$2D,$2E,$2F,$30,$31,$32,$00
db $33,$34,$35,$36,$00,$00,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F,$40
db $41,$42,$43,$A0,$00,$00,$44,$45,$46,$00,$47,$48,$49,$4A,$4B,$00
; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler
db $00,$4C,$00,$00,$00,$4D,$4E,$9E,$00,$00,$00,$4F,$50,$51,$52,$53
db $00,$54,$00,$9C,$9D,$55,$00,$00,$00,$00,$00,$56,$57,$58,$59,$00
db $5A,$5B,$5C,$5D,$00,$5E,$5F,$00,$9B,$60,$00,$61,$62,$63,$64,$65
db $66,$67,$68,$69,$6A,$6B,$00,$00,$6C,$6D,$6E,$6F,$70,$00,$71,$72
db $00,$73,$74,$75,$76,$77,$78,$79,$7A,$7B,$7C,$7D,$7E,$00,$7F,$80
db $00,$81,$82,$83,$84,$85,$86,$87,$88,$89,$00,$8A,$8B,$00,$8C,$00
db $00,$8D,$8E,$00,$00,$8F,$90,$00,$91,$92,$93,$94,$95,$00,$00,$00
db $9f
org $A7A000
DoorTable:
;; NW 00 N 01 NE 02 WN 00 W 01 WS 02 SW 00 S 01 SE 02 EN 00 E 01 ES 02 - Door ruler
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Default/Garbage row
dw $0003, $0003, $0003, $0450, $0003, $0003, $0003, $0003, $0003, $0452, $0003, $0003 ; HC Back Hall (x01)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Switches (x02)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Crystaroller
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Arghus
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Aga 2
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Secret Room
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sanc
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Pokey
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Lava Pipe
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Pipes n Ledge
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swap Canal
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod dark Maze
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Bridge
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Eye Statue
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Pre Aga
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Cross
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice BK
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x20 Aga1
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Key Rat
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Waters
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Eye Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Chest Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Statue
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; PoD Arena (x2a)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; PoD Statue (x2b)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Compass
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x30 Aga's Altar
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Dark Cross
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Lanmolas
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp West Wing
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Flooded Key
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Main Hub (x36)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Hammer Time
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp First Basement
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Drop to the Moth
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod 3 Catwalks
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Conveyor
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Minihelma
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Conveyor
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewers
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Torches
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Big Chest
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Cellblock
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Compass Loop
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull3 Torches
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Mimics 1
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Conveyor Ice
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Moldorm
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; IPBJ
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0401, $0003, $0003 ; HC West Hall (x50)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC Throne Room (x51)
dw $0003, $0003, $0003, $0401, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC East Hall (x52)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Tiles 1
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull 2 Left Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull 2 Right Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull 1 Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull 3 Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Helmasaur
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Spike Switch
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Cannonball
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Gauntlet 1
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Choice Cross
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Iced U
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC West Lobby (x60)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC Main Lobby (x61)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC East Lobby (x62)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x66 Swamp Waterfall
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x67 Skull 1 Left Drop
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x68 Skull 1 Pinball
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6a Pod Rupees
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6b GT Mimics
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6c GT Lanmolas
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6d Gauntlet 2
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6e Ice Gators
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC Armory
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert BK Chest
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Flooded Chests
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT DM's Tile
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Randoroom
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Warp Maze
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Freezors
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Hookpit
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC Catawalk
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Right Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Left
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Hopeful Torch
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Right
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Lonely Freezor
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Vitreous (x90)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Rain
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Dark Crystals
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Blockswitch
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Fallbridge
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Torch Cross
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Darkness
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Warp Maze 2
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Invis Bridge
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Compass Room
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Big Chests
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Icy Pots
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Pre-Vitreous (xa0)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Fishbone
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Bridges
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Corner
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Trinexx (xa4)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Wizzrobes
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Compass (xa8)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Courtyard (xa9)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Map (xaa)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Switch
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Blind
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Iced T
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Slipway
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Warpzone
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire ????
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Spikes
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Refill
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Dark Maze
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Chainchomp
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Rollers
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Big Key
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Easter Cannonball
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Dark Circle
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Hellway
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Bossway
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Blockswitch
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Backtracker
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Tiles
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Main Hub
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Big Chest
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Switch Maze
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Narrow
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Early Hub
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Floating Torches
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Armos
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT NW Quad
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT NE Quad
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Boss Drop
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire BK
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire 2
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Laser Bridge
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Main Entrance
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Eyegores
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Attic Switches
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Attic Start
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Entrance Quad
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT SE Quad
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Aga 6F
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewers Rope
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Lobby
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Lobby
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Lobby
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Lobby
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert West Lobby
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Main Lobby
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Hera Lobby
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Tower Lobby
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Back Lobby
; this should end at 27AF18 about (160 * 24 bytes = 3840 or F18)
; some values you can hardcode for spirals
;dw $0070, $36a0 ; ->HC Stairwell
;dw $0072, $4ff8 ; ->HC Map Room
;dw $0080, $1f50 ; ->zelda's cellblock
org $A7B000
SpiralTable: ;113 4 byte entries - should end at 27B1C4
dw $0203, $8080 ;null row
dw $0203, $8080 ;HC Backhallway
dw $0203, $8080 ;Sewer Pull
dw $0203, $8080 ;Crystaroller
dw $0203, $8080 ;Moldorm
dw $0203, $8080, $0203, $8080 ;Pod Basement
dw $0203, $8080 ;Pod Stalfos
dw $0203, $8080, $0203, $8080, $0203, $8080 ;GT Entrance
dw $0203, $8080 ;Ice Entrance
dw $0203, $8080 ;Escape
dw $0203, $8080 ;TR Pipe Ledge
dw $0203, $8080 ;Swamp Way
dw $0203, $8080, $0203, $8080 ;Hera Fallplace
dw $0203, $8080, $0203, $8080 ;PoD Bridge
dw $0203, $8080 ;GT Ice
dw $0203, $8080 ;GT F8
dw $0203, $8080 ;Ice Cross
dw $0203, $8080, $0203, $8080, $0203, $8080 ;Swamp Statue
dw $0203, $8080, $0203, $8080 ;Hera Big
dw $0203, $8080 ;Swamp Ent
dw $0203, $8080, $0203, $8080, $0203, $8080 ;Hera Startiles (middle value unused)
dw $0203, $8080 ;West Swamp
dw $0203, $8080 ;Swamp Basement
dw $0203, $8080 ;Pod Drops
dw $0203, $8080 ;Ice Hammer
dw $0203, $8080 ;Aga Guards
dw $0203, $8080 ;Sewer Begin
dw $0203, $8080 ;Sewer Rope
dw $0203, $8080 ;TT Cellblock
dw $0203, $8080, $0203, $8080 ;Pod Entrance
dw $0203, $8080 ;GT Icespike
dw $0203, $8080 ;GT Moldorm
dw $0203, $8080 ;IPBJ
dw $0203, $8080 ;Desert Prep
dw $0203, $8080 ;Swamp Attic
dw $0203, $8080 ;GT Cannonball
dw $0203, $8080 ;GT Gauntlet1
dw $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080 ;Ice U (1st three values unused)
dw $0203, $8080 ;Desert Back
dw $0203, $8080 ;TT Attic L
dw $0203, $8080 ;Swamp Waterf
dw $0203, $8080 ;Pod Rupees
dw $0203, $8080 ;Pod Rupees
dw $0203, $8080 ;GT Mimics
dw $0203, $8080 ;GT Lanmo
dw $0203, $8080 ;Ice Gators
dw $0203, $8080, $0203, $8080, $0203, $8080 ;HC Tiny (first value placeholder)
dw $0203, $8080 ;HC Boomer
dw $0203, $8080 ;HC Pits1
dw $0203, $8080, $0203, $8080, $0203, $8080 ;Swamp Sunken
dw $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080 ;Hera Entrance (first value unused)
dw $0203, $8080 ;Ice Hookshot
dw $0203, $8080 ;HC Cellblock
dw $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080 ;Hera Basement (first and third values unused)
dw $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080 ;GT Circle (third value unused)
dw $0203, $8080 ;Ice Last Freeze
dw $0203, $8080 ;Mire Drops
dw $0203, $8080 ;Mire Block
dw $0203, $8080 ;Mire Attic
dw $0203, $8080 ;Mire Entrance
dw $0203, $8080 ;East Dark
dw $0203, $8080 ;Ice Big
dw $0203, $8080 ;Mire Previtreous
dw $0203, $8080 ;Mire Bridges
dw $0203, $8080 ;GT Wizzrobes
dw $0203, $8080 ;GT Spikepit
dw $0203, $8080 ;TT Switch
dw $0203, $8080 ;Ice T
dw $0203, $8080, $0203, $8080, $0203, $8080 ;Tower Usains (2nd value unused)
dw $0203, $8080 ;TR PlatMaze
dw $0203, $8080 ;TR Chainchomp
dw $0203, $8080 ;TT Bossway
dw $0203, $8080 ;Ice FallZone
dw $0203, $8080, $0203, $8080, $0203, $8080 ;Tower Dark2 (2nd value unused)
dw $0203, $8080, $0203, $8080, $0203, $8080 ;Tower Dark1 (2nd value unused)
dw $0203, $8080 ;Mire BK Thang
dw $0203, $8080 ;Mire2
dw $0203, $8080 ;East Attic Start
dw $0203, $8080 ;Tower Entrance
org $A7C000 ;ends around 27C418
PairedDoorTable:
dw $0000 ; the bad template
dw $0000,$0000
dw $0000,$0000,$0000
dw $0000,$0000,$0000,$0000,$0000
dw $0000
dw $0000
dw $0000,$0000,$0000
dw $0000
dw $0000
dw $0000,$0000,$0000
dw $0000,$0000,$8021
dw $0000,$0000,$0000,$0000
dw $4014,$0000
dw $8024,$8013,$0000,$0000,$0000,$0000,$0000
dw $0000,$0000
dw $0000,$0000,$0000,$0000
dw $201a,$401a
dw $0000,$4019,$8019,$402a,$0000,$0000
dw $0000,$0000
dw $0000,$0000,$0000
dw $0000
dw $0000,$0000,$0000,$0000
dw $0000,$0000
dw $0000
dw $2011,$0000,$0000
dw $8032,$0000
dw $0000,$0000
dw $8014,$0000,$0000,$0000,$0000,$0000,$0000,$0000
dw $4036,$0000,$0000,$0000
dw $0000,$0000
dw $0000,$101a,$402b,$0000,$0000,$0000
dw $0000,$202a,$0000,$0000
dw $0000
dw $0000,$0000
dw $0000,$0000
dw $8022
dw $0000
dw $0000,$0000
dw $2036,$0000,$0000,$0000,$0000,$0000
dw $8037,$8026,$8035,$0000,$0000,$0000
dw $8036,$8038,$0000,$4038,$0000,$0000
dw $4037,$1037
dw $0000,$0000
dw $204a,$0000,$0000
dw $0000
dw $0000,$0000,$804d,$0000
dw $0000,$404e
dw $0000
dw $0000
dw $0000
dw $0000,$0000,$2053
dw $0000,$0000,$0000,$0000
dw $0000,$0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000,$0000,$8059,$0000
dw $0000,$0000,$803a,$0000,$0000
dw $0000,$0000,$0000
dw $0000
dw $203d,$0000
dw $0000,$403e
dw $0000 ; this is the odd extra room - shouldn't be used
dw $0000,$0000
dw $0000,$0000
dw $0000,$0000,$0000
dw $0000,$0000,$2043
dw $0000,$0000,$0000,$0000
dw $0000,$0000,$4058,$0000,$0000,$0000
dw $0000,$2057,$4068,$0000,$0000,$0000
dw $2049,$0000,$0000,$0000
dw $0000
dw $806b,$0000
dw $0000,$0000
dw $0000,$0000,$0000
dw $805f,$0000,$0000,$0000
dw $805e
dw $0000,$0000,$0000,$0000,$0000,$0000
dw $0000,$0000,$0000,$0000,$0000,$0000,$0000
dw $0000,$0000,$0000,$0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000
dw $0000
dw $0000,$0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000,$2058
dw $0000
dw $805b,$0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000
dw $0000,$0000,$0000
dw $0000
dw $0000,$0000,$0000
dw $0000,$0000
dw $0000,$0000
dw $0000,$0000,$0000,$0000
dw $0000,$0000
dw $0000,$207c,$0000
dw $0000,$407d,$407b,$0000
dw $0000,$407c,$0000
dw $808e,$0000,$0000
dw $0000,$0000
dw $0000
dw $0000,$0000,$0000
dw $0000
dw $0000,$0000,$0000,$0000
dw $0000,$0000
dw $0000,$0000,$0000,$0000,$0000
dw $0000,$0000,$0000,$0000,$0000,$0000
dw $0000,$0000,$0000,$0000,$0000
dw $807e
dw $0000
dw $0000
dw $0000,$0000,$0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000,$0000
dw $0000,$0000
dw $0000,$0000
dw $0000
dw $0000,$20a9,$0000
dw $0000,$0000,$0000
dw $0000,$0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000,$0000,$0000,$0000
dw $0000,$0000
dw $0000
dw $40b1,$0000
dw $80b2,$0000,$0000,$0000
dw $0000,$0000
dw $0000
dw $0000,$0000,$0000
dw $0000,$0000,$80b8,$0000,$0000,$0000
dw $0000,$0000,$4099,$0000,$0000,$0000
dw $0000,$0000,$0000,$0000,$0000,$0000
dw $0000,$0000
dw $0000
dw $0000
dw $0000,$0000
dw $0000,$0000,$0000
dw $0000,$80a1,$0000,$0000
dw $80a2,$0000,$0000,$0000,$0000,$0000,$0000,$0000
dw $0000,$0000,$0000,$0000,$0000
dw $0000
dw $0000
dw $0000,$0000,$80c6,$0000,$0000
dw $0000
dw $20a8,$0000
dw $80ba,$0000,$0000,$0000
dw $80b9,$0000,$0000
dw $0000,$0000,$0000,$0000,$0000,$0000
dw $0000,$80cc,$0000,$40cc,$0000,$0000,$0000,$0000
dw $0000,$80bf,$0000
dw $40be
dw $0000,$0000,$0000
dw $0000,$40c2,$0000,$0000,$0000,$0000,$0000,$0000
dw $80c3,$40c1,$0000,$0000,$0000,$0000,$0000,$0000
dw $80c2,$0000,$0000,$0000,$0000,$0000,$0000
dw $80c5
dw $80c4,$0000,$0000
dw $20b6,$0000,$0000,$0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000
dw $0000,$0000,$0000,$0000,$0000
dw $20cc
dw $40bc,$10bc,$80cb
dw $0000
dw $0000,$0000
dw $0000,$0000,$0000,$0000
dw $0000
dw $0000,$0000
dw $0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000,$0000,$0000
dw $0000
dw $0000,$0000
dw $0000
dw $0000,$0000,$0000,$0000
dw $ffff ; indicates the end - we can drop this
; Edge Transition Table (Target Room, Flags, MultiDiv ratio for edges)
org $A7C500 ;ends around 27C5F(9) 4 bytes would be 27C649
;I kind of want to split the 3rd byte into two
NorthOpenEdge:
db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11
db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11
db $00,$80,$11, $00,$80,$11, $00,$80,$11
SouthOpenEdge:
db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11
db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11
db $00,$80,$11, $00,$80,$11, $00,$80,$11
WestOpenEdge:
db $00,$80,$11, $00,$80,$11, $00,$80,$11
db $00,$80,$11, $00,$80,$11, $00,$80,$11
db $00,$80,$11, $00,$80,$11, $00,$80,$11
EastOpenEdge:
db $00,$80,$11, $00,$80,$11, $00,$80,$11
db $00,$80,$11, $00,$80,$11, $00,$80,$11
db $00,$80,$11, $00,$80,$11, $00,$80,$11
; Edge Info Table (Midpoint, Width, Min Coord)
; I kind of want to add a fourth byte to help indicate quadrant info on min coord
NorthEdgeInfo:
db $a8,$10,$a0, $2c,$08,$28 ;HC
db $b8,$20,$a8 ; DP West Wing
db $38,$20,$28, $f8,$a0,$a8, $b8,$20,$a8 ; DP Main
db $78,$20,$68 ; DP East Wing
db $f8,$10,$f0, $7c,$18,$70 ; TT Lobby
db $74,$18,$68, $f8,$10,$f0 ; TT Compass
SouthEdgeInfo:
db $a8,$10,$a0, $2c,$08,$28 ; HC
db $b8,$20,$a8 ; DP Sandworm
db $38,$20,$28, $f8,$a0,$a8, $b8,$20,$a8 ; DP North Hall & Dead End
db $78,$20,$68 ; DP Arrow Pot
db $f8,$10,$f0, $7c,$18,$70 ; TT Ambush
db $74,$18,$68, $f8,$10,$f0 ; TT BK Corner
WestEdgeInfo:
db $78,$30,$60 ; TT Attic
db $40,$20,$30 ; DP North Hall
db $40,$20,$30 ; DP Arrow Pot
db $84,$18,$78, $68,$10,$60 ; HC South
db $a0,$a0,$50 ; DP East Wing
db $58,$50,$30, $98,$50,$70 ; TT BK Corner
db $58,$50,$30 ; TT Compass
EastEdgeInfo:
db $78,$30,$60 ; TT Attic
db $40,$20,$30 ; DP Sandworm
db $40,$20,$30 ; DP North Hall
db $68,$10,$60, $84,$18,$78 ; HC Guards
db $a0,$a0,$50 ; DP Main Lobby
db $58,$50,$30, $98,$50,$70 ; TT Ambush
db $58,$50,$30 ; TT Nook
MultDivInfo: ; (1, 2, 3, 4, 5, 6, 10, 20)
db $01, $02, $03, $04, $05, $06, $0a, $14
; indices: 0-7
; In-room stairs in North/South pairs. From left to right:
; PoD, IP right side, IP Freezor chest and GT
org $A7C700
InroomStairsTable:
dw $0003,$0003, $0003,$0003, $0003,$0003, $0003,$0003
org $A7C720
InroomStairsRoom:
db $0B,$1B, $3F,$1F, $7E,$5E, $96,$3D
InroomStairsX:
dw $0190, $0160, $0040, $0178
InroomStairsY:
dw $0058, $0148, $0198, $0190
org $A7E000
CutoffRooms:
; TT Alcove, Mire Bridge Left & Right, Mire Bent Bridge, Mire Hub
; Pod Falling & Harmless, SW Star Pits, TR Lava Escape & TR Dual Pipes, Bob's Room & GT Big Chest
dw $00bc, $00a2, $00a3, $00c2, $001a, $0049, $0014, $008c
; Ice Many Pots, Swamp Waterfall, GT Gauntlet 3, Eastern Push Block, Eastern Courtyard, Eastern Map Valley
; Eastern Cannonball, HC East Hall
dw $009f, $0066, $005d, $00a8, $00a9, $00aa, $00b9, $0052
; HC West Hall, TR Dash Bridge, TR Hub, Pod Arena, GT Petting Zoo, Ice Spike Cross
dw $0050, $00c5, $00c6, $0009, $0003, $002a, $007d, $005e
; Sewer Drop, Mire Cross, GT Crystal Circles
dw $0011, $00b2, $003d
dw $ffff
; dungeon tables
; HC HC EP DP AT SP PD MM SW IP TH TT TR GT
org $A7f000
CompassBossIndicator:
dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000
TotalKeys: ;27f020
db $04, $04, $02, $04, $04, $06, $06, $06, $05, $06, $01, $03, $06, $08, $00, $00
skip $10
;ChestKeys: ;27f030 - moved to B0F010
;db $01, $01, $00, $01, $02, $01, $06, $03, $03, $02, $01, $01, $04, $04, $00, $00
BigKeyStatus: ;27f040 (status 2 indicate BnC guard)
dw $0002, $0002, $0001, $0001, $0000, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0000, $0000
DungeonReminderTable: ;27f060
dw $2D50, $2D50, $2D51, $2D52, $2D54, $2D56, $2D55, $2D5A, $2D57, $2D59, $2D53, $2D58, $2D5B, $2D5C, $0000, $0000
TotalLocationsLow: ;27f080
db $08, $08, $06, $06, $02, $00, $04, $08, $08, $08, $06, $08, $02, $07, $00, $00
TotalLocationsHigh: ;27f090
db $00, $00, $00, $00, $00, $01, $01, $00, $00, $00, $00, $00, $01, $02, $00, $00
org $A7f0a0
TotalLocations:
db $08, $08, $06, $06, $02, $0a, $0e, $08, $08, $08, $06, $08, $0c, $1b, $00, $00
; no more room here
; Vert 0,6,0 Horz 2,0,8
org $A7f0b0
CoordIndex: ; Horizontal 1st
db 2, 0 ; Coordinate Index $20-$23
OppCoordIndex:
db 0, 2 ; Swapped coordinate Index $20-$23 (minor optimization)
CameraIndex: ; Horizontal 1st
db 0, 6 ; Camera Index $e2-$ea
CamQuadIndex: ; Horizontal 1st
db 8, 0 ; Camera quadrants $600-$60f
ShiftQuadIndex:
db 2, 1 ; see ShiftQuad func (relates to $a9,$aa)
CamBoundIndex: ; Horizontal 1st
db 0, 4 ; Camera Bounds $0618-$61f
OppCamBoundIndex: ; Horizontal 1st
db 4, 0 ; Camera Bounds $0618-$61f
CamBoundBaseLine: ; X camera stuff is 1st column todo Y camera needs more testing
dw $007f, $0077 ; Left/Top camera bounds when at edge or layout frozen
dw $0007, $000b ; Left/Top camera bounds when not frozen + appropriate low byte $22/$20 (preadj. by #$78/#$6c)
dw $00ff, $010b ; Right/Bot camera bounds when not frozen + appropriate low byte $20/$22
dw $017f, $0187 ; Right/Bot camera bound when at edge or layout frozen
;27f0ce next free byte
org $A7f0f0
RemoveRainDoorsRoom:
dw $0060, $0062, $ffff ; ffff indicates end of list
RainDoorMatch: ; org $A7f0f6 and f8 for now
dw $0081, $0061 ; not xba'd
BlockSanctuaryDoorInRain: ;27f0fa
dw $0000
org $A7f100
TilesetTable:
; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler
db $13,$04,$04,$06,$0d,$ff,$08,$05,$06,$07,$07,$07,$0e,$0e,$0b,$ff
db $13,$04,$04,$0d,$0d,$0d,$08,$05,$06,$07,$07,$07,$0e,$0e,$0b,$0b
db $04,$04,$04,$0d,$0d,$ff,$08,$05,$08,$09,$07,$07,$06,$ff,$0b,$06
db $04,$05,$04,$12,$08,$08,$08,$08,$08,$09,$07,$07,$06,$0e,$0b,$0b
db $04,$04,$04,$12,$0a,$0a,$08,$ff,$ff,$09,$07,$07,$0e,$0e,$0b,$0b
db $04,$04,$04,$12,$08,$01,$09,$09,$09,$09,$07,$0e,$0e,$0e,$0b,$0b
db $04,$04,$04,$12,$0a,$0a,$08,$09,$09,$ff,$07,$0e,$0e,$0e,$0b,$ff
db $04,$04,$04,$12,$12,$12,$08,$05,$ff,$ff,$ff,$0e,$0e,$0e,$0b,$0b
db $04,$04,$04,$12,$12,$12,$ff,$05,$ff,$05,$ff,$0e,$0e,$0e,$0b,$ff
db $0c,$0c,$0c,$0c,$ff,$0e,$0e,$0c,$0c,$05,$ff,$0e,$0e,$0e,$0b,$0b
db $0c,$0c,$0c,$0c,$0d,$0e,$0e,$05,$05,$05,$05,$0a,$0a,$ff,$0b,$0b
db $04,$0c,$0c,$0c,$0d,$0d,$0d,$0d,$05,$05,$05,$0a,$0a,$ff,$0b,$0b
db $04,$0c,$0c,$0c,$0d,$0d,$0d,$0d,$05,$05,$ff,$0a,$0a,$ff,$0b,$ff
db $04,$0c,$0c,$ff,$ff,$0d,$0d,$ff,$05,$05,$05,$0a,$0a,$ff,$0b,$06
db $04,$06,$06,$06,$06,$06,$06,$06,$06,$ff,$06,$06,$ff,$06,$06,$06
db $06,$06,$03,$03,$03,$03,$ff,$ff,$06,$06,$06,$06,$ff,$06,$06,$06
;27f200
PaletteTable:
db $21,$00,$00,$07,$00,$08,$00,$00,$07,$00,$00,$00,$00,$00,$00,$21
db $21,$00,$00,$00,$00,$00,$00,$00,$07,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$0e,$00,$00,$07,$00,$00,$07
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$07,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$13
db $00,$00,$00,$00,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler
db $00,$00,$00,$00,$00,$00,$00,$06,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$14,$20
db $00,$07,$20,$20,$07,$07,$07,$07,$07,$20,$20,$07,$20,$20,$20,$20
db $07,$07,$02,$02,$02,$02,$07,$07,$07,$20,$20,$07,$20,$20,$20,$07
;A7f300
DungeonTilesets:
db $04,$04,$05,$12,$04,$08,$07,$0C,$09,$0B,$05,$0A,$0D,$0E,$06,$06
;
;org $A7ff00
org $A7fff0
LinksHouseDarkWorld:
dw $ffff
SanctuaryDarkWorld:
dw $ffff
OldManDarkWorld:
dw $ffff
OldManRetrievalWorld:
dw $0000

View File

@@ -1,23 +0,0 @@
CheckDarkWorldSpawn:
PHP
STA.b RoomIndex : STA.w RoomIndexMirror ; what we wrote over
JSL SetDefaultWorld
LDA.l LinksHouseDarkWorld : CMP.b RoomIndex : BEQ ++
LDA.l SanctuaryDarkWorld : CMP.b RoomIndex : BEQ ++
LDA.l OldManDarkWorld : CMP.b RoomIndex : BNE +
++ SEP #$20 : LDA.l CurrentWorld : EOR.b #$40 : STA.l CurrentWorld
LDA.l DRFlags+1 : AND.b #$02 : BEQ + ; skip if the flag isn't set
LDA.l MoonPearlEquipment : BNE + ; moon pearl?
LDA.b #$17 : STA.b LinkState : INC.w BunnyFlag
+ PLP : RTL
SetDefaultWorld:
PHP : SEP #$20
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ .default
LDA.l FollowerIndicator : CMP.b #$04 : BNE .default
LDA.l OldManRetrievalWorld : BRA +
.default
LDA.l InvertedMode : BEQ +
LDA.b #$40
+ STA.l CurrentWorld
PLP : RTL

View File

@@ -1,221 +0,0 @@
org $82b5c4 ; -- moving right routine 135c4
jsl WarpRight
org $82b665 ; -- moving left routine
jsl WarpLeft
org $82b713 ; -- moving down routine
jsl WarpDown
org $82b7b4 ; -- moving up routine
jsl WarpUp
org $82bd80
jsl AdjustTransition
nop
;turn off linking doors -- see .notRoomLinkDoor label in Bank02.asm
org $82b5a8 ; <- 135a8 - Bank02.asm : 8368 (LDA $7EC004 : STA $A0)
jsl CheckLinkDoorR
bcc NotLinkDoor1
org $82b5b6
NotLinkDoor1:
org $82b649 ; <- 135a8 - Bank02.asm : 8482 (LDA $7EC004 : STA $A0)
jsl CheckLinkDoorL
bcc NotLinkDoor2
org $82b657
NotLinkDoor2:
; Staircase routine
org $81c3d4 ; <- c3d4 - Bank01.asm : 9762-4 (Dungeon_DetectStaircase-> STA $A0 : LDA $063D, X)
jsl RecordStairType : nop
org $82a1e7 ;(PC: 121e7)
jsl SpiralWarp
org $8291b3 ; <- Bank02.asm : 3303 (LDA $0462 : AND.b #$04)
jsl SpiralPriorityHack : nop
org $8290f9 ; <- Bank02.asm : 3188 (LDA $0462 : AND.b #$04)
jsl SpiralPriorityHack : nop
org $829369 ; <- 11369 - Bank02.asm : 3610 (STX $0464 : STY $012E)
jsl StraightStairsAdj : nop #2
org $829383 ; <- 11384 - Bank02.asm : 3629 (.walkingDownStaircase-> ADD $20 : STA $20)
jsl StraightStairsFix : nop
org $8293aa ; <- 113aa - Bank02.asm : 3653 (ADD $20 : STA $20)
jsl StraightStairsFix : nop
org $8293d1 ; <- 113d1 - Bank02.asm : 3683 (ADD $20 : STA $20 BRANCH_IOTA)
jsl StraightStairsFix : nop
org $829396 ; <- 11396 - Bank02.asm : 3641 (LDA $01C322, X)
jsl StraightStairLayerFix
org $82c06d ; <- Bank02.asm : 9874 (LDX $0418, CMP.b #$02)
jsl DoorToStraight : nop
org $82c092 ; STA $0020, Y : LDX #$00
jsl DoorToInroom : nop
org $82c0f8 ; CMP $02C034, X
jsl DoorToInroomEnd
org $82941a ; <- Bank02.asm : 3748 module 7.12.11 (LDA $0464 : BNE BRANCH_$11513 : INC $B0 : RTS)
jsl StraightStairsTrapDoor : rts
org $828b54 ; <- Bank02.asm : 2200 (JSL UseImplicitRegIndexedLocalJumpTable)
jsl InroomStairsTrapDoor
org $82c146
jsl HandleSpecialDoorLanding
org $8289a0 ; JSL $0091C4
jsl QuadrantLoadOrderBeforeScroll
org $82bd9c ; JSL $0091C4
jsl QuadrantLoadOrderAfterScroll
; Graphics fix
org $82895d ; Bank 02 line 1812 (JSL Dungeon_LoadRoom : JSL Dungeon_InitStarTileChr : JSL $00D6F9 : INC $B0)
Splicer:
jsl GfxFixer
lda.b $b1 : beq .done
rts
nop #5
.done
org $81b618 ; Bank01.asm : 7963 Dungeon_LoadHeader (REP #$20 : INY : LDA [$0D], Y)
nop : jsl OverridePaletteHeader
org $82817e ; Bank02.asm : 414 (LDA $02811E, X)
jsl FixAnimatedTiles
org $8aef43 ; UnderworldMap_RecoverGFX
jsl FixCloseDungeonMap
org $828a06 ; Bank02.asm : 1941 Dungeon_ResetTorchBackgroundAndPlayer
JSL FixWallmasterLamp
org $80d377 ;Bank 00 line 3185
DecompDungAnimatedTiles:
org $80fda4 ;Bank 00 line 8882
Dungeon_InitStarTileCh:
org $80d6ae ;(PC: 56ae)
LoadTransAuxGfx:
org $80d739 ;
LoadTransAuxGfx_Alt:
org $80df5a ;(PC: 5f5a)
PrepTransAuxGfx:
org $8ffd65 ;(PC: 07fd65)
Dungeon_LoadCustomTileAttr:
org $81feb0
Dungeon_ApproachFixedColor:
;org $81fec1
;Dungeon_ApproachFixedColor_variable:
;org $a0f972 ; Rando version
;LoadRoomHook:
org $9bee74 ;(PC: 0dee74)
Palette_DungBgMain:
org $9bec77
Palette_SpriteAux3:
org $9becc5
Palette_SpriteAux2:
org $9bece4
Palette_SpriteAux1:
org $828046 ; <- 10046 - Bank02.asm : 217 (JSL EnableForceBlank) (Start of Module_LoadFile)
jsl OnFileLoadOverride
org $87A93F ; < 3A93F - Bank07.asm 6548 (LDA $8A : AND.b #$40 - Mirror checks)
jsl MirrorCheckOverride
org $85ef47
Sprite_HeartContainer_Override: ;sprite_heart_upgrades.asm : 96-100 (LDA $040C : CMP.b #$1A : BNE .not_in_ganons_tower)
jsl GtBossHeartCheckOverride : bcs .not_in_ganons_tower
nop : stz.w SpriteAITable, X : rts
.not_in_ganons_tower
org $87a955 ; <- Bank07.asm : around 6564 (JP is a bit different) (STZ $05FC : STZ $05FD)
jsl BlockEraseFix
nop #2
org $82A0A8
Mirror_SaveRoomData:
org $87A95B ; < bank_07.asm ; #_07A95B: JSL Mirror_SaveRoomData
jsl EGFixOnMirror
org $82b82a
jsl FixShopCode
org $9ddeea ; <- Bank1D.asm : 286 (JSL SpritePrep_LoadProperties)
jsl VitreousKeyReset
org $9ed024 ; f5024 sprite_guruguru_bar.asm : 27 (LDA $040C : CMP.b #$12 : INY #2
jsl GuruguruFix : bra .next
nop #3
.next
org $828fc9
nop #2 : jsl BlindAtticFix
org $828409
jsl SuctionOverworldFix
org $8ded04 ; <- rando's hooks.asm line 2192 - 6ED04 - equipment.asm : 1963 (REP #$30)
jsl DrHudDungeonItemsAdditions
;org $098638 ; rando's hooks.asm line 2192
;jsl CountChestKeys
org $86D192 ; rando's hooks.asm line 457
jsl CountAbsorbedKeys
; rando's hooks.asm line 1020
;org $05FC7E ; <- 2FC7E - sprite_dash_item.asm : 118 (LDA $7EF36F : INC A : STA $7EF36F)
;jsl CountBonkItem
org $819dbd ; <- Bank01.asm : 4465 of Object_Draw8xN (LDA $9B52, Y : STA $7E2000, X)
jsl CutoffEntranceRug : bra .nextTile : nop
.nextTile
;maybe set 02e2 to 0
org $8799de ; <- Bank07.asm : 4088 (LDA.b #$15 : STA $5D)
JSL StoreTempBunnyState
;
org $88C450 ; <- ancilla_receive_item.asm : 146-148 (STY $5D : STZ $02D8)
JSL RetrieveBunnyState : JMP.w + : NOP : +
org $82d9ce ; <- Bank02.asm : Dungeon_LoadEntrance 10829 (STA $A0 : STA $048E)
JSL CheckDarkWorldSpawn : NOP
org $9edabf ; <- sprite_energy_ball.asm : 86-7 Sprite_EnergyBall (LDA.b #$10 : LDX.b #$00)
JSL StandardAgaDmg
org $89F7B2 ; 09F7B2 Module17_01 S&Q
JSL StandardSaveAndQuit
org $89a681 ; < - similar to talalong.asm : 1157 (JSL Main_ShowTextMessage)
JSL BlindsAtticHint : NOP #2
org $9cfd69
Main_ShowTextMessage:
; Conditionally disable UW music changes in Door Rando
org $828ADB ; <- Bank02.asm:2088-2095 (LDX.b #$14 : LDA $A0 ...)
JSL Underworld_DoorDown_Entry : CPX.b #$FF
BEQ + : db $80, $1C ; BRA $028B04
NOP #6 : +
org $82FD00 ; unreachable code
Underworld_SetBossOrSancMusicUponEntry_long:
JSR Underworld_SetBossOrSancMusicUponEntry : RTL
org $81AA90
JSL BigKeyDoorCheck : NOP
org $81AAA2
RoomDraw_OneSidedShutters_South_onesided_shutter_or_big_key_door:
;Enable south facing bk graphic
org $80CE24
dw $2ac8
org $81b714 ; PC: b714
OpenableDoors:
jsl CheckIfDoorsOpen
bcs .normal
rts
.normal
org $82C157
JSL AlwaysPushThroughFDoors
org $80E766
JML ConditionalLoadCommonSprites_Do3To4Low : NOP #2
LoadCommonSprites_Prep3To4Low:

View File

@@ -1,305 +0,0 @@
; defines
; Ram usage
HorzEdge:
cpy.b #$ff : beq +
jsr DetectWestEdge : ldy.b #$02 : bra ++
+ jsr DetectEastEdge
++ cmp.b #$ff : beq +
sta.b Scrap00 : asl : !ADD.b Scrap00 : tax
cpy.b #$ff : beq ++
jsr LoadWestData : bra .main
++ jsr LoadEastData
.main
jsr LoadEdgeRoomHorz
sec : rts
+ clc : rts
VertEdge:
cpy.b #$ff : beq +
jsr DetectNorthEdge : bra ++
+ jsr DetectSouthEdge
++ cmp.b #$ff : beq +
sta.b Scrap00 : asl : !ADD.b Scrap00 : tax
cpy.b #$ff : beq ++
jsr LoadNorthData : bra .main
++ jsr LoadSouthData
.main
jsr LoadEdgeRoomVert
sec : rts
+ clc : rts
LoadEdgeRoomHorz:
lda.b Scrap03 : sta.b RoomIndex
sty.b Scrap06
and.b #$0f : asl a : !SUB.b LinkPosX+1 : !ADD.b Scrap06 : sta.b Scrap02
ldy.b #$00 : jsr ShiftVariablesMainDir
lda.b Scrap04 : and.b #$80 : bne .edge
lda.b Scrap04 : sta.b Scrap01 ; load up flags in $01
jsr PrepScrollToNormal
bra .scroll
.edge
lda.b Scrap04 : and.b #$10 : beq +
lda.b #$01
+ sta.b LinkLayer ; layer stuff
jsr MathHorz
.scroll
jsr ScrollY
rts
LoadEdgeRoomVert:
lda.b Scrap03 : sta.b RoomIndex
sty.b Scrap06
and.b #$f0 : lsr #3 : !SUB.b LinkPosY+1 : !ADD.b Scrap06 : sta.b Scrap02
lda.b Scrap04 : and.b #$80 : bne .edge
lda.b Scrap04 : sta.b Scrap01 ; load up flags in $01
and.b #$03 : cmp.b #$03 : beq .inroom
ldy.b #$01 : jsr ShiftVariablesMainDir
jsr PrepScrollToNormal
bra .scroll
.inroom
jsr ScrollToInroomStairs
rts
.edge
ldy.b #$01 : jsr ShiftVariablesMainDir
lda.b Scrap04 : and.b #$10 : beq +
lda.b #$01
+ sta.b LinkLayer ; layer stuff
jsr MathVert
lda.b Scrap03
.scroll
jsr ScrollX
rts
MathHorz:
jsr MathStart : lda.b LinkPosY
jsr MathMid : and.w #$0040
jsr MathEnd
rts
MathVert:
jsr MathStart : lda.b LinkPosX
jsr MathMid : and.w #$0020
jsr MathEnd
rts
MathStart:
rep #$30
lda.b Scrap08 : and.w #$00ff : sta.b Scrap00
rts
MathMid:
and.w #$01ff : !SUB.b Scrap00 : and.w #$00ff : sta.b Scrap00
; nothing should be bigger than $a0 at this point
lda.b Scrap05 : and.w #$00f0 : lsr #4 : tax
lda.w MultDivInfo, x : and.w #$00ff : tay
lda.b Scrap00 : jsr MultiplyByY : sta.b Scrap02
lda.b Scrap07 : and.w #$00ff : jsr MultiplyByY : tax
lda.b Scrap05 : and.w #$000f : tay
lda.w MultDivInfo, y : and.w #$00ff : tay
lda.b Scrap02 : jsr DivideByY : sta.b Scrap00
lda.b Scrap0C : and.w #$00ff : sta.b Scrap02
lda.b Scrap04
rts
MathEnd:
beq +
lda.w #$0100
+ !ADD.b Scrap02 : !ADD.b Scrap00
sta.b Scrap04
sep #$30
rts
; don't need midpoint of edge Link is leaving (formerly in $06 - used by dir indicator)
; don't need width of edge Link is going to (currently in $0b)
LoadNorthData:
lda.w NorthOpenEdge, x : sta.b Scrap03 : inx ; target room
lda.w NorthEdgeInfo, x : sta.b Scrap07 ; needed for maths - (divide by 2 anyway)
lda.w NorthOpenEdge, x : sta.b Scrap04 : inx ; bit field
lda.w NorthEdgeInfo, x : sta.b Scrap08 ; needed for maths
lda.w NorthOpenEdge, x : sta.b Scrap05 ; ratio
lda.b Scrap04 : jsr LoadSouthMidpoint : inx ; needed now, and for nrml transition
lda.w SouthEdgeInfo, x : sta.b Scrap0B : inx ; probably not needed todo: remove
lda.w SouthEdgeInfo, x : sta.b Scrap0C ; needed for maths
rts
LoadSouthMidpoint:
and.b #$0f : sta.b Scrap00 : asl : !ADD.b Scrap00 : tax
lda.w SouthEdgeInfo, x : sta.b Scrap0A ; needed now, and for nrml transition
rts
LoadSouthData:
lda.w SouthOpenEdge, x : sta.b Scrap03 : inx
lda.w SouthEdgeInfo, x : sta.b Scrap07
lda.w SouthOpenEdge, x : sta.b Scrap04 : inx
lda.w SouthEdgeInfo, x : sta.b Scrap08
lda.w SouthOpenEdge, x : sta.b Scrap05
lda.b Scrap04 : jsr LoadNorthMidpoint : inx
lda.w NorthEdgeInfo, x : sta.b Scrap0B : inx
lda.w NorthEdgeInfo, x : sta.b Scrap0C
rts
LoadNorthMidpoint:
and.b #$0f : sta.b Scrap00 : asl : !ADD.b Scrap00 : tax
lda.w NorthEdgeInfo, x : sta.b Scrap0A ; needed now, and for nrml transition
rts
LoadWestData:
lda.w WestOpenEdge, x : sta.b Scrap03 : inx
lda.w WestEdgeInfo, x : sta.b Scrap07
lda.w WestOpenEdge, x : sta.b Scrap04 : inx
lda.w WestEdgeInfo, x : sta.b Scrap08
lda.w WestOpenEdge, x : sta.b Scrap05
lda.b Scrap04 : jsr LoadEastMidpoint : inx
lda.w EastEdgeInfo, x : sta.b Scrap0B : inx
lda.w EastEdgeInfo, x : sta.b Scrap0C
rts
LoadEastMidpoint:
and.b #$0f : sta.b Scrap00 : asl : !ADD.b Scrap00 : tax
lda.w EastEdgeInfo, x : sta.b Scrap0A ; needed now, and for nrml transition
rts
LoadEastData:
lda.w EastOpenEdge, x : sta.b Scrap03 : inx
lda.w EastEdgeInfo, x : sta.b Scrap07
lda.w EastOpenEdge, x : sta.b Scrap04 : inx
lda.w EastEdgeInfo, x : sta.b Scrap08
lda.w EastOpenEdge, x : sta.b Scrap05
lda.b Scrap04 : jsr LoadWestMidpoint : inx
lda.w WestEdgeInfo, x : sta.b Scrap0B : inx
lda.w WestEdgeInfo, x : sta.b Scrap0C
LoadWestMidpoint:
and.b #$0f : sta.b Scrap00 : asl : !ADD.b Scrap00 : tax
lda.w WestEdgeInfo, x : sta.b Scrap0A ; needed now, and for nrml transition
rts
DetectNorthEdge:
ldx.b #$ff
lda.b PreviousRoom
cmp.b #$82 : bne +
lda.b LinkPosX : cmp.b #$50 : bcs ++
ldx.b #$01 : bra .end
++ ldx.b #$00 : bra .end
+ cmp.b #$83 : bne +
ldx.b #$02 : bra .end
+ cmp.b #$84 : bne +
lda.b $a9 : beq ++
lda.b LinkPosX : cmp.b #$78 : bcs +++
ldx.b #$04 : bra .end
+++ ldx.b #$05 : bra .end
++ lda.b LinkPosX : cmp.b #$78 : bcs ++
ldx.b #$03 : bra .end
++ ldx.b #$04 : bra .end
+ cmp.b #$85 : bne +
ldx.b #$06 : bra .end
+ cmp.b #$db : bne +
lda.b $a9 : beq ++
lda.b LinkPosX : beq ++
ldx.b #$08 : bra .end
++ ldx.b #$07 : bra .end
+ cmp.b #$dc : bne .end
lda.b $a9 : bne ++
lda.b LinkPosX : cmp.b #$b0 : bcs ++
ldx.b #$09 : bra .end
++ ldx.b #$0a
.end txa : rts
DetectSouthEdge:
ldx.b #$ff
lda.b PreviousRoom
cmp.b #$72 : bne +
lda.b LinkPosX : cmp.b #$50 : bcs ++
ldx.b #$01 : bra .end
++ ldx.b #$00 : bra .end
+ cmp.b #$73 : bne +
ldx.b #$02 : bra .end
+ cmp.b #$74 : bne +
lda.b $a9 : beq ++
lda.b LinkPosX : cmp.b #$78 : bcs +++
ldx.b #$04 : bra .end
+++ ldx.b #$05 : bra .end
++ lda.b LinkPosX : cmp.b #$78 : bcs ++
ldx.b #$03 : bra .end
++ ldx.b #$04 : bra .end
+ cmp.b #$75 : bne +
ldx.b #$06 : bra .end
+ cmp.b #$cb : bne +
lda.b $a9 : beq ++
lda.b LinkPosX : beq ++
ldx.b #$08 : bra .end
++ ldx.b #$07 : bra .end
+ cmp.b #$cc : bne .end
lda.b $a9 : bne ++
lda.b LinkPosX : cmp.b #$b0 : bcs ++
ldx.b #$09 : bra .end
++ ldx.b #$0a
.end txa : rts
DetectWestEdge:
ldx.b #$ff
lda.b PreviousRoom
cmp.b #$65 : bne +
ldx.b #$00 : bra .end
+ cmp.b #$74 : bne +
ldx.b #$01 : bra .end
+ cmp.b #$75 : bne +
ldx.b #$02 : bra .end
+ cmp.b #$82 : bne +
lda.b LinkQuadrantV : beq ++
ldx.b #$03 : bra .end
++ ldx.b #$04 : bra .end
+ cmp.b #$85 : bne +
ldx.b #$05 : bra .end
+ cmp.b #$cc : bne +
lda.b LinkQuadrantV : beq ++
ldx.b #$06 : bra .end
++ ldx.b #$07 : bra .end
+ cmp.b #$dc : bne .end
ldx.b #$08
.end txa : rts
DetectEastEdge:
ldx.b #$ff
lda.b PreviousRoom
cmp.b #$64 : bne +
ldx.b #$00 : bra .end
+ cmp.b #$73 : bne +
ldx.b #$01 : bra .end
+ cmp.b #$74 : bne +
ldx.b #$02 : bra .end
+ cmp.b #$81 : bne +
lda.b LinkQuadrantV : beq ++
ldx.b #$04 : bra .end
++ ldx.b #$03 : bra .end
+ cmp.b #$84 : bne +
ldx.b #$05 : bra .end
+ cmp.b #$cb : bne +
lda.b LinkQuadrantV : beq ++
ldx.b #$06 : bra .end
++ ldx.b #$07 : bra .end
+ cmp.b #$db : bne .end
ldx.b #$08
.end txa : rts
AlwaysPushThroughFDoors:
PHA : AND.b #$F0 : CMP.b #$F0 : BNE +
PLA : RTL
+ PLA : AND.b #$8E : CMP.b #$80
RTL

View File

@@ -1,300 +0,0 @@
;===================================================================================================
; The only specific concern to keep in mind with this code is that your databank will be $00
; Actually, it should be $80, if you're using my fastrom changes.
;
; Leave all your door data vanilla
; Do not try to adjust doors as I previously suggested (not worth the effort)
; We need a few hooks and some light hardcoding either way
; Might as well just do it in a brute, but reliable, way
;
; In brief, this is the hack we're making:
; 1) Let vanilla routines draw the door normally
; 2) Draw over what vanilla just drew
; 3) Hijack the door tile type routine
; and replace the vanilla value with that of solid collision
; For door dection free RAM at $19EE-$19FF has been co-opted to door each drawn doors position and type bytes
; 19EE is for the "current" door for the IdentifyBlockedEntrance routine
; The array at 19F0 is for the collision routine to retrieve that information as it is no longer
; available by that point
;===================================================================================================
pushpc
org $81B0E6
JSL StoreDoorInfo
org $81892F
DoorDrawJankMove:
JML PrepDoorDraw
.return
JSL AdjustEscapeDoorGraphics
RTS
; we don't want to overwrite the JMP ($000E) that's already there
; Well, we could, but we don't need to
warnpc $818939
org $81BF43
JSL AdjustEscapeDoorCollision
org $81C132 ; ADC.w #$0040 : TAX : LDA.b $00
JSL AdjustEscapeDoorCollision_LowEntrance : NOP #2
pullpc
;===================================================================================================
StoreDoorInfo:
STA.w $1980,X
LDA.b Scrap00 : STA.w $19F0,X
TXA
RTL
PrepDoorDraw:
; first off, we need this routine to return to our jank hook
; otherwise, finding a reliable place to put the graphics change check will be a pin
; so push the address to return to the routine
; It's a lot to explain why this is necessary
; Much easier to just tell you to look at $01890D in the disassembly
; and you should understand the vanilla program flow we need to reject
PEA.w DoorDrawJankMove_return-1
LDA.b Scrap00
STA.w $19EE ; for current routine
; copy vanilla code (but fast rom)
LDA.l $8186F0,X
STA.b Scrap0E
LDX.b Scrap02
LDA.b Scrap04
; and to execute the jump, we'll use the JMP ($000E) we carefully avoided overwriting
JML $818939
;===================================================================================================
; Adjustment stage 1: graphics
AdjustEscapeDoorGraphics:
JSR IdentifyBlockedEntrance
BCS .replace_graphics
JSR IdentifySancEntrance
BCS .fix_sanctuary_entrance
JSR IdentifySwampEntrance
BCS .fix_swamp_entrance
; Do nothing
RTL
;---------------------------------------------------------------------------------------------------
.replace_graphics ; for blocked doors
; using the value in $19A0 should be fine for finding the graphics
; the only caveat is that this appears to locate the tile just above the north-west corner
; so below, I've indicated that offset with a +$xxx after the base tilemap buffer
; The only odd thing I notice with this position is that some bad hardcoded adjust for
; exploding walls that shouldn't affect how we use this value at all!
LDY.w $0460 ; get door index
LDX.w $19A0-2,Y ; get tilemap index
; hardcoded shutter door graphics tile replacement
; the horizontal flips could easily be explicit LDAs
; but it's probably best the door is symmetrical
; using ORA makes your intent more clear
; and gives you fewer values to change if you experiment with other graphics
; row 1
LDA.w #$8838
STA.l TileMapA+$080,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$086,X
; row 2
LDA.w #$8828
STA.l TileMapA+$100,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$106,X
LDA.w #$8829
STA.l TileMapA+$102,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$104,X
JSR IdentifySwampEntrance
BCS .fix_swamp_entrance_alternate
; the state of the A, X, and Y registers is irrelevant when we exit
; they're all subsequently loaded with new values
RTL
.fix_sanctuary_entrance
LDY.w $0460 ; get door index
LDX.w $19A0-2,Y ; get tilemap index
; row 0
LDA.w #$14C4
STA.l TileMapA+$000,X ; sanity check = should calculate to 7e3bbc
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$006,X
LDA.w #$14C5
STA.l TileMapA+$002,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$004,X
; row 1
LDA.w #$14E8
STA.l TileMapA+$082,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$084,X
; row 2
LDA.w #$14F8
STA.l TileMapA+$102,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$104,X
RTL
.fix_swamp_entrance
LDY.w $0460 ; get door index
LDX.w $19A0-2,Y ; get tilemap index
; row 1 - outer section
LDA.w #$0908
STA.l TileMapA+$080,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$086,X
; row 2
LDA.w #$0918
STA.l TileMapA+$100,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$106,X
LDA.w #$14F8
STA.l TileMapA+$102,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$104,X
.fix_swamp_entrance_alternate
; row 0
LDA.w #$9DFC
STA.l TileMapA+$000,X
STA.l TileMapA+$002,X
STA.l TileMapA+$004,X
STA.l TileMapA+$006,X
; row 1 - mid section
LDA.w #$14E8
STA.l TileMapA+$082,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$084,X
; row 3
LDA.w #$A82C
STA.l TileMapA+$180,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$186,X
LDA.w #$A82D
STA.l TileMapA+$182,X
ORA.w #$4000 ; horizontally flip
STA.l TileMapA+$184,X
RTL
IdentifySancEntrance:
LDA.b RoomIndex : CMP.w #$0012 : BNE +
LDA.b Scrap0A : CMP.w #$0010 : BNE +
SEC : RTS
+ CLC : RTS
IdentifySwampEntrance:
LDA.b RoomIndex : CMP.w #$0036 : BNE +
LDA.b Scrap0A : CMP.w #$0010 : BNE +
SEC : RTS
+ CLC : RTS
;===================================================================================================
; Leaving this here in case you desire a fully custom door later
; For now, we'll just hardcode the tiles, as I did above
; I put these in column order because that's how they're expected for the vanilla draw routines
; but I changed my mind on redefining things
; and am too lazy to change it to a row-wise listing
BlockedEntrance:
dw $8838, $8828, $A888 ; column 0
dw $14E8, $8829, $C888 ; column 1
dw $14E8, $8829, $A888 ; column 2
dw $C838, $C828, $C888 ; column 3
;===================================================================================================
; Adjustment stage 2: collision
AdjustEscapeDoorCollision:
LSR ; vanilla shift
AdjustEscapeDoorCollisionShared:
; save our parameters
; but one or both of these may not be necessary depending on how you detect these doors
; all that matters is that after identifying blockage, we have:
; Y is the same as what we entered with
; X has A>>1, for whatever A entered with
PHA
LDA.w $19F0, Y ; grab door info (type, position)
STA.w $19EE ; store in temporary variable
JSR IdentifyBlockedEntrance
PLX ; this is a TAX in vanilla, just have X pull A instead
BCS .block_entrance
; vanilla value
LDA.b Scrap00
RTL
.block_entrance
LDA.w #$0101 ; load tile type for solid collision
RTL
AdjustEscapeDoorCollision_LowEntrance:
ADC.w #$0040 ; vanilla add
JMP AdjustEscapeDoorCollisionShared
;===================================================================================================
; Enter with:
; $19EE containing the door information: position and type bytes
; Exit with:
; carry clear - leave door alone
; carry set - block door
IdentifyBlockedEntrance:
LDA.l ProgressIndicator : AND.w #$00FF : CMP.w #$0002 : BCS .leave_alone ; only in rain states (0 or 1)
LDA.l ProgressFlags : AND.w #$0004 : BNE .leave_alone ; zelda's been rescued
LDA.l BlockSanctuaryDoorInRain : BEQ + ;flagged
LDA.b RoomIndex : CMP.w #$0012 : BNE +
; we're in the sanctuary
; this code could be removed because you can't reach sanc without zelda currently
; but that's enforced in the logic, so this is to catch that case in case some mode allows it
LDA.l FollowerIndicator : AND.w #$00FF : CMP.w #$0001 : BEQ .leave_alone ; zelda is following
LDA.b Scrap0A
CMP.w #$000A : BCC .leave_alone
CMP.w #$0014 : BCS .leave_alone
.block_door
SEC : RTS
+ LDA.l BlockCastleDoorsInRain : AND.w #$00FF : BEQ .leave_alone
LDX.w #$FFFE
- INX #2
LDA.l RemoveRainDoorsRoom, X : CMP.w #$FFFF : BEQ .leave_alone
CMP.b RoomIndex : BNE -
LDA.l RainDoorMatch, X
CMP.w $19EE : BNE .leave_alone
BRA .block_door
.continue
BRA -
.leave_alone
CLC : RTS
;===================================================================================================

View File

@@ -1,104 +0,0 @@
GfxFixer:
{
lda.l DRMode : bne +
jsl LoadRoomHook ;this is the code we overwrote
jsl Dungeon_InitStarTileCh
jsl LoadTransAuxGfx_Alt
inc.b SubSubModule
rtl
+ lda.b $b1 : bne .stage2
jsl LoadRoomHook ; this is the rando version - let's only call this guy once - may fix star tiles and slower loads
jsl Dungeon_InitStarTileCh
jsl LoadTransAuxGfx
jsl Dungeon_LoadCustomTileAttr
jsl PrepTransAuxGfx
lda.l DRMode : cmp.b #$02 : bne + ; only do this in crossed mode
ldx.b RoomIndex : lda.l TilesetTable, x
cmp.w $0aa1 : beq + ; already eq no need to decomp
sta.w $0aa1
tax : lda.l AnimatedTileSheets, x : tay
jsl DecompDungAnimatedTiles
+
lda.b #$09 : sta.b NMIINCR : sta.w SkipOAM
jsl Palette_SpriteAux3
jsl Palette_SpriteAux2
jsl Palette_SpriteAux1
jsl Palette_DungBgMain
jsr CgramAuxToMain
inc.b $b1
rtl
.stage2
lda.b #$0a : sta.b NMIINCR : sta.w SkipOAM
stz.b $b1 : inc.b SubSubModule
rtl
}
FixAnimatedTiles:
LDA.l DRMode : CMP.b #$02 : BNE +
LDA.w DungeonID : CMP.b #$FF : BEQ +
PHX
LDX.b RoomIndex : LDA.l TilesetTable, x
CMP.w $0AA1 : beq ++
TAX : PLA : BRA +
++
PLX
+ LDA.l AnimatedTileSheets, X ; what we wrote over
RTL
FixCloseDungeonMap:
LDA.l DRMode : CMP.b #$02 : BNE .vanilla
LDA.w DungeonID : BMI .vanilla
LSR : TAX
LDA.l DungeonTilesets,x
RTL
.vanilla
LDA.l $7EC20E
RTL
FixWallmasterLamp:
ORA.w $0458
STY.b MAINDESQ : STA.b SUBDESQ : RTL ; what we wrote over
CgramAuxToMain: ; ripped this from bank02 because it ended with rts
{
rep #$20
ldx.b #$00
.loop
lda.l $7EC300, X : sta.l $7EC500, x
lda.l $7EC340, x : sta.l $7EC540, x
lda.l $7EC380, x : sta.l $7EC580, x
lda.l $7EC3C0, x : sta.l $7EC5C0, x
lda.l $7EC400, x : sta.l $7EC600, x
lda.l $7EC440, x : sta.l $7EC640, x
lda.l $7EC480, x : sta.l $7EC680, x
lda.l $7EC4C0, x : sta.l $7EC6C0, x
inx #2 : cpx.b #$40 : bne .loop
sep #$20
; tell NMI to upload new CGRAM data
inc.b NMICGRAM
rts
}
OverridePaletteHeader:
lda.l DRMode : cmp.b #$02 : bne +
lda.l DRFlags : and.b #$20 : bne +
cpx.w #$01c2 : !BGE +
rep #$20
txa : lsr : tax
lda.l PaletteTable, x
iny : rtl
+ rep #$20 : iny : lda.b [Scrap0D], Y ; what we wrote over
rtl
Sprite_ConditionalPrepOAMCoord:
LDA.w SpriteTypeTable,X : CMP.b #$62 : BNE .notMasterSword
LDA.w $0D90,X : BNE .specialCutscene
.notMasterSword
JML Sprite_PrepOAMCoordLong ; what we wrote over
.specialCutscene
SEC ; this prevents MasterSword sprite from drawing if it is a special cutscene
RTL

View File

@@ -1,308 +0,0 @@
!BlankTile = $207F
!SlashTile = $2830
!HyphenTile = $2405
!LTile = $2D68
!DTile = $2D60
!RedSquare = $345E
!BlueSquare = $2C5E
DrHudOverride:
PHB
SEP #$30
LDA.b #$7E
PHA
PLB
DRHUD_DrawItemCounter:
; hides total for mystery seeds
LDA.l ItemCounterHUD : BEQ DRHUD_DrawIndicators
LDA.l DRFlags+1 : LSR : BCC DRHUD_DrawIndicators
REP #$30
LDY.w #!HyphenTile : STY.w HUDGoalIndicator+$0A : STY.w HUDGoalIndicator+$0C
STY.w HUDGoalIndicator+$0E : STY.w HUDGoalIndicator+$10
SEP #$30
DRHUD_DrawIndicators:
LDA.b IndoorsFlag : BNE .continue
JMP OWRHUD_DrawWorldIndicator
.continue
LDA.b FrameCounter : AND.b #$10 : BEQ DRHUD_EnemyDropIndicator
DRHUD_BossIndicator:
LDA.l DRMode : BNE .continue
.early_exit
REP #$10
LDY.w #!BlankTile : STY.w HUDMultiIndicator
JMP DRHUD_Finished
.continue
LDA.w DungeonID : CMP.b #$1B : BCS .early_exit
SEP #$10 ; clears the high byte of X and prevents it from getting B register
TAX
REP #$30
LDY.w #!BlankTile
LDA.w CompassField : AND.l DungeonMask, x
SEP #$20
BEQ .draw_indicator
LDA.l CompassBossIndicator, x : CMP.b RoomIndex : BNE .draw_indicator
LDY.w #!RedSquare
.draw_indicator
STY.w HUDMultiIndicator
BRA DRHUD_DrawCurrentDungeonIndicator
DRHUD_EnemyDropIndicator:
REP #$30
LDA.w EnemyDropIndicator : STA.w HUDMultiIndicator
SEP #$20
LDA.w DungeonID : CMP.b #$1B : BCC + : JMP DRHUD_Finished : +
SEP #$10 : TAX : REP #$10
DRHUD_DrawCurrentDungeonIndicator: ; mX
LDA.l DRMode : BIT.b #$02 : BEQ DRHUD_Finished
LDY.w #!BlankTile
LDA.w CurrentHealth : BEQ .draw_indicator
REP #$20 : LDA.l DungeonReminderTable,X : TAY
SEP #$20
.draw_indicator
STY.w HUDCurrentDungeonWorld
DRHUD_DrawKeyCounter:
LDA.l DRFlags : AND.b #$04 : BEQ DRHUD_Finished
LDA.l CompassMode : BIT.b #$03 : BEQ DRHUD_Finished
REP #$20
BIT.w #$0002 : BNE .skip_map_check
LDA.w MapField : AND.l DungeonMask, X : BEQ DRHUD_Finished
.skip_map_check
TXA : LSR : BNE .dungeon_id
INC
.dungeon_id
TAX
LDA.l GenericKeys : LSR : BCS .total_only
LDA.w DungeonCollectedKeys, X : JSR ConvertToDisplay : STA.w HUDKeysObtained
LDA.w #!SlashTile : STA.w HUDKeysSlash
.total_only
LDA.l ChestKeys, x : JSR ConvertToDisplay : STA.w HUDKeysTotal
JMP DRHUD_Finished
OWRHUD_DrawWorldIndicator:
LDA.l OWMode+1 : AND.b #(!FLAG_OW_CROSSED+!FLAG_OW_MIXED) : BEQ DRHUD_Finished
REP #$10
LDY.w #!BlankTile
LDA.w CurrentHealth : BEQ .draw_indicator
LDA.w CurrentWorld : BEQ +
LDY.w #!DTile : BRA .draw_indicator
+ LDY.w #!LTile
.draw_indicator
STY.w HUDCurrentDungeonWorld ; uses same slot as DR Dungeon Indicator
DRHUD_Finished:
PLB : RTL
;===================================================================================================
;column distance for BK/Smalls
HudOffsets:
; none hc east desert aga swamp pod mire skull ice hera tt tr gt
dw $fffe, $0000, $0006, $0008, $0002, $0010, $000e, $0018, $0012, $0016, $000a, $0014, $001a, $001e
; offset from 1644
RowOffsets:
dw $0000, $0000, $0040, $0080, $0000, $0080, $0040, $0080, $00c0, $0040, $00c0, $0000, $00c0, $0000
ColumnOffsets:
dw $0000, $0000, $0000, $0000, $000a, $000a, $000a, $0014, $000a, $0014, $0000, $0014, $0014, $001e
DrHudDungeonItemsAdditions:
{
jsl DrawHUDDungeonItems
lda.l DRMode : cmp.b #$02 : beq + : rtl : +
phx : phy : php
rep #$30
lda.w #$24f5 : sta.w $1606 : sta.w $1610 : sta.w $161a : sta.w $1624
sta.w $1644 : sta.w $164a : sta.w $1652 : sta.w $1662 : sta.w $1684 : sta.w $16c4
ldx.w #$0000
- sta.w $1704, x : sta.w $170e, x : sta.w $1718, x
inx #2 : cpx.w #$0008 : !BLT -
lda.l HudFlag : and.w #$0020 : beq + : JMP ++ : +
lda.l HUDDungeonItems : and.w #$0007 : bne + : JMP ++ : +
; bk symbols
lda.w #$2811 : sta.w $1606 : sta.w $1610 : sta.w $161a : sta.w $1624
; sm symbols
lda.w #$2810 : sta.w $160a : sta.w $1614 : sta.w $161e : sta.w $16e4
; blank out stuff
lda.w #$24f5 : sta.w $1724
ldx.w #$0002
- lda.w #$0000 : !ADD.l RowOffsets,x : !ADD.l ColumnOffsets, x : tay
lda.l DungeonReminderTable, x : sta.w $1644, y : iny #2
lda.w #$24f5 : sta.w $1644, y
lda.l MapField : and.l DungeonMask, x : beq + ; must have map
jsr BkStatus : sta.w $1644, y : bra .smallKey ; big key status
+ lda.l BigKeyField : and.l DungeonMask, x : beq .smallKey
lda.w #$2826 : sta.w $1644, y
.smallKey
+ iny #2
cpx.w #$001a : bne +
tya : !ADD.w #$003c : tay
+ stx.b Scrap00
txa : lsr : tax
lda.w #$24f5 : sta.w $1644, y
lda.l GenericKeys : and.w #$00FF : bne +
lda.l DungeonKeys, x : and.w #$00FF : beq +
jsr ConvertToDisplay2 : sta.w $1644, y
+ iny #2 : lda.w #$24f5 : sta.w $1644, y
phx : ldx.b Scrap00
LDA.l CompassMode : BIT.w #$0002 : BNE .skip_map_check
LDA.l MapField : AND.l DungeonMask, x : BEQ .key_info_done ; must have map
.skip_map_check
plx : sep #$30 : lda.l ChestKeys, x : sta.b Scrap02
lda.l GenericKeys : bne +++
lda.b Scrap02 : !SUB.l DungeonCollectedKeys, x : sta.b Scrap02
+++ lda.b Scrap02
rep #$30
jsr ConvertToDisplay2 : sta.w $1644, y ; small key totals
bra .skipStack
.key_info_done
plx
.skipStack iny #2
cpx.w #$000d : beq +
lda.w #$24f5 : sta.w $1644, y
+
ldx.b Scrap00
+ inx #2 : cpx.w #$001b : bcs ++ : JMP -
++
lda.l HudFlag : and.w #$0020 : bne + : JMP ++ : +
; map symbols
lda.w #$2821 : sta.w $1606 : sta.w $1610 : sta.w $161a
; compass symbols
lda.w #$2c20 : sta.w $160a : sta.w $1614 : sta.w $161e : sta.w $16e4
; blank out a couple thing from old hud
lda.w #$24f5 : sta.w $1624 : sta.w $1724
ldx.w #$0002
- lda.w #$0000 ; start of hud area
!ADD.l RowOffsets, x : !ADD.l ColumnOffsets, x : tay
lda.l DungeonReminderTable, x : sta.w $1644, y
iny #2
lda.w #$24f5 : sta.w $1644, y ; blank out map spot
lda.l MapField : ora.l MapCountDisplay : ora.l MapOverlay
and.l DungeonMask, x : beq + ; must have map
JSR MapIndicatorShort : STA.w $1644, Y
+ iny #2
cpx.w #$001a : bne +
tya : !ADD.w #$003c : tay
+ lda.l CompassField : ora.l CompassCountDisplay
and.l DungeonMask, x : beq + ; must have compass
phx ; total chest counts
LDA.l CompassTotalsWRAM, x : !SUB.l DungeonLocationsChecked, x
SEP #$30 : JSR HudHexToDec2DigitCopy : REP #$30
lda.b Scrap06 : jsr ConvertToDisplay2 : sta.w $1644, y : iny #2
lda.b Scrap07 : jsr ConvertToDisplay2 : sta.w $1644, y
plx
bra .skipBlanks
+ lda.w #$24f5 : sta.w $1644, y : iny #2 : sta.w $1644, y
.skipBlanks iny #2
cpx.w #$001a : beq +
lda.w #$24f5 : sta.w $1644, y ; blank out spot
+ inx #2 : cpx.w #$001b : !BGE ++ : JMP -
++
plp : ply : plx : rtl
}
MapIndicatorLong:
PHX
LDA.l OldHudToNewHudTable, X : TAX
JSR MapIndicator
PLX
RTL
MapIndicatorShort:
PHX
TXA : LSR : TAX
JSR MapIndicator
PLX
RTS
OldHudToNewHudTable:
dw 1, 2, 3, 10, 4, 6, 5, 8, 11, 9, 7, 12, 13
IndicatorCharacters:
; check 1 2 3 4 5 6 7 G B R
dw $2426, $2817, $2818, $2819, $281A, $281B, $281C, $281D, $2590, $258B, $259B
MapIndicator:
LDA.l CrystalPendantFlags_3, X : AND.w #$00FF
PHX
ASL : TAX : LDA.l IndicatorCharacters, X
PLX
RTS
BkStatus:
lda.l BigKeyField : and.l DungeonMask, x : bne +++ ; has the bk already
lda.l BigKeyStatus, x : bne ++
lda.w #$2827 : rts ; 0/O for no BK
++ cmp.w #$0002 : bne +
lda.w #$2420 : rts ; symbol for BnC
+ lda.w #$24f5 : rts ; black otherwise
+++ lda.w #$2826 : rts ; check mark
ConvertToDisplay:
and.w #$00ff : cmp.w #$000a : !BLT +
!ADD.w #$2519 : rts
+ !ADD.w #$2490 : rts
ConvertToDisplay2:
and.w #$00ff : beq ++
cmp.w #$000a : !BLT +
!ADD.w #$2517 : rts ; 2580 with 258A as "A" for non transparent digits
+ !ADD.w #$2816 : rts
++ lda.w #$2827 : rts ; 0/O for 0 or placeholder digit ;2483
CountAbsorbedKeys:
JML IncrementSmallKeysNoPrimary
; This function apporach doesn't currently work
CountAbsorbedKeysViaCountAllKey:
PHA : PHX
LDA.l StandingItemsOn : BEQ .count_it
; LDA.w SpawnedItemKeyCounted : BNE .done ; this was added because pot keys were being double counted when they weren't shuffled
CPY.b #$24 : BEQ .count_it ; small key for this dungeon
LDA.w DungeonID : LSR : TAX
TYA : CMP.l KeyTable, X : BNE .done
.count_it
STY.b Scrap02 : LDY.b #$24 ; for non-24 items (w/o standing_items a small key is just $C), fake it
LDX.b #$84 ; pretend this isn't a smallkey, but an absorbed object (small heart)
REP #$10 : JSL CountAllKey : SEP #$10
LDY.b Scrap02
.done
; STZ.w SpawnedItemKeyCounted ; reset to zero for next time
PLX : PLA
JML IncrementSmallKeysNoPrimary
;================================================================================
; 8-bit registers
; in: A(b) - Byte to Convert
; out: $06 - $07 (high - low)
;================================================================================
HudHexToDec2DigitCopy: ; modified
PHY
LDY.b #$00
-
CMP.b #10 : !BLT +
INY
SBC.b #10 : BRA -
+
STY.b Scrap06 : LDY.b #$00 ; Store 10s digit and reset Y
CMP.b #1 : !BLT +
-
INY
DEC : BNE -
+
STY.b Scrap07 ; Store 1s digit
PLY
RTS

View File

@@ -1,42 +0,0 @@
; code to un-pair or re-pair doors
; doorlist is loaded into 19A0 but no terminator
; new room is in A0
; for "each" door do the following: (each could mean the first four doors?)
; in lookup table, grab room and corresponding position
; find the info at 7ef000, x where x is twice the paired room
; check the corresponding bit (there are only 4)
; set the bit in 068C
; Note the carry bit is used to indicate if we should aborted (set) or not
CheckIfDoorsOpen: {
jsr TrapDoorFixer ; see normal.asm
; note we are 16bit mode right now
lda.l DRMode : beq +
lda.w DungeonID : cmp.w #$00ff : bne .gtg
+ lda.b RoomIndex : dec : tax : and.w #$000f ; hijacked code
sec : rtl ; set carry to indicate normal behavior
.gtg
phb : phk : plb
stx.b Scrap00 : ldy.w #$0000
.nextDoor
lda.b RoomIndex : asl : tax
lda.w KeyDoorOffset, x : beq .skipDoor
asl : sty.b Scrap05 : !ADD.b Scrap05 : tax
lda.w PairedDoorTable, x : beq .skipDoor
sta.b Scrap02 : and.w #$00ff : asl a : tax
lda.b Scrap02 : and.w #$ff00 : sta.b Scrap03
lda.l RoomDataWRAM.l, X : and.w #$f000 : and.b Scrap03 : beq .skipDoor
tyx : lda.w $068c : ora.l DungeonMask,x : sta.w $068c
.skipDoor
iny #2 : cpy.b Scrap00 : bne .nextDoor
plb : clc : rtl
}
; outstanding issues
; how to indicate opening for other (non-first four doors?)
; Bank01 Door Register stores the 4 bits in 068c to 400 (depending on type)
; Key collision and others depend on F0-F3 attribute not sure if extendable to other numbers
; Dungeon_ProcessTorchAndDoorInteractives.isOpenableDoor is the likely culprit for collision problems
; Saving open status to other unused rooms is tricky -- Bank 2 13947 (line 8888)

View File

@@ -1,66 +0,0 @@
;divide by 2 example
; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10--Offset Ruler
;v 00 01 01 02 02 03 03 04 04 04 05 05 06 06 07 07 08
;divide by 3 example
; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18
;00 00 01 01 01 02 02 02 03 03 03 04 04 04 05 05 05 06 06 06 07 07 07 08 08
MultiplyByY:
.loop cpy.w #$0001 : beq .done
cpy.w #$0003 : bne ++
jsr MultiBy3 : bra .done
++ cpy.w #$0005 : bne ++
jsr MultiBy5 : bra .done
++ asl : sta.b Scrap00 : tya : lsr : tay : lda.b Scrap00 : bra .loop
.done rts
;Divisor in Y. Width of division is in X for rounding toward middle
DivideByY:
.loop
cpy.w #$0000 : beq .done
cpy.w #$0001 : beq .done
cpy.w #$0003 : bne ++
jsr DivideBy3 : bra .done
++ cpy.w #$0005 : bne ++
jsr DivideBy5 : bra .done
++ jsr DivideBy2 : sta.b Scrap00
tya : lsr : tay
txa : lsr : tax
lda.b Scrap00 : bra .loop
.done rts
MultiBy3:
sta.b Scrap00 : asl : !ADD.b Scrap00
rts
MultiBy5:
sta.b Scrap00 : asl #2 : !ADD.b Scrap00
rts
;width of divison in x: rounds toward X/2
DivideBy2:
sta.b Scrap00
lsr : bcc .done
sta.b Scrap02 : txa : lsr : cmp.b Scrap00 : !BLT +
lda.b Scrap02 : inc : bra .done
+ lda.b Scrap02
.done rts
DivideBy3:
sta.b Scrap00
ldx.w #$0000
lda.w #$0002
.loop cmp.b Scrap00 : !BGE .store
inx : !ADD.w #$0003 : bra .loop
.store txa
rts
DivideBy5:
sta.b Scrap00
ldx.w #$0000
lda.w #$0003
.loop cmp.b Scrap00 : !BGE .store
inx : !ADD.w #$0005 : bra .loop
.store txa
rts

View File

@@ -1,448 +0,0 @@
WarpLeft:
lda.l DRMode : beq .end
JSR CheckIfCave : BCS .end
lda.b LinkPosY : ldx.b LinkQuadrantV
jsr CalcIndex
!ADD.b #$06 : ldy.b #$01 ; offsets in A, Y
jsr LoadRoomHorz
.end
jsr Cleanup
rtl
WarpRight:
lda.l DRMode : beq .end
JSR CheckIfCave : BCS .end
lda.b LinkPosY : ldx.b LinkQuadrantV
jsr CalcIndex
!ADD.b #$12 : ldy.b #$ff ; offsets in A, Y
jsr LoadRoomHorz
.end
jsr Cleanup
rtl
WarpUp:
lda.l DRMode : beq .end
JSR CheckIfCave : BCS .end
lda.b LinkPosX : ldx.b LinkQuadrantH
jsr CalcIndex
ldy.b #$02 ; offsets in A, Y
jsr LoadRoomVert
.end
jsr Cleanup
rtl
; Checks if $a0 is equal to <Room>. If it is, opens its stonewall if it's there
macro StonewallCheck(Room)
lda.b RoomIndex : cmp.b #<Room> : bne ?end
lda.l <Room>*2+$7ef000 : ora.b #$80 : sta.l <Room>*2+$7ef000
?end
endmacro
WarpDown:
lda.l DRMode : beq .end
JSR CheckIfCave : BCS .end
lda.b LinkPosX : ldx.b LinkQuadrantH
jsr CalcIndex
!ADD.b #$0c : ldy.b #$ff ; offsets in A, Y
jsr LoadRoomVert
%StonewallCheck($43)
.end
jsr Cleanup
rtl
; carry set = use link door like normal
; carry clear = we are in dr mode, never use linking doors
CheckLinkDoorR:
lda.l DRMode : bne +
lda.l $7ec004 : sta.b RoomIndex ; what we wrote over
sec : rtl
+ clc : rtl
CheckLinkDoorL:
lda.l DRMode : bne +
lda.l $7ec003 : sta.b RoomIndex ; what we wrote over
sec : rtl
+ clc : rtl
TrapDoorFixer:
lda.b $fe : and.w #$0038 : beq .end
xba : asl #2 : sta.b Scrap00
stz.w TrapDoorFlag : lda.w $068c : ora.b Scrap00 : sta.w $068c
.end
stz.b $fe ; clear our fe here because we don't need it anymore
rts
Cleanup:
lda.l DRFlags : and.b #$10 : beq +
stz.w LayerAdjustment
+ inc.b GameSubMode
lda.b $ef
rts
; carry set if cave, clear otherwise
CheckIfCave:
REP #$30
LDA.b PreviousRoom : CMP.w #$00E1 : BCS .invalid
SEP #$30 : CLC : RTS
.invalid
SEP #$30 : SEC : RTS
;A needs be to the low coordinate, x needs to be either 0 for left,upper or non-zero for right,down
; This sets A (00,02,04) and stores half that at $04 for later use, (src door)
CalcIndex: ; A->low byte of Link's Coord, X-> Link's quadrant, DoorOffset x 2 -> A, DoorOffset -> $04 (vert/horz agnostic)
cpx.b #00 : bne .largeDoor
cmp.b #$d0 : bcc .smallDoor
lda.b #$01 : bra .done ; Middle Door
.smallDoor lda.b #$00 : bra .done
.largeDoor lda.b #$02
.done
sta.b Scrap04
asl
rts
; Y is an adjustment for main direction of travel
; A is a door table row offset
LoadRoomHorz:
{
phb : phk : plb
sty.b Scrap06 : sta.b Scrap07 : lda.b RoomIndex : pha ; Store normal room on stack
lda.b Scrap07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00-$01
lda.b Scrap00 : cmp.b #$03 : bne .gtg
jsr HorzEdge : pla : bcs .end
sta.b RoomIndex : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine)
.gtg ;Good to Go!
pla ; Throw away normal room (don't fill up the stack)
lda.b RoomIndex : and.b #$0F : asl a : !SUB.b LinkPosX+1 : !ADD.b Scrap06 : sta.b Scrap02
ldy.b #$00 : jsr ShiftVariablesMainDir
lda.b Scrap01 : and.b #$80 : beq .normal
ldy.b Scrap06 : cpy.b #$ff : beq +
lda.b Scrap01 : jsr LoadEastMidpoint : bra ++
+ lda.b Scrap01 : jsr LoadWestMidpoint
++ jsr PrepScrollToEdge : bra .scroll
.normal
jsr PrepScrollToNormal
.scroll
lda.b Scrap01 : and.b #$40 : pha
jsr ScrollY
pla : beq .end
ldy.b #$06 : jsr ApplyScroll
.end
plb ; restore db register
rts
}
; Y is an adjustment for main direction of travel (stored at $06)
; A is a door table row offset (stored a $07)
LoadRoomVert:
{
phb : phk : plb
sty.b Scrap06 : sta.b Scrap07 : lda.b RoomIndex : pha ; Store normal room on stack
lda.b Scrap07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00-$01
lda.b Scrap00 : cmp.b #$03 : bne .gtg
jsr VertEdge : pla : bcs .end
sta.b RoomIndex : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine)
.gtg ;Good to Go!
pla ; Throw away normal room (don't fill up the stack)
lda.b RoomIndex : and.b #$F0 : lsr #3 : !SUB.b LinkPosY+1 : !ADD.b Scrap06 : sta.b Scrap02
lda.b Scrap01 : and.b #$80 : beq .notEdge
ldy.b #$01 : jsr ShiftVariablesMainDir
ldy.b Scrap06 : cpy.b #$ff : beq +
lda.b Scrap01 : jsr LoadSouthMidpoint : bra ++
+ lda.b Scrap01 : jsr LoadNorthMidpoint
++ jsr PrepScrollToEdge : bra .scroll
.notEdge
lda.b Scrap01 : and.b #$03 : cmp.b #$03 : bne .normal
jsr ScrollToInroomStairs
stz.w $046d
bra .end
.normal
ldy.b #$01 : jsr ShiftVariablesMainDir
jsr PrepScrollToNormal
.scroll
lda.b Scrap01 : and.b #$40 : sta.w $046d
jsr ScrollX
.end
plb ; restore db register
rts
}
LookupNewRoom: ; expects data offset to be in A
{
rep #$30 : and.w #$00FF ;sanitize A reg (who knows what is in the high byte)
sta.b Scrap00 ; offset in 00
lda.b PreviousRoom : tax ; probably okay loading $a3 in the high byte
lda.w DoorOffset,x : and.w #$00FF ;we only want the low byte
asl #3 : sta.b Scrap02 : !ADD.b Scrap02 : !ADD.b Scrap02 ;multiply by 24 (data size)
!ADD.b Scrap00 ; should now have the offset of the address I want to load
tax : lda.w DoorTable,x : sta.b Scrap00
and.w #$00FF : sta.b RoomIndex ; assign new room
sep #$30
rts
}
; INPUTS-- Y: Direction Index , $02: Shift Value
; Sets high bytes of various registers
ShiftVariablesMainDir:
{
lda.w CoordIndex,y : tax
lda.b LinkPosY+1,x : !ADD.b Scrap02 : sta.b LinkPosY+1,x ; coordinate update
lda.w CameraIndex,y : tax
lda.b $e3,x : !ADD.b Scrap02 : sta.b $e3,x ; scroll register high byte
lda.w CamQuadIndex,y : tax
lda.w $0605,x : !ADD.b Scrap02 : sta.w $0605,x ; high bytes of these guys
lda.w $0607,x : !ADD.b Scrap02 : sta.w $0607,x
lda.w $0601,x : !ADD.b Scrap02 : sta.w $0601,x
lda.w $0603,x : !ADD.b Scrap02 : sta.w $0603,x
rts
}
; Normal Flags should be in $01
ScrollToInroomStairs:
{
jsr PrepScrollToInroomStairs
ldy.b #$01 : jsr ShiftVariablesMainDir
jsr ScrollX
ldy.b #$00 : jsr ApplyScroll
lda.b RoomIndex : and.b #$0f : cmp.b #$0f : bne +
stz.b BG1H : stz.b BG2H ; special case camera fix
lda.b #$1f : sta.b BG1H+1 : sta.b BG2H+1
+
rts
}
; Direction should be in $06, Shift Value (see above) in $02 and other info in $01
; Sets $02, $04, $05, $ee, $045e, $045f and things related to Y coordinate
PrepScrollToInroomStairs:
{
lda.b Scrap01 : and.b #$30 : lsr #3 : tay
lda.w InroomStairsX,y : sta.b Scrap04
lda.w InroomStairsX+1,y : sta.b Scrap05
lda.b Scrap06 : cmp.b #$ff : beq .south
lda.w InroomStairsY+1,y : bne +
inc.w $045f ; flag indicating special screen transition
dec.b Scrap02 ; shift variables further
stz.b LinkQuadrantV
lda.b $a8 : and.b #%11111101 : sta.b $a8
stz.w CameraTargetS+1 ; North scroll target
inc.w $0603 : inc.w $0607
dec.w CameraScrollN+1 : dec.w CameraScrollS+1
+
lda.w InroomStairsY,y : !ADD.b #$20 : sta.b LinkPosY
!SUB.b #$38 : sta.w $045e
lda.b Scrap01 : and.b #$40 : beq +
lda.b LinkPosY : !ADD.b #$20 : sta.b LinkPosY
stz.w $045f
+
dec.b LinkPosY+1
%StonewallCheck($1b)
bra ++
.south
lda.w InroomStairsY+1,y : beq +
inc.w $045f ; flag indicating special screen transition
inc.b Scrap02 ; shift variables further
lda.b #$02 : sta.b LinkQuadrantV
lda.b $a8 : ora.b #%00000010 : sta.b $a8
inc.w CameraTargetN+1 ; South scroll target
dec.w $0603 : dec.w $0607
inc.w CameraScrollN+1 : inc.w CameraScrollS+1
+
lda.w InroomStairsY,y : !SUB.b #$20 : sta.b LinkPosY
!ADD.b #$38 : sta.w $045e
lda.b Scrap01 : and.b #$40 : beq +
lda.b LinkPosY : !SUB.b #$20 : sta.b LinkPosY
stz.w $045f
+
inc.b LinkPosY+1
++
lda.b Scrap01 : and.b #$04 : lsr #2 : sta.b LinkLayer : bne +
stz.w $0476
+ rts
}
; Target pixel should be in A, other info in $01
; Sets $04 $05 and $ee
PrepScrollToEdge:
{
sta.b Scrap04 : lda.b Scrap01 : and.b #$20 : beq +
lda.b #01
+ sta.b Scrap05
lda.b Scrap01 : and.b #$10 : beq +
lda.b #01
+ sta.b LinkLayer : bne +
stz.w $0476
+ rts
}
; Normal Flags should be in $01
; Sets $04 $05 and $ee, and $fe
PrepScrollToNormal:
{
lda.b Scrap01 : sta.b $fe : and.b #$04 : lsr #2 : sta.b LinkLayer ; trap door and layer
bne +
stz.w $0476
+ stz.b Scrap05 : lda.b #$78 : sta.b Scrap04
lda.b Scrap01 : and.b #$03 : beq .end
cmp.b #$02 : !BGE +
lda.b #$f8 : sta.b Scrap04 : bra .end
+ inc.b Scrap05
.end rts
}
StraightStairsAdj:
{
stx.w $0464 : sty.w SFX2 ; what we wrote over
lda.l DRMode : beq +
lda.w $045e : bne .toInroom
lda.w $046d : beq .noScroll
sta.b LinkPosX
ldy.b #$00 : jsr ApplyScroll
stz.w $046d
.noScroll
jsr GetTileAttribute : tax
lda.b GameSubMode : cmp.b #$12 : beq .goingNorth
lda.b PreviousRoom : cmp.b #$51 : bne ++
rep #$20 : lda.w #$0018 : !ADD.b LinkPosY : sta.b LinkPosY : sep #$20 ; special fix for throne room
jsr GetTileAttribute : tax
++ lda.l StepAdjustmentDown, X : bra .end
; lda.b LinkLayer : beq .end
; rep #$20 : lda.w #$ffe0 : !ADD.b LinkPosY : sta.b LinkPosY : sep #$20
.goingNorth
cpx.b #$00 : bne ++
lda.b RoomIndex : cmp.b #$51 : bne ++
lda.b #$36 : bra .end ; special fix for throne room
++ ldy.b LinkLayer : cpy.b #$00 : beq ++
inx
++ lda.l StepAdjustmentUp, X
.end
pha : lda.w $0462 : and.b #$04 : bne ++
pla : !ADD.b #$f6 : pha
++ pla : !ADD.w $0464 : sta.w $0464
+ rtl
.toInroom
lda.b #$32 : sta.w $0464 : stz.w $045e
rtl
}
GetTileAttribute:
{
phk : pea.w .jslrtsreturn-1
pea.w $82802c
jml CalculateTransitionLanding ; mucks with x/y sets a to Tile Attribute, I think
.jslrtsreturn
rts
}
; 0 open edge
; 1 nrm door high
; 2 straight str
; 3 nrm door low
; 4 trap door high
; 5 trap door low (none of these exist on North direction)
StepAdjustmentUp: ; really North Stairs
db $00, $f6, $1a, $18, $16, $38
StepAdjustmentDown: ; really South Stairs
db $d0, $f6, $10, $1a, $f0, $00
StraightStairsFix:
{
pha
lda.l DRMode : bne +
pla : !ADD.b LinkPosY : sta.b LinkPosY : rtl ;what we wrote over
+ pla : rtl
}
StraightStairLayerFix:
{
lda.l DRMode : beq +
lda.b LinkLayer : rtl
+ lda.l LayerOfDestination+3, x : rtl ; what we wrote over
}
DoorToStraight:
{
pha
lda.l DRMode : beq .skip
pla : bne .end
pha
lda.b RoomIndex : cmp.b #$51 : bne .skip
lda.b #$04 : sta.b $4e
.skip pla
.end LDX.w TransitionDirection : CMP.b #$02 ; what we wrote over
rtl
}
DoorToInroom:
{
ldx.w $045e : bne .end
sta.w $0020, y ; what we wrote over
.end
ldx.b #$00 ; what we wrote over
rtl
}
DoorToInroomEnd:
{
ldy.w $045e : beq .vanilla
cmp.w $045e : bne .return
stz.w $045e ; clear
.return
rtl
.vanilla
cmp.l UnderworldTransitionLandingCoordinate, x ; what we wrote over
rtl
}
StraightStairsTrapDoor:
{
lda.w $0464 : bne +
; reset function
.reset phk : pea.w .jslrtsreturn-1
pea.w $82802c
jml ResetThenCacheRoomEntryProperties ; $10D71 .reset label of Bank02
.jslrtsreturn
lda.w TrapDoorFlag : bne ++
lda.b RoomIndex : cmp.b #$ac : bne .animateTraps
lda.w $0403 : and.b #$20 : bne .animateTraps
lda.w $0403 : and.b #$10 : beq ++
.animateTraps
lda.b #$05 : sta.b GameSubMode
inc.w TrapDoorFlag : stz.w TileMapDoorPos : stz.w DoorTimer
++ JML Underworld_SetBossOrSancMusicUponEntry_long
+ JML Dungeon_ApproachFixedColor ; what we wrote over
}
InroomStairsTrapDoor:
{
lda.w SubModuleInterface : cmp.b #$05 : beq .reset
lda.b SubSubModule : jml JumpTableLocal ; what we wrote over (essentially)
.reset
pla : pla : pla
jsl StraightStairsTrapDoor_reset
jml $828b15 ; just some RTS in bank 02
}
HandleSpecialDoorLanding: {
LDA.l $7F2000,X ; what we wrote over
SEP #$30
; A = tiletype
HandleIncomingDoorState:
PHA
LDA.l DRMode : BEQ .noDoor
LDA.b 1,S : AND.b #$FA : CMP.b #$80 : bne .noDoor
.setDoorState
LDA.w TransitionDirection : AND.b #$02 : BNE + : INC
+ STA.b $6C
.noDoor
PLA
CMP.b #$34 : BNE + ; inroom stairs
PHA : LDA.b #$26 : STA.w $045E : PLA
+
RTL
}

View File

@@ -1,128 +0,0 @@
GtBossHeartCheckOverride:
lda.b RoomIndex : cmp.b #$1c : beq ++
cmp.b #$6c : beq ++
cmp.b #$4d : bne +
++ lda.l DRFlags : and.b #$01 : bne ++ ;skip if flag on
lda.w RoomItemsTaken : ora.b #$80 : sta.w RoomItemsTaken
++ clc
rtl
+ sec
rtl
OnFileLoadOverride:
jsl OnFileLoad ; what I wrote over
jsl StartingFollower
+ lda.l DRFlags : and.b #$02 : beq + ; Mirror Scroll
lda.l MirrorEquipment : bne +
lda.b #$01 : sta.l MirrorEquipment
+ rtl
MirrorCheckOverride:
lda.l DRFlags : and.b #$02 : beq ++
lda.l MirrorEquipment : cmp.b #$01 : beq +
++ phx : ldx.b OverworldIndex : lda.l OWTileWorldAssoc,x : plx : and.b #$ff
rtl
+ lda.l DRScroll : rtl
EGFixOnMirror:
lda.l DRFlags : and.b #$10 : beq +
stz.w LayerAdjustment
+ jsl Mirror_SaveRoomData
rtl
BlockEraseFix:
lda.l MirrorEquipment : and.b #$02 : beq +
stz.w $05fc : stz.w $05fd
+ rtl
FixShopCode:
cpx.w #$0300 : !BGE +
sta.l RoomDataWRAM[$00].l, x
+ rtl
VitreousKeyReset:
LDA.l FixPrizeOnTheEyes : BEQ +
STZ.w SpriteForceDrop, X
+ JML SpritePrep_LoadProperties ; what we wrote over
GuruguruFix:
lda.b RoomIndex : cmp.b #$df : !BGE +
and.b #$0f : cmp.b #$0e : !BLT +
iny #2
+ rtl
BlindAtticFix:
lda.l DRMode : beq +
- lda.b #$01 : rtl
+ lda.l FollowerTravelAllowed : cmp.b #$02 : beq -
lda.l FollowerIndicator : cmp.b #$06
rtl
SuctionOverworldFix:
stz.b LinkStrafe : stz.b LinkSpeed
lda.l DRMode : beq +
stz.b ForceMove
+ rtl
CutoffEntranceRug:
PHA : PHX
LDA.l DRMode : BEQ .norm
LDA.b Scrap04 : CMP.w #$000A : BEQ + ; only affect A & C objects
CMP.w #$000C : BNE .norm
+ LDX.w #$0000 : LDA.l CutoffRooms, x
- CMP.b RoomIndex : BEQ .check
INX #2 : LDA.l CutoffRooms, x : CMP.w #$FFFF : BNE -
.norm
PLX : PLA : LDA.w $9B52, Y : STA.l TileMapA, X ; what we wrote over
RTL
.check
LDA.b Scrap0C : CMP.w #$0004 : !BGE .skip
LDA.b Scrap0E : CMP.w #$0008 : !BGE .skip
CMP.w #$0004 : !BLT .skip
BRA .norm
.skip
PLX : PLA : RTL
StoreTempBunnyState:
LDA.b LinkState : CMP.b #$1C : BNE +
STA.b ManipTileField
+ LDA.b #$15 : STA.b LinkState ; what we wrote over
RTL
RetrieveBunnyState:
STY.b LinkState : STZ.w ItemReceiptID ; what we wrote over
LDA.b ManipTileField : BEQ +
STA.b LinkState
+ JML MaybeKeepLootID
; A should be how much dmg to do to Aga when leaving this function, 0 if prevented
StandardAgaDmg:
LDX.b #$00 ; part of what we wrote over
LDA.l ProgressFlags : AND.b #$04 : BNE .enableDamage ; zelda's been rescued, no further checks needed
; zelda's not been rescued
LDA.l AllowAgaDamageBeforeZeldaRescued : BEQ + ; zelda needs to be rescued if not allowed
.enableDamage
LDA.b #$10 ; hurt him!
+ RTL
StandardSaveAndQuit:
LDA.b #$0F : STA.b MOSAICQ ; what we wrote over
LDA.l ProgressFlags : AND.b #$04 : BNE +
LDA.l DRMode : BEQ +
LDA.l StartingEntrance : CMP.b #$02 : BCC +
LDA.b #$03 : STA.l StartingEntrance ; set spawn to uncle if >=
+ RTL
; note: this skips both maiden dialog triggers if the hole is open
BlindsAtticHint:
REP #$20
CMP.w #$0122 : BNE +
LDA.l RoomDataWRAM[$65].low : AND.w #$0100 : BEQ +
SEP #$20 : RTL ; skip the dialog box if the hole is already open
+ SEP #$20 : JML Main_ShowTextMessage
BigKeyDoorCheck:
CPY.w #$001E : BNE + ; skip if it isn't a BK door
LDA.l DRFlags : AND.w #$0400 : BNE + ; skip if the flag is set - bk doors can be double-sided
PLA : PEA.w RoomDraw_OneSidedShutters_South_onesided_shutter_or_big_key_door-1
+ LDA.w #$0000 : RTL

View File

@@ -1,222 +0,0 @@
AdjustTransition:
{
lda.b $ab : and.w #$01ff : beq .reset
phy : ldy.b #$06 ; operating on vertical registers during horizontal trans
cpx.b #$02 : bcs .horizontalScrolling
ldy.b #$00 ; operate on horizontal regs during vert trans
.horizontalScrolling
cmp.w #$0008 : bcs +
pha : lda.b $ab : and.w #$0200 : beq ++
pla : bra .add
++ pla : eor.w #$ffff : inc ; convert to negative
.add jsr AdjustCamAdd : ply : bra .reset
+ lda.b $ab : and.w #$0200 : xba : tax
lda.l OffsetTable,x : jsr AdjustCamAdd
lda.b $ab : !SUB.w #$0008 : sta.b $ab
ply : bra .done
.reset ; clear the $ab variable so to not disturb intra-tile doors
stz.b $ab
.done
lda.b Scrap00 : and.w #$01fc
rtl
}
AdjustCamAdd:
!ADD.w $00E2,y : pha
and.w #$01ff : cmp.w #$0111 : !BLT +
cmp.w #$01f8 : !BGE ++
pla : and.w #$ff10 : pha : bra +
++ pla : and.w #$ff00 : !ADD.w #$0100 : pha
+ pla : sta.w $00E2,y : sta.w $00E0,y : rts
; expects target quad in $05 (either 0 or 1) and target pixel in $04, target room should be in $a0
; $06 is either $ff or $01/02
; uses $00-$03 and $0e for calculation
; also set up $ac
ScrollY: ;change the Y offset variables
lda.b RoomIndex : and.b #$f0 : lsr #3 : sta.w $0603 : inc : sta.w $0607
lda.b Scrap05 : bne +
lda.w $0603 : sta.b Scrap00 : stz.b Scrap01 : bra ++
+ lda.w $0607 : sta.b Scrap00 : lda.b #$02 : sta.b Scrap01
++ ; $01 now contains 0 or 2 and $00 contains the correct lat
stz.b Scrap0E
rep #$30
lda.b Scrap00 : pha
lda.b BG2V : and.w #$01ff : sta.b Scrap02
lda.b Scrap04 : jsr LimitYCamera : sta.b Scrap00
jsr CheckRoomLayoutY : bcc +
lda.b Scrap00 : cmp.w #$0080 : !BGE ++
cmp.w #$0010 : !BLT .cmpSrll
lda.w #$0010 : bra .cmpSrll
++ cmp.w #$0100 : !BGE .cmpSrll
lda.w #$0100
.cmpSrll sta.b Scrap00
; figures out scroll amt
+ lda.b Scrap00 : cmp.b Scrap02 : bne +
lda.w #$0000 : bra .next
+ !BLT +
!SUB.b Scrap02 : inc.b Scrap0E : bra .next
+ lda.b Scrap02 : !SUB.b Scrap00
.next
sta.b $ab
jsr AdjustCameraBoundsY
pla : sta.b Scrap00
sep #$30
lda.b Scrap04 : sta.b $20
lda.b Scrap00 : sta.b $21 : sta.w $0601 : sta.w $0605
lda.b Scrap01 : sta.b $aa
lda.b Scrap0E : asl : ora.b $ac : sta.b $ac
lda.b BG2V+1 : and.b #$01 : asl #2 : tax : lda.w $0603, x : sta.b BG2V+1
rts
LimitYCamera:
cmp.w #$006c : !BGE +
lda.w #$0000 : bra .end
+ cmp.w #$017d : !BLT +
lda.w #$0110 : bra .end
+ !SUB.w #$006c
.end rts
CheckRoomLayoutY:
jsr LoadRoomLayout ;switches to 8-bit
cmp.b #$00 : beq .lock
cmp.b #$07 : beq .free
cmp.b #$01 : beq .free
cmp.b #$04 : !BGE .lock
cmp.b #$02 : bne +
lda.b Scrap06 : cmp.b #$ff : beq .lock
+ cmp.b #$03 : bne .free
lda.b Scrap06 : cmp.b #$ff : bne .lock
.free rep #$30 : clc : rts
.lock rep #$30 : sec : rts
AdjustCameraBoundsY:
jsr CheckRoomLayoutY : bcc .free
; layouts that are camera locked (quads only)
lda.b Scrap04 : and.w #$00ff : cmp.w #$007d : !BLT +
lda.w #$0088 : bra ++
+ cmp.w #$006d : !BGE +
lda.w #$0078 : bra ++
+ !ADD.w #$000b
; I think we no longer need the $02 variable
++ sta.b Scrap02 : lda.b Scrap04 : and.w #$0100 : !ADD.b Scrap02 : bra .setBounds
; layouts where the camera is free
.free lda.b Scrap04 : cmp.w #$006c : !BGE +
lda.w #$0077 : bra .setBounds
+ cmp.w #$017c : !BLT +
lda.w #$0187 : bra .setBounds
+ !ADD.w #$000b
.setBounds sta.w $0618 : inc #2 : sta.w $061a
rts
LoadRoomLayout:
lda.b RoomIndex : asl : !ADD.b RoomIndex : tax
lda.l RoomData_ObjectDataPointers+1, x : sta.b $b8
lda.l RoomData_ObjectDataPointers, x : sta.b $b7
sep #$30
ldy.b #$01 : lda.b [$b7], y : and.b #$1c : lsr #2
rts
; expects target quad in $05 (either 0 or 1) and target pixel in $04, target room should be in $a0
; uses $00-$03 and $0e for calculation
; also set up $ac
ScrollX: ;change the X offset variables
lda.b RoomIndex : and.b #$0f : asl : sta.w $060b : inc : sta.w $060f
lda.b Scrap05 : bne +
lda.w $060b : sta.b Scrap00 : stz.b Scrap01 : bra ++
+ lda.w $060f : sta.b Scrap00 : lda.b #$01 : sta.b Scrap01
++ ; $01 now contains 0 or 1 and $00 contains the correct long
stz.b Scrap0E ; pos/neg indicator
rep #$30
lda.b Scrap00 : pha
lda.b BG2H : and.w #$01ff : sta.b Scrap02
lda.b Scrap04 : jsr LimitXCamera : sta.b Scrap00
jsr CheckRoomLayoutX : bcc +
lda.b Scrap00 : cmp.w #$0080 : !BGE ++
lda.w #$0000 : bra .cmpSrll
++ lda.w #$0100
.cmpSrll sta.b Scrap00
;figures out scroll amt
+ lda.b Scrap00 : cmp.b Scrap02 : bne +
lda.w #$0000 : bra .next
+ !BLT +
!SUB.b Scrap02 : inc.b Scrap0E : bra .next
+ lda.b Scrap02 : !SUB.b Scrap00
.next
sta.b $ab : lda.b Scrap04
cmp.w #$0078 : !BGE +
lda.w #$007f : bra ++
+ cmp.w #$0178 : !BLT +
lda.w #$017f : bra ++
+ !ADD.w #$0007
++ sta.w $061c : inc #2 : sta.w $061e
pla : sta.b Scrap00
sep #$30
lda.b Scrap04 : ldx.w $046d : bne .straight
sta.b LinkPosX : bra +
.straight
sta.w $046d ; set X position later
+
lda.b Scrap00 : sta.b LinkPosX+1 : sta.w $0609 : sta.w $060d
lda.b Scrap01 : sta.b LinkQuadrantH
lda.b Scrap0E : asl : ora.b $ac : sta.b $ac
lda.b BG2H+1 : and.b #$01 : asl #2 : tax : lda.w $060b, x : sta.b BG2H+1
rts
LimitXCamera:
cmp.w #$0079 : !BGE +
lda.w #$0000 : bra .end
+ cmp.w #$0178 : !BLT +
lda.w #$0178
+ !SUB.w #$0078
.end rts
CheckRoomLayoutX:
jsr LoadRoomLayout ;switches to 8-bit
cmp.b #$04 : !BLT .lock
cmp.b #$05 : bne +
lda.b Scrap06 : cmp.b #$ff : beq .lock
+ cmp.b #$06 : bne .free
lda.b Scrap06 : cmp.b #$ff : bne .lock
.free rep #$30 : clc : rts
.lock rep #$30 : sec : rts
ApplyScroll:
rep #$30
lda.b $ab : and.w #$01ff : sta.b Scrap00
lda.b $ab : and.w #$0200 : beq +
lda.w $00e2, y : !ADD.b Scrap00 : bra .end
+ lda.w $00e2, y : !SUB.b Scrap00
.end
sta.w $00e2, y
sta.w $00e0, y
stz.b $ab : sep #$30 : rts
QuadrantLoadOrderBeforeScroll:
lda.w $045f : beq .end
lda.b #$08 : sta.w $045c ; start with opposite quadrant row
.end
JML WaterFlood_BuildOneQuadrantForVRAM ; what we overwrote
QuadrantLoadOrderAfterScroll:
lda.w $045f : beq .end
stz.w $045c : stz.w $045f ; draw other row and clear flag
.end
JML WaterFlood_BuildOneQuadrantForVRAM ; what we overwrote

View File

@@ -1,338 +0,0 @@
RecordStairType: {
pha
lda.l DRMode : beq .norm
REP #$30 : LDA.b PreviousRoom : CMP.w #$00E1 : BCS .norm
CMP.w #$00DF : BEQ .norm
SEP #$30
lda.b Scrap0E
cmp.b #$25 : bcc ++ ; don't record straight staircases
sta.w $045e
++ pla : bra +
.norm SEP #$30 : pla : sta.b RoomIndex
+ lda.w $063d, x
rtl
}
SpiralWarp: {
lda.l DRMode : beq .abort ; abort if not DR
REP #$30 : LDA.b PreviousRoom : CMP.w #$00E1 : BCS .abort
CMP.w #$00DF : BEQ .abort
SEP #$30
lda.w $045e : cmp.b #$5e : beq .gtg ; abort if not spiral - intended room is in A!
cmp.b #$5f : beq .gtg
cmp.b #$26 : beq .inroom
.abort
SEP #$30 : stz.w $045e : lda.b PreviousRoom : and.b #$0f : rtl ; clear,run hijacked code and get out
.inroom
jsr InroomStairsWarp
lda.b PreviousRoom : and.b #$0f ; this is the code we are hijacking
rtl
.gtg
phb : phk : plb : phx : phy ; push stuff
jsr LookupSpiralOffset
rep #$30 : and.w #$00FF : asl #2 : tax
lda.w SpiralTable, x : sta.b Scrap00
lda.w SpiralTable+2, x : sta.b Scrap02
sep #$30
lda.b Scrap00 : sta.b RoomIndex
; shift quadrant if necessary
stz.b Scrap07 ; this is a x quad adjuster for those blasted staircase on the edges
lda.b Scrap01 : and.b #$01 : !SUB.b LinkQuadrantH
bne .xQuad
lda.w $0462 : and.b #$04 : bne .xqCont
inc.b Scrap07
.xqCont lda.b LinkPosX : bne .skipXQuad ; this is an edge case
dec.b LinkPosX+1 : bra .skipXQuad ; need to -1 if $22 is 0
.xQuad sta.b Scrap06 : !ADD.b LinkQuadrantH : sta.b LinkQuadrantH
lda.w $0462 : and.b #$04 : bne .xCont
inc.b Scrap07 ; up stairs are going to -1 the quad anyway during transition, need to add this back
.xCont ldy.b #$00 : jsr ShiftQuadSimple
.skipXQuad
lda.b LinkQuadrantV : lsr : sta.b Scrap06 : lda.b Scrap01 : and.b #$02 : lsr : !SUB.b Scrap06
beq .skipYQuad
sta.b Scrap06 : asl : !ADD.b LinkQuadrantV : sta.b LinkQuadrantV
ldy.b #$01 : jsr ShiftQuadSimple
.skipYQuad
lda.b Scrap01 : and.b #$04 : lsr : sta.w $048a ;fix layer calc 0->0 2->1
lda.b Scrap01 : and.b #$08 : lsr #2 : sta.w $0492 ;fix from layer calc 0->0 2->1
; shift lower coordinates
lda.b Scrap02 : sta.b LinkPosX : bne .adjY : lda.b LinkPosX+1 : !ADD.b Scrap07 : sta.b LinkPosX+1
.adjY lda.b Scrap03 : sta.b LinkPosY : bne .upDownAdj : inc.b LinkPosY+1
.upDownAdj ldx.b #$08
lda.w $0462 : and.b #$04 : beq .upStairs
ldx.b #$fd
lda.b Scrap01 : and.b #$80 : bne .set53
; if target is also down adjust by (6,-15)
lda.b #$06 : !ADD.b LinkPosY : sta.b LinkPosY : lda.b #$eb : !ADD.b LinkPosX : sta.b LinkPosX : bra .set53
.upStairs
lda.b Scrap01 : and.b #$80 : beq .set53
; if target is also up adjust by (-6, 14)
lda.b #$fa : !ADD.b LinkPosY : sta.b LinkPosY : lda.b #$14 : !ADD.b LinkPosX : sta.b LinkPosX
bne .set53 : inc.b LinkPosX+1
.set53
txa : !ADD.b LinkPosX : sta.b $53
lda.b Scrap01 : and.b #$10 : sta.b Scrap07 ; zeroHzCam check
ldy.b #$00 : jsr SetCamera
lda.b Scrap01 : and.b #$20 : sta.b Scrap07 ; zeroVtCam check
ldy.b #$01 : jsr SetCamera
jsr StairCleanup
ply : plx : plb ; pull the stuff we pushed
lda.b PreviousRoom : and.b #$0f ; this is the code we are hijacking
rtl
}
StairCleanup: {
stz.w $045e ; clear the staircase flag
; animated tiles fix
lda.l DRMode : cmp.b #$02 : bne + ; only do this in crossed mode
ldx.b RoomIndex : lda.l TilesetTable, x
cmp.w $0aa1 : beq + ; already eq no need to decomp
sta.w $0aa1
tax : lda.l AnimatedTileSheets, x : tay
jsl DecompDungAnimatedTiles
+
stz.w LayerAdjustment
rts
}
LookupSpiralOffset_long:
PHB : PHK : PLB
JSR LookupSpiralOffset
PLB : RTL
;Sets the offset in A
LookupSpiralOffset: {
;where link currently is in $a2: quad in a8 & #$03
;count doors
stz.b Scrap00 : ldx.b #$00 : stz.b Scrap01
.loop
lda.w $047e, x : cmp.b Scrap00 : bcc .continue
sta.b Scrap00
.continue inx #2
cpx.b #$08 : bcc .loop
lda.b Scrap00 : lsr
cmp.b #$01 : beq .done
; look up the quad
lda.b LinkQuadrantH : ora.b LinkQuadrantV : and.b #$03 : beq .quad0
cmp.b #$01 : beq .quad1
cmp.b #$02 : beq .quad2
bra .quad3
.quad0
inc.b Scrap01 : lda.b PreviousRoom
cmp.b #$0c : beq .q0diff ;gt ent
cmp.b #$70 : bne .done ;hc stairwell
.q0diff lda.b LinkPosX : cmp.b #$00 : beq .secondDoor
cmp.b #$98 : bcc .done ;gt ent and hc stairwell
.secondDoor inc.b Scrap01 : bra .done
.quad1
lda.b PreviousRoom
cmp.b #$1a : beq .q1diff ;pod compass
cmp.b #$26 : beq .q1diff ;swamp elbows
cmp.b #$6a : beq .q1diff ;pod dark basement
cmp.b #$76 : bne .done ;swamp drain
.q1diff lda.b LinkPosX : cmp.b #$98 : bcc .done
inc.b Scrap01 : bra .done
.quad2
lda.b #$03 : sta.b Scrap01 : lda.b PreviousRoom
cmp.b #$5f : beq .iceu ;ice u room
cmp.b #$3f : bne .done ;hammer ice exception
stz.b Scrap01 : bra .done
.iceu lda.b LinkPosX : cmp.b #$78 : bcc .done
inc.b Scrap01 : bra .done
.quad3
lda.b PreviousRoom : cmp.b #$40 : beq .done ; top of aga exception
lda.b #$02 : sta.b Scrap01 ; always 2
.done
lda.b PreviousRoom : tax : lda.w SpiralOffset,x
!ADD.b Scrap01 ;add a thing (0 in easy case)
rts
}
InroomStairsWarp: {
phb : phk : plb : phx : phy ; push stuff
; find stairs by room and store index in X
lda.b RoomIndex : ldx.b #$07
.loop
cmp.w InroomStairsRoom,x
beq .found
dex
bne .loop
.found
rep #$30
txa : and.w #$00ff : asl : tay
lda.w InroomStairsTable,y : sta.b Scrap00
sep #$30
sta.b RoomIndex
; set position and everything else based on target door type
txa : and.b #$01 : eor.b #$01 : sta.b Scrap07
; should be the same as lda $0462 : and #$04 : lsr #2 : eor #$01 : sta $07
lda.b Scrap01 : and.b #$80 : beq .notEdge
lda.b Scrap07 : sta.b Scrap03 : beq +
lda.b Scrap01 : jsr LoadSouthMidpoint : sta.b LinkPosX : lda.b #$f4
bra ++
+
lda.b Scrap01 : jsr LoadNorthMidpoint : sta.b LinkPosX : dec.b LinkPosY+1 : lda.b #$f7
++
sta.b LinkPosY
lda.b Scrap01 : and.b #$20 : beq +
lda.b #$01
+
sta.b Scrap02
stz.b Scrap07
lda.b Scrap01 : and.b #$10 : lsr #4
JMP .layer
.notEdge
lda.b Scrap01 : and.b #$03 : cmp.b #$03 : bne .normal
txa : and.b #$06 : sta.b Scrap07
lda.b Scrap01 : and.b #$30 : lsr #3 : tay
lda.w InroomStairsX+1,y : sta.b Scrap02
lda.w InroomStairsY+1,y : sta.b Scrap03
cpy.b Scrap07 : beq .vanillaTransition
lda.w InroomStairsX,y : sta.b LinkPosX
lda.w InroomStairsY,y
ldy.b Scrap07 : beq +
!ADD.b #$07
+
sta.b LinkPosY
inc.b Scrap07
bra ++
.vanillaTransition
lda.b #$c0 : sta.b Scrap07 ; leave camera
++
%StonewallCheck($1b)
lda.b Scrap01 : and.b #$04 : lsr #2
bra .layer
.normal
lda.b Scrap01 : sta.b $fe ; trap door
lda.b Scrap07 : sta.b Scrap03 : beq +
lda.b Scrap01 : and.b #$04 : bne .specialFix
lda.b #$e0 : bra ++
.specialFix
lda.b #$c8 : bra ++
+
%StonewallCheck($43)
lda.b Scrap01 : and.b #$04 : bne +
lda.b #$1b : bra ++
+ lda.b #$33
++ sta.b LinkPosY
inc.b Scrap07 : stz.b Scrap02 : lda.b #$78 : sta.b LinkPosX
lda.b Scrap01 : and.b #$03 : beq ++
cmp.b #$02 : !BGE +
lda.b #$f8 : sta.b LinkPosX : stz.b Scrap07 : bra ++
+ inc.b Scrap02
++
lda.b Scrap01 : and.b #$04 : lsr #2
.layer
sta.b LinkLayer
bne +
stz.w $0476
+
lda.b Scrap02 : !SUB.b LinkQuadrantH
beq .skipXQuad
sta.b Scrap06 : !ADD.b LinkQuadrantH : sta.b LinkQuadrantH
ldy.b #$00 : jsr ShiftQuadSimple
.skipXQuad
lda.b LinkQuadrantV : lsr : sta.b Scrap06 : lda.b Scrap03 : !SUB.b Scrap06
beq .skipYQuad
sta.b Scrap06 : asl : !ADD.b LinkQuadrantV : sta.b LinkQuadrantV
ldy.b #$01 : jsr ShiftQuadSimple
.skipYQuad
lda.b Scrap07 : bmi .skipCamera
ldy.b #$00 : jsr SetCamera ; horizontal camera
ldy.b #$01 : sty.b Scrap07 : jsr SetCamera ; vertical camera
lda.b LinkPosY : cmp.b #$e0 : bcc +
lda.b BG2V : bne +
lda.b #$10 : sta.b BG2V ; adjust vertical camera at bottom
+
.skipCamera
jsr StairCleanup
ply : plx : plb ; pull the stuff we pushed
rts
}
ShiftQuadSimple: {
lda.w CoordIndex,y : tax
lda.b LinkPosY,x : beq .skip
lda.b LinkPosY+1,x : !ADD.b Scrap06 : sta.b LinkPosY+1,x ; coordinate update
.skip
lda.w CamQuadIndex,y : tax
lda.w $0601,x : !ADD.b Scrap06 : sta.w $0601,x
lda.w $0605,x : !ADD.b Scrap06 : sta.w $0605,x ; high bytes of these guys
rts
}
SetCamera: {
stz.b Scrap04
tyx : lda.b LinkQuadrantH,x : bne .nonZeroHalf
lda.w CamQuadIndex,y : tax : lda.w $0607,x : pha
lda.w CameraIndex,y : tax : pla : cmp.b BG2H+1, x : bne .noQuadAdj
dec.b BG2H+1,x
.noQuadAdj
lda.b Scrap07 : bne .adj0
lda.w CoordIndex,y : tax
lda.b LinkPosY,x : beq .oddQuad
cmp.b #$79 : bcc .adj0
!SUB.b #$78 : sta.b Scrap04
tya : asl : !ADD.b #$04 : tax : jsr AdjCamBounds : bra .done
.oddQuad
lda.b #$80 : sta.b Scrap04 : bra .adj1 ; this is such a weird case - quad cross boundary
.adj0
tya : asl : tax : jsr AdjCamBounds : bra .done
.nonZeroHalf ;meaning either right half or bottom half
lda.b Scrap07 : bne .setQuad
lda.w CoordIndex,y : tax
lda.b LinkPosY,x : cmp.b #$78 : bcs .setQuad
!ADD.b #$78 : sta.b Scrap04
lda.w CamQuadIndex,y : tax : lda.w $0603, x : pha
lda.w CameraIndex,y : tax : pla : sta.b BG2H+1, x
.adj1
tya : asl : !ADD.b #$08 : tax : jsr AdjCamBounds : bra .done
.setQuad
lda.w CamQuadIndex,y : tax : lda.w $0607, x : pha
lda.w CameraIndex,y : tax : pla : sta.b BG2H+1, x
tya : asl : !ADD.b #$0c : tax : jsr AdjCamBounds : bra .done
.done
lda.w CameraIndex,y : tax
lda.b Scrap04 : sta.b BG2H, x
rts
}
; input, expects X to be an appropriate offset into the CamBoundBaseLine table
; when $04 is 0 no coordinate are added
AdjCamBounds: {
rep #$20 : lda.w CamBoundBaseLine, x : sta.b Scrap05
lda.b Scrap04 : and.w #$00ff : beq .common
lda.w CoordIndex,y : tax
lda.b LinkPosY, x : and.w #$00ff : !ADD.b Scrap05 : sta.b Scrap05
.common
lda.w OppCamBoundIndex,y : tax
lda.b Scrap05 : sta.w CameraScrollN, x
inc #2 : sta.w CameraScrollS, x : sep #$20
rts
}
SpiralPriorityHack: {
lda.l DRMode : beq +
lda.b #$01 : rtl ; always skip the priority code - until I figure out how to fix it
+ lda.w $0462 : and.b #$04 ; what we wrote over
rtl
}

View File

@@ -3,54 +3,44 @@
;--------------------------------------------------------------------------------
SpawnDungeonPrize:
PHX : PHB
PHA
; Don't spawn prize in Cave state, Hyrule Castle, Escape, Castle Tower, or Ganon's Tower
LDA.w DungeonID : BMI .skip_prize_drop ; Cave state
CMP.b #$00 : BEQ .skip_prize_drop ; Escape
CMP.b #$02 : BEQ .skip_prize_drop ; Hyrule Castle
CMP.b #$1A : BEQ .skip_prize_drop ; Ganon's Tower
CMP.b #$08 : BEQ .skip_prize_drop ; Agahnim's Tower (Castle Tower)
PLA
STA.w ItemReceiptID
TAX
LDA.b $06,S : STA.b ScrapBuffer72 ; Store current RoomTag index
TXA
JSL.l AttemptItemSubstitution
JSL.l ResolveLootIDLong
STA.w ItemReceiptID
TAX
LDA.b #$29 : LDY.b #$06
JSL AddAncillaLong
JSL.l AddAncillaLong
BCS .failed_spawn
LDA.w ItemReceiptID
STA.w AncillaGet,X
JSR AddDungeonPrizeAncilla
STA.w AncillaGet,X : STA.w SpriteID,X
JSR.w AddDungeonPrizeAncilla
LDX.b ScrapBuffer72 : STZ.b RoomTag,X
.failed_spawn
PLB : PLX
RTL
.skip_prize_drop:
PLA : PLB : PLX
RTL
AddDungeonPrizeAncilla:
LDY.w ItemReceiptID
STZ.w AncillaVelocityY,X
STZ.w AncillaVelocityX,X
STZ.w AncillaGeneralF,X
STZ.w AncillaGeneralA,X
STZ.w AncillaGeneralN,X
STZ.w AncillaGeneral,X
STZ.w $0385,X
STZ.w $0C54,X
LDA.b #$D0 : STA.w AncillaVelocityZ,X
LDA.b #$80 : STA.w AncillaZCoord,X
LDA.b #$09 : STA.w AncillaTimer,X
LDA.b #$00 : STA.w AncillaGeneralD,X
LDA.b #$00 : STA.w $0394,X
LDA.w AncillaGet,X : STA.w ItemReceiptID
LDA.w DungeonID : CMP.b #$14 : BNE .not_hera
LDA.b LinkPosY+1 : AND.b #$FE
LDA.b LinkAbsoluteY+1 : AND.b #$FE
INC A
STA.b Scrap01
STZ.b Scrap00
LDA.b LinkPosX+1 : AND.b #$FE
LDA.b LinkAbsoluteX+1 : AND.b #$FE
INC A
STA.b Scrap03
STZ.b Scrap02
@@ -75,45 +65,26 @@ RTS
PrepPrizeTile:
PHA : PHX : PHY
JSL BossPrizeGetPlayer : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.b #$01 : STA.l SpriteSkipEOR
LDA.w AncillaGet, X
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w AncillaGet, X
JSL RequestStandingItemVRAMSlot
LDA.b #$00 : STA.l SpriteSkipEOR
LDA.w AncillaGet, X
JSL.l AttemptItemSubstitution
JSL.l ResolveLootIDLong
STA.w SpriteID,X
JSL.l TransferItemReceiptToBuffer_using_ReceiptID
PLY : PLX : PLA
RTL
PrizeReceiveItem:
PHA
JSL BossPrizeGetPlayer : STA.l !MULTIWORLD_ITEM_PLAYER_ID
PLA
CMP.b #$6A : BNE +
; TODO : This doesn't increment any item counts/stats
JML ActivateTriforceCutscene
+
JSL Link_ReceiveItem
LDA.l TextBoxDefer : BEQ +
STZ.w TextID : STZ.w TextID+1 ; reset decompression buffer
JSL Main_ShowTextMessage_Alt
LDA.b #$00 : STA.l TextBoxDefer
+
RTL
SetItemPose:
PHA
LDA.w DungeonID : BMI .one_handed
LDA.w RoomItemsTaken : BIT.b #$80 : BNE +
.one_handed
PLA
JML Link_ReceiveItem_not_cool_pose
JML $8799F2
+
JSR CrystalOrPendantBehavior : BCC .one_handed
JSR.w CrystalOrPendantBehavior : BCC .one_handed
.two_handed
PLA
JML Link_ReceiveItem_cool_pose
JML $8799EE ; cool pose
SetPrizeCoords:
PHX : PHY
@@ -124,7 +95,7 @@ SetPrizeCoords:
LDY.w AncillaGet,X
RTL
+
JSR CrystalOrPendantBehavior : BCC .regular_coords
JSR.w CrystalOrPendantBehavior : BCC .regular_coords
PLY : PLX
LDY.b #$20 ; Treat as crystal
RTL
@@ -134,7 +105,7 @@ SetCutsceneFlag:
PHX
LDY.b #$01 ; wrote over
LDA.w DungeonID : BMI .no_cutscene
LDA.w RoomItemsTaken : BIT.b #$80 : BNE .dungeon_prize
LDA.w RoomItemsTaken : BIT #$80 : BNE .dungeon_prize
.no_cutscene
SEP #$30
PLX
@@ -142,7 +113,7 @@ SetCutsceneFlag:
RTL
.dungeon_prize
LDA.w ItemReceiptMethod : CMP.b #$03 : BCC .no_cutscene
JSR SetDungeonCompleted
JSR.w SetDungeonCompleted
LDA.w ItemReceiptID
REP #$30
AND.w #$00FF : ASL : TAX
@@ -153,9 +124,9 @@ RTL
AnimatePrizeCutscene:
LDA.w ItemReceiptMethod : CMP.b #$03 : BNE +
JSR CrystalOrPendantBehavior : BCC +
JSR.w CrystalOrPendantBehavior : BCC +
LDA.w DungeonID : BMI +
LDA.w RoomItemsTaken : BIT.b #$80 : BEQ +
LDA.w RoomItemsTaken : BIT #$80 : BEQ +
SEC
RTL
+
@@ -164,7 +135,7 @@ RTL
PrizeDropSparkle:
LDA.w AncillaID,X : CMP.b #$29 : BNE .no_sparkle
JSR CrystalOrPendantBehavior : BCC .no_sparkle
JSR.w CrystalOrPendantBehavior : BCC .no_sparkle
SEC
RTL
.no_sparkle
@@ -172,8 +143,8 @@ PrizeDropSparkle:
RTL
HandleDropSFX:
LDA.w RoomItemsTaken : BIT.b #$80 : BEQ .no_sound
JSR CrystalOrPendantBehavior : BCC .no_sound
LDA.w RoomItemsTaken : BIT #$80 : BEQ .no_sound
JSR.w CrystalOrPendantBehavior : BCC .no_sound
SEC
RTL
.no_sound
@@ -192,7 +163,7 @@ RTL
MaybeKeepLootID:
PHA
LDA.w DungeonID : BMI .no_prize
LDA.w RoomItemsTaken : BIT.b #$80 : BNE .prize
LDA.w RoomItemsTaken : BIT #$80 : BNE .prize
.no_prize
STZ.w ItemReceiptID
STZ.w ItemReceiptPose
@@ -263,45 +234,20 @@ PrepPrizeOAMCoordinates:
STA.b Scrap02
STA.b Scrap04
LDA.w AncillaZCoord,X
REP #$20
LDA.w $029E,X
AND.w #$00FF
STA.b ScrapBuffer72
STA.b $72
LDA.b Scrap00
STA.b Scrap06
LDA.b $00
STA.b $06
SEC
SBC.b ScrapBuffer72
STA.b Scrap00
SBC.b $72
STA.b $00
JSL PrepAncillaAnimation
TXY
LDA.w AncillaGet,Y : AND.w #$00FF : PHA
REP #$10
ASL : TAX
LDA.l VRAMAddressOffset,X : STA.b Scrap0C
CLC : ADC.w #$0010 : STA.b Scrap0D
PLX
SEP #$10
PHX
; special animation handling
CPX.b #$D2 : BNE + ; fairy
LDX.w AncillaDirection,Y : BEQ ++ : CPX.b #$03 : BEQ ++ ; use other fairy GFX
LDA.b Scrap0C : CLC : ADC.w #$0002 : STA.b Scrap0C
CLC : ADC.w #$0010 : STA.b Scrap0D
++ CPX.b #$02 : BCC .check_width ; move fairy up 2 pixels
LDA.b Scrap00 : SEC : SBC.w #$0002 : STA.b Scrap00
BRA .check_width
+ CPX.b #$D6 : BNE + ; good bee
LDA.b Scrap0C : AND.w #$FF00 : ORA.w #$007C : STA.b Scrap0C ; use blank GFX for high VRAM
LDX.w AncillaDirection,Y : BEQ ++ : CPX.b #$03 : BEQ ++ ; use other bee GFX
LDA.b Scrap0D : SEC : SBC.w #$0010 : STA.b Scrap0D
++ CPX.b #$02 : BCC + ; move bee up 2 pixels
LDA.b Scrap00 : SEC : SBC.w #$0002 : STA.b Scrap00
+
.check_width
PLX
SEP #$20
TXY
LDA.w AncillaGet,X : TAX
LDA.l SpriteProperties_chest_width,X : BNE .wide
TYX
LDA.w AncillaID,X : CMP.b #$3E : BEQ .rising_crystal
@@ -323,70 +269,20 @@ PrepPrizeOAMCoordinates:
PLY : PLX
RTL
PrepPrizeVRAMHigh:
PHX
LDX.b #$00
JSL PrepPrizeVRAM : BCS .store
LDA.b #$24
.store
STA.b ($90),Y
PLX
RTL
PrepPrizeVRAMLow:
PHX
LDX.b #$01
JSL PrepPrizeVRAM : BCS .store
LDA.b #$34
.store
STA.b ($90),Y
PLX
RTL
PrepPrizeVRAM:
PHY
LDA.b 9,S : TAY
LDA.w AncillaID,Y : CMP.b #$29 : BEQ +
PLY : CLC : RTL ; not a prize drop ancilla
+ LDA.b Scrap0C,X : CMP.b #$24 : BEQ + : CMP.b #$34 : BEQ +
PLY : SEC : RTL ; in vanilla VRAM
+
; use dynamic VRAM slot
PHX
LDA.w SprItemGFXSlot,Y : ASL : TAX
REP #$20
LDA.l FreeUWGraphics,X : LSR #4
PLX
CPX.b #$01 : BNE +
CLC : ADC.w #$0010
+
SEP #$20
PLY : SEC
RTL
PrepPrizeShadow:
PHX
LDA.b 5,S : TAX : LDA.w AncillaGet,X : TAX
LDA.w ItemReceiptID : TAX
LDA.l SpriteProperties_standing_width,X : BNE .wide
LDA.b Scrap02
SEC : SBC.b #$04
STA.b Scrap02
PLX : LDX.b #$02
BRA .wide+1
.wide
PLX
LDA.b #$20 : STA.b Scrap04 ; What we wrote over
PLX
RTL
CheckPoseItemCoordinates:
PHX
LDA.w SprRedrawFlag,X : BEQ +
JSL BossPrizeGetPlayer : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.b #$01 : STA.l SpriteSkipEOR
LDA.w AncillaGet,X
JSL RequestStandingItemVRAMSlot
LDA.b #$00 : STA.l SpriteSkipEOR
+
LDA.w ItemReceiptPose : BEQ .done
BIT.b #$02 : BEQ .done
LDA.w AncillaGet,X : TAX
@@ -408,9 +304,6 @@ CrystalOrPendantBehavior:
AND.w #$00FF : ASL : TAX
LDA.l InventoryTable_properties,X : BIT.w #$0080 : BNE .crystal_behavior
SEP #$30
LDA.w ItemReceiptPose : BEQ +
LDA.b #$02 : STA.b LinkDirection
+
PLX : PLA
RTS
.crystal_behavior
@@ -434,46 +327,3 @@ SetDungeonCompleted:
SEP #$20
+
RTS
MaybeSkipHeartRefill:
LDA.w CurrentControlRequest : CMP.b #$13 : BNE .vanilla
LDA.l HeartPieceQuarter : BNE +
; increase health
LDA.l MaximumHealth : CMP.b #$A0 : BEQ .reset_skip
CLC : ADC.b #$08 : STA.l MaximumHealth
+
.reset_skip
LDA.b #$00 ; just to ensure the MaximumHealth doesn't flow outside
BRA .skip
.vanilla
LDA.l HeartPieceQuarter : BEQ .do ; what we wrote over
.skip
CLC
RTL
.do
SEC
RTL
ClearMultiworldText:
PHP : PHX
SEP #$30
LDA.l !MULTIWORLD_HUD_TIMER : BEQ +
LDA.b #$01 : STA.l !MULTIWORLD_HUD_TIMER
JSL GetMultiworldItem
+
PLX : PLP
RTL
MaybeSkipCrystalCutsceneFollowerReset:
PHA
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ .skip
; skip if prizes are shuffled outside of normal boss drops
LDA.l InventoryTable_properties+($37*2) : AND.b #$01 : BEQ .continue
.skip
PLA : PLA : PLA : PLA
JML CrystalCutscene_SpawnMaiden_PostFollowerGfx
.continue
PLA
STA.l FollowerIndicator ; what we wrote over
RTL

View File

@@ -13,24 +13,18 @@ DoDungeonMapBossIcon:
; get dungeon boss room
++ REP #$30
LDA.l DungeonMapBossRooms, X
LDA.l $8AE817,X
ASL
TAX
; get sprite pointer for room
LDA.l UWSpritesPointers,X
STA.b Scrap00 ; pointer in $00
if !FEATURE_FIX_BASEROM
LDA.w #$0089
else
LDA.w #$0028 ; set the bank to 28 for now
endif
STA.b Scrap02
LDY.w #$0001 ; to skip the "sort"
LDA.l $89D62E,X
INC ; to skip the "sort"
TAX
; get first byte to make sure it isn't an empty room
SEP #$20
LDA.b [Scrap00], Y
LDA.l $890000,X
CMP.b #$FF
BNE ++
@@ -38,8 +32,7 @@ DoDungeonMapBossIcon:
BRA .cave
; check first sprite
++ INY #2
LDA.b [Scrap00], Y
++ LDA.l $890002,X
SEP #$10
; match boss id
@@ -104,13 +97,13 @@ DoDungeonMapBossIcon:
STA.w DAS1L
LDX.b #$02
STX.w DMAENABLE
STX.w MDMAEN
STA.w DAS1L
LDA.w #$A260>>1
STA.w VMADDL
STX.w DMAENABLE
STX.w MDMAEN
; done
SEP #$30

218
elder.asm
View File

@@ -1,8 +1,8 @@
NewElderCode:
{
LDA.b OverworldIndex : AND.b #$3F : CMP.b #$1B : BEQ .newCodeContinue
LDA.b OverworldIndex : CMP.b #$1B : BEQ .newCodeContinue
;Restore Jump we can keep the RTL so JML
JML Sprite_16_Elder
JML $85F0CD
.newCodeContinue
PHB : PHK : PLB
LDA.b #$07 : STA.w SpriteOAMProp, X ; Palette
@@ -12,10 +12,11 @@ JSR Elder_Code
PLB
RTL
}
Elder_Draw:
{
LDA.b #$02 : STA.b Scrap06 : STZ.b Scrap07 ;Number of Tiles
LDA.w SpriteGFXControl, X : ASL #04
@@ -39,219 +40,32 @@ RTL
Elder_Code:
{
TXY : LDX.b #$06
REP #$30
LDA.l GoalConditionTable, X
TAX : LDA.l $B00000, X
SEP #$30
TYX
CMP.b #$00 : BEQ .despawn ; no goal, despawn
LDA.l TurnInGoalItems : BNE +
REP #$20
LDA.l GoalItemRequirement : BEQ .despawn
LDA.l GanonVulnerableMode : AND.w #$00FF : CMP.w #$0005 : BEQ .despawn
LDA.l TurnInGoalItems : AND.w #$00FF : BNE +
.despawn
SEP #$20
STZ.w SpriteAITable, X ; despawn self
RTS
+
SEP #$20
LDA.b GameSubMode
BNE .done
LDA.b #$96
LDY.b #$01
JSL Sprite_ShowSolicitedMessageIfPlayerFacing_PreserveMessage : BCC .dont_show
LDA.b #$03 : JSL CheckConditionPass : BCC +
JSL ActivateTriforceCutscene
REP #$20
LDA.l GoalCounter
CMP.l GoalItemRequirement : !BLT +
SEP #$20
JSL.l ActivateGoal
+
.dont_show
.done
SEP #$20
LDA.b FrameCounter : LSR #5 : AND.b #$01 : STA.w SpriteGFXControl, X
RTS
}
;--------------------------------------------------------------------------------
; Triforce (Pedestal) Cutscene
;--------------------------------------------------------------------------------
ActivateTriforceCutscene:
; despawn other sprites
LDY.b #$0F
- LDA.w SpriteTypeTable,Y : CMP.b #$16 : BNE +
CPY.b #$00 : BEQ .next
; move Murahdahla to slot 0 for draw priority reasons
LDA.w SpriteTypeTable,Y : STA.w SpriteTypeTable
LDA.w SpritePosYLow,Y : STA.w SpritePosYLow
LDA.w SpritePosXLow,Y : STA.w SpritePosXLow
LDA.w SpritePosYHigh,Y : STA.w SpritePosYHigh
LDA.w SpritePosXHigh,Y : STA.w SpritePosXHigh
LDA.w SpriteVelocityY,Y : STA.w SpriteVelocityY
LDA.w SpriteOAMProp,Y : STA.w SpriteOAMProp
LDA.w SpriteOAMProperties,Y : STA.w SpriteOAMProperties
LDA.w SpriteControl,Y : STA.w SpriteControl
LDA.w SpriteAITable,Y : STA.w SpriteAITable
LDA.b #$02 : STA.w SpriteLayer
+ LDA.b #$00 : STA.w SpriteAITable,Y
.next
DEY : BPL -
LDA.b #$62 ; MasterSword Sprite
JSL Sprite_SpawnDynamically
; set up coords
LDA.b LinkPosX : STA.w SpritePosXLow,Y
LDA.b LinkPosX+1 : STA.w SpritePosXHigh,Y
LDA.b LinkPosY : CLC : ADC.b #$08 : STA.w SpritePosYLow,Y
LDA.b LinkPosY+1 : ADC.b #$00 : STA.w SpritePosYHigh,Y
LDA.b #$01 : STA.w SpriteMovement,Y ; our indicator this is a special cutscene sprite
INC : STA.b LinkDirection ; makes Link face downward
; reset modules
LDA.b IndoorsFlag : BEQ +
LDA.b #$07
BRA ++
+ LDA.b #$09
++ STA.b GameMode
STZ.b GameSubMode : STZ.b SubSubModule
RTL
pushpc
org $858928
MasterSword_InPedestal_DoCutscene:
org $8589B1
MasterSword_ConditionalHandleReceipt_DoReceipt:
org $8588DF
JSL MasterSword_CheckIfPulled : PLX : NOP #2
db $90 ; BCC instead of BEQ
org $85890E
JSL MasterSword_ConditionalActivateCutscene
org $85895F
JSL MasterSword_ConditionalGrabPose : NOP
org $858994
JSL MasterSword_ConditionalGrabPose : NOP
org $858D1C
JML MasterSword_SpawnPendantProp_ChangePalette
MasterSword_SpawnPendantProp_ChangePalette_return:
org $8589A3
JSL MasterSword_ConditionalHandleReceipt : NOP #2
pullpc
MasterSword_CheckIfPulled:
CPX.b #$80 : BEQ +
- CLC : RTL ; not on pedestal screen, continue with cutscene
+ LDA.l OverworldEventDataWRAM,X : AND.b #$40 ; what we wrote over
BEQ - : SEC : RTL
MasterSword_ConditionalActivateCutscene:
LDA.w SpriteMovement,X : BNE .specialCutscene
PHX
REP #$30
LDA.w SprRedrawFlag, X : BNE .doNormalPed
INC.w SprRedrawFlag, X
LDA.l PedPullGfx : BEQ .doNormalPed
LDX.w ItemStackPtr : STA.l ItemGFXStack,X
LDA.w #$BCE0>>1 : STA.l ItemTargetStack,X
TXA : INC #2 : STA.w ItemStackPtr
.doNormalPed
SEP #$30
PLX
JML Sprite_CheckDamageToPlayerSameLayerLong ; what we wrote over
.specialCutscene
LDA.b #$02 : STA.w ItemReceiptPose ; Link's 2-hands-up pose
STA.b LinkLayer ; draw Link on top
; draw Triforce piece in VRAM
LDA.w SprRedrawFlag, X : BNE .skipTransfer
INC.w SprRedrawFlag, X
PHX
REP #$30
LDA.l MurahdahlaGfx : BNE .submitRequest
LDX.w #$006A<<1 : LDA.l StandingItemGraphicsOffsets,X
.submitRequest
LDX.w ItemStackPtr : STA.l ItemGFXStack,X
LDA.w #$9CE0>>1 : STA.l ItemTargetStack,X
TXA : INC #2 : STA.w ItemStackPtr
SEP #$30
PLX
.skipTransfer
PLA : PLA : PLA : JML MasterSword_InPedestal_DoCutscene ; do cutscene
MasterSword_ConditionalGrabPose:
PHA
LDA.w SpriteMovement,X : BNE .specialCutscene
PLA
STA.w $0377 : LDA.b #$01 ; what we wrote over
RTL
.specialCutscene
PLA
LDA.b #$01
RTL
MasterSword_SpawnPendantProp_ChangePalette:
STA.w SpriteVelocityY,Y : PLX ; what we wrote over
LDA.w SpriteMovement,X : BNE .specialCutscene
LDA.l PedPullGfx : BNE .customPedGfx
LDA.l PedPullGfx+1 : BNE .customPedGfx
BRA .done
.customPedGfx
LDA.l PedPullPalette : ASL : INC : BRA .setPalette
.specialCutscene
LDA.b #$02 : STA.w SpriteLayer,Y ; change layer
LDA.l MurahdahlaGfx : BNE .customGfx
LDA.l MurahdahlaGfx+1 : BNE .customGfx
LDA.b #$08 : BRA .setPalette
.customGfx
LDA.l MurahdahlaPalette : ASL
.setPalette
STA.w SpriteOAMProp,Y ; change palette
.done
JML MasterSword_SpawnPendantProp_ChangePalette_return
MasterSword_ConditionalHandleReceipt:
LDA.w SpriteMovement,X : BNE .specialCutscene
LDX.b OverworldIndex : LDA.l OverworldEventDataWRAM,X ; what we wrote over
RTL
.specialCutscene
PLA : PLA : PEA.w MasterSword_ConditionalHandleReceipt_DoReceipt-1
LDA.b 4,S : TAX
LDY.b #$6A
RTL
pushpc
org $858AB6
MasterSword_SpawnLightWell:
org $858AD0
MasterSword_SpawnLightFountain:
org $858B62
MasterSword_SpawnLightBeam:
org $858941
JSL MasterSword_ConditionalSpawnLightWell : NOP #2
MasterSword_SpawnLightWell_return:
org $858952
JSL MasterSword_ConditionalSpawnLightFountain : NOP #2
MasterSword_SpawnLightFountain_return:
org $858B64
JSL MasterSword_ConditionalSpawnLightBeam : NOP #2
pullpc
MasterSword_ConditionalSpawnLightWell:
INC.w SpriteActivity,X ; part of what we wrote over
LDA.w SpriteMovement,X : BNE .specialCutscene
PLA : PLA : PLA : PEA.w MasterSword_SpawnLightWell_return-1
JML MasterSword_SpawnLightWell ; part of what we wrote over
.specialCutscene
RTL
MasterSword_ConditionalSpawnLightFountain:
INC.w SpriteActivity,X ; part of what we wrote over
LDA.w SpriteMovement,X : BNE .specialCutscene
PLA : PLA : PLA : PEA.w MasterSword_SpawnLightFountain_return-1
JML MasterSword_SpawnLightFountain ; part of what we wrote over
.specialCutscene
RTL
MasterSword_ConditionalSpawnLightBeam:
LDA.w SpriteMovement,X : BNE .specialCutscene
LDA.b #$62 : JSL Sprite_SpawnDynamically ; what we wrote over
RTL
.specialCutscene
LDY.b #$FF
RTL

View File

@@ -1,70 +0,0 @@
!DISP_REG = $2100 ; Screen Display Register
!VMAIN_REG = $2115 ; Video Port Control Register
!VRAM_LOW_REG = $2116 ; VRAM Address Registers (Low)
!VRAM_HIGH_REG = $2117 ; VRAM Address Registers (High)
!VRAM_WRITE_REG = #$18 ; VRAM Data Write Registers (Low) (you always store it to the dest register so no need for the actual address)
!DMA0_REG = $4300 ; DMA Control Register - channel 0
!DMA0_DEST_REG = $4301 ; DMA Destination Register
!DMA0_SRC_LOW_REG = $4302 ; DMA Source Address Register (Low)
!DMA0_SRC_HIGH_REG = $4303 ; DMA Source Address Register (High)
!DMA0_SRC_BANK_REG = $4304 ; DMA Source Address Register (Bank)
!DMA0_SIZE_LOW_REG = $4305 ; DMA Size Registers (Low)
!DMA0_SIZE_HIGH_REG = $4306 ; DMA Size Registers (Low)
macro DMA_VRAM(VRAM_HIGH,VRAM_LOW,SRC_BANK,SRC_HIGH,SRC_LOW,LENGTH_HIGH,LENGTH_LOW)
PHA
; --- preserve DMA registers ----------------------------------------------------
LDA.w !DMA0_REG : PHA
LDA.w !DMA0_DEST_REG : PHA
LDA.w !DMA0_SRC_LOW_REG : PHA
LDA.w !DMA0_SRC_HIGH_REG : PHA
LDA.w !DMA0_SRC_BANK_REG : PHA
LDA.w !DMA0_SIZE_LOW_REG : PHA
LDA.w !DMA0_SIZE_HIGH_REG : PHA
; -------------------------------------------------------------------------------
;LDA.b #$80 : STA.w !DISP_REG ; force vblank
LDA.b #$80 : STA.w !VMAIN_REG
; write to vram at $<VRAM_HIGH><VRAM_LOW>
LDA.b <VRAM_LOW> : STA.w !VRAM_LOW_REG ; Set VRAM destination address low byte
LDA.b <VRAM_HIGH> : STA.w !VRAM_HIGH_REG ; Set VRAM destination address high byte
; Set DMA0 to write a word at a time.
LDA.b #$01
STA.w !DMA0_REG
; Write to $2118 & $2119 - VRAM Data Write Registers (Low) & VRAM Data Write Registers (High)
; setting word write mode on DMA0_REG causes a write to $2118 and then $2119
; $21xx is assumed
LDA.b !VRAM_WRITE_REG
STA.w !DMA0_DEST_REG
; Read from $<SRC_BANK>:<SRC_HIGH><SRC_LOW>.
LDA.b <SRC_LOW>
STA.w !DMA0_SRC_LOW_REG ; set src address low byte
LDA.b <SRC_HIGH>
STA.w !DMA0_SRC_HIGH_REG ; set src address high byte
LDA.b <SRC_BANK>
STA.w !DMA0_SRC_BANK_REG ; set src address bank byte
; total bytes to copy: #$1000 bytes.
LDA.b <LENGTH_LOW> : STA.w !DMA0_SIZE_LOW_REG ; length low byte
LDA.b <LENGTH_HIGH> : STA.w !DMA0_SIZE_HIGH_REG ; length high byte
; start DMA on channel 0
LDA.b #$01 ; channel select bitmask
STA.w DMAENABLE
; --- restore DMA registers -----------------------------------------------------
PLA : STA.w !DMA0_SIZE_HIGH_REG
PLA : STA.w !DMA0_SIZE_LOW_REG
PLA : STA.w !DMA0_SRC_BANK_REG
PLA : STA.w !DMA0_SRC_HIGH_REG
PLA : STA.w !DMA0_SRC_LOW_REG
PLA : STA.w !DMA0_DEST_REG
PLA : STA.w !DMA0_REG
; -------------------------------------------------------------------------------
PLA
endmacro

View File

@@ -1,53 +0,0 @@
;-------------
NMIHookActionEnemizer:
{
;-----------------------------------------
; do our shell stuff
PHA
PHP
SEP #$20 ; get into 8-bit mode
LDA.l !SHELL_DMA_FLAG : BEQ .return ; check our draw flag
AND.b #$01 : BNE .loadKholdstare
LDA.l !SHELL_DMA_FLAG : AND.b #$02 : BNE .loadTrinexx
BRA .return ; just in case
;BIT.b #$01 : BEQ .loadKholdstare
;BIT.b #$02 : BEQ .loadTrinexx
.loadKholdstare
JSL DMAKholdstare
LDA.b #$00 : STA.l !SHELL_DMA_FLAG ; clear our draw flag
BRA .return
.loadTrinexx
JSL DMATrinexx
LDA.b #$00 : STA.l !SHELL_DMA_FLAG ; clear our draw flag
.return
PLP
PLA
;-----------------------------------------
; restore code Bank00.asm (164-167)
PHB
; Sets DP to $0000
LDA.w #$0000 : TCD
JML NMIHookReturnEnemizer
}
DMAKholdstare:
{
;#GFX_Kholdstare_Shell>>16
%DMA_VRAM(#$34,#$00,#GFX_Kholdstare_Shell>>16&$FF,#GFX_Kholdstare_Shell>>8&$FF,#GFX_Kholdstare_Shell&$FF,#$10,#$00)
RTL
}
DMATrinexx:
{
; TODO: change this to trinexx gfx
%DMA_VRAM(#$34,#$00,#GFX_Trinexx_Shell>>16,#GFX_Trinexx_Shell>>8&$FF,#GFX_Trinexx_Shell&$FF,#$08,#$00)
%DMA_VRAM(#$3A,#$A0,#GFX_Trinexx_Shell2>>16,#GFX_Trinexx_Shell2>>8&$FF,#GFX_Trinexx_Shell2&$FF,#$00,#$C0)
RTL
}

View File

@@ -1,23 +0,0 @@
;================================================================================
; Blind Boss fight
;--------------------------------------------------------------------------------
pushpc
org $9DA081 ; Original Code
JML check_blind_boss_room
Check_for_Blind_Fight:
org $9DA090
Initialize_Blind_Fight:
pullpc
check_blind_boss_room:
LDA.b RoomIndex ; load room index (low byte)
CMP.b #$AC : BNE + ; Is is Thieves Town Boss Room
LDA.l !BLIND_DOOR_FLAG : BNE + ; Blind maiden does not need rescuing
LDA.l FollowerIndicator : JML Check_for_Blind_Fight
+
JML Initialize_Blind_Fight

View File

@@ -1,23 +0,0 @@
;================================================================================
; Fix boss item drop position to 'center' of screen
;================================================================================
change_heartcontainer_position:
{
PHA
LDA.l !CENTER_BOSS_DROP_FLAG : BEQ .not_moldorm_room
LDA.b #$78 : STA.w SpritePosXLow, X
STA.w SpritePosYLow, X
LDA.b LinkPosX+1 : STA.w SpritePosXHigh, X
LDA.b LinkPosY+1 : STA.w SpritePosYHigh, X
LDA.b RoomIndex : CMP.b #$07 : BNE .not_moldorm_room ; not moldorm room
LDA.b LinkPosX : STA.w SpritePosXLow, X
LDA.b LinkPosY : STA.w SpritePosYLow, X
.not_moldorm_room
PLA
JSL Sprite_Get16BitCoords_long
RTL
}

View File

@@ -1,303 +0,0 @@
;================================================================================
; Move the bosses to the right screen location depending on the room
;--------------------------------------------------------------------------------
boss_move:
{
; TODO: should probably double check that we don't need to preserve registers (A,X)...
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
LDA.b RoomIndex ; load room index (low byte)
LDX.b RoomIndex+1 ; (high byte)
CMP.b #7 : BNE + ; Is it Hera Tower Boss Room
CPX.b #$00 : BNE +
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_middle
+
CMP.b #200 : BNE + ; Is it Eastern Palace Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_bottom_right
+
CMP.b #41 : BNE + ; Is it Skull Woods Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
LDA.w $0E20 : CMP.b #$92 : BNE ++ ; Is it Helmasuar King?
LDA.b #$07 : STA.w $0B00 ;Spawn the bugged moving floor sprite
STZ.w $0B28
INC.w OverlordXLow
++
BRL .move_to_bottom_right
+
CMP.b #51 : BNE + ; Is it Desert Palace Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_bottom_left
+
CMP.b #90 : BNE + ; Is it Palace of darkness Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_bottom_right
+
CMP.b #144 : BNE + ; Is it Misery Mire Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_bottom_left
+
CMP.b #172 : BNE + ; Is it Thieve Town Boss Room
; IF MAIDEN IS NOT RESCUED -> DO NOTHING
; IF MAIDEN IS ALREADY RESCUED -> spawn sprites normally
JSL Sprite_ResetAll ; removes sprites in thieve town boss room
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
;Close the door if !BLIND_DOOR_FLAG == 1
LDA.l !BLIND_DOOR_FLAG : BEQ .no_blind_door
INC.w TrapDoorFlag
STZ.w TileMapDoorPos
STZ.w DoorTimer
INC.w BossSpecialAction
; ;That must be called after the room load!
.no_blind_door
BRL .move_to_bottom_right
+
CMP.b #6 : BNE + ; Is it Swamp Palace Boss Room
CPX.b #$00 : BNE +
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_bottom_left
+
CMP.b #222 : BNE + ; Is it Ice Palace Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_top_right
+
CMP.b #164 : BNE + ; Is it Turtle Rock Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_bottom_left
+
CMP.b #28 : BNE + ; Is it Gtower (Armos2) Boss Room
CPX.b #$00 : BNE +
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_bottom_right
+
CMP.b #108 : BNE + ; Is it Gtower (Lanmo2) Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_bottom_left
+
CMP.b #77 : BNE + ; Is it Gtower (Moldorm2) Boss Room
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
BRL .move_to_middle
+
BRL .return
; $0D00[0x10] - The lower byte of a sprite's Y - coordinate.
; $0D10[0x10] - The lower byte of a sprite's X - coordinate.
; $0D20[0x10] - The high byte of a sprite's Y - coordinate.
; $0D30[0x10] - The high byte of a sprite's X - coordinate.
; $0B08[0x08] - (Overlord) X coordinate low byte.
; $0B18[0x08] - (Overlord) Y coordinate low byte.
; $0B10[0x08] - (Overlord) X coordinate high byte.
; $0B20[0x08] - (Overlord) Y coordinate high byte.
.move_to_middle
;load all sprite of that room and overlord
LDX.b #$00
.loop_middle ; move sprites
LDA.w SpriteTypeTable, X
JSR ShouldMoveSprite : BCC .no_change
LDA.w SpritePosXLow, X : !ADD.b #$68 : STA.w SpritePosXLow, X
LDA.w SpritePosYLow, X : !ADD.b #$68 : STA.w SpritePosYLow, X
.no_change
INX : CPX.b #$10 : BNE .loop_middle
LDX.b #$00
.loop_middle2 ; move overlords
LDA.w $0B00, X
CMP.b #$E3 : BNE + ;is it moving floor?
BRA .no_change_ov
+
LDA.w OverlordXLow, X : !ADD.b #$68 : STA.w OverlordXLow, X
LDA.w OverlordYLow, X : !ADD.b #$68 : STA.w OverlordYLow, X
.no_change_ov
INX : CPX.b #$08 : BNE .loop_middle2
BRL .return
.move_to_top_right
LDX.b #$00
.loop_top_right ; move sprites
LDA.w SpriteTypeTable, X
JSR ShouldMoveSprite : BCC .no_change2
LDA.w SpritePosYHigh, X : !ADD.b #$00 : STA.w SpritePosYHigh, X
LDA.w SpritePosXHigh, X : !ADD.b #$01 : STA.w SpritePosXHigh, X
.no_change2
INX : CPX.b #$10 : BNE .loop_top_right
LDX.b #$00
.loop_top_right2 ; move overlords
LDA.w $0B00, X
CMP.b #$E3 : BNE + ;is it moving floor?
BRA .no_change_ov2
+
LDA.w OverlordXHigh, X : !ADD.b #$01 : STA.w OverlordXHigh, X
LDA.w OverlordYHigh, X : !ADD.b #$00 : STA.w OverlordYHigh, X
.no_change_ov2
INX : CPX.b #$08 : BNE .loop_top_right2
BRL .return
.move_to_bottom_right
LDX.b #$00
.loop_bottom_right ; move sprites
LDA.w SpriteTypeTable, X
JSR ShouldMoveSprite : BCC .no_change3
LDA.w SpritePosYHigh, X : !ADD.b #$01 : STA.w SpritePosYHigh, X
LDA.w SpritePosXHigh, X : !ADD.b #$01 : STA.w SpritePosXHigh, X
.no_change3
INX : CPX.b #$10 : BNE .loop_bottom_right
LDX.b #$00
.loop_bottom_right2 ; move overlords
LDA.w $0B00, X
CMP.b #$E3 : BNE + ;is it moving floor?
BRA .no_change_ov3
+
LDA.w OverlordXHigh, X : !ADD.b #$01 : STA.w OverlordXHigh, X
LDA.w OverlordYHigh, X : !ADD.b #$01 : STA.w OverlordYHigh, X
.no_change_ov3
INX : CPX.b #$08 : BNE .loop_bottom_right2
BRL .return
.move_to_bottom_left
LDX.b #$00
.loop_bottom_left ; move sprites
LDA.w SpriteTypeTable, X
JSR ShouldMoveSprite : BCC .no_change4
LDA.w SpritePosYHigh, X : !ADD.b #$01 : STA.w SpritePosYHigh, X
LDA.w SpritePosXHigh, X : !ADD.b #$00 : STA.w SpritePosXHigh, X
.no_change4
INX : CPX.b #$10 : BNE .loop_bottom_left
LDX.b #$00
.loop_bottom_left2 ; move overlords
LDA.w $0B00, X
CMP.b #$E3 : BNE + ;is it moving floor?
BRA .no_change_ov4
+
LDA.w OverlordXHigh, X : !ADD.b #$00 : STA.w OverlordXHigh, X
LDA.w OverlordYHigh, X : !ADD.b #$01 : STA.w OverlordYHigh, X
.no_change_ov4
INX : CPX.b #$08 : BNE .loop_bottom_left2
BRL .return
.return
RTL
}
; A - sprite id from E20, X
; X - sprite index - should be preserved
; sets or clears carry flag, set if sprite should be moved
ShouldMoveSprite:
PHX
LDX.b #$FF
- INX : CPX.b #$0F : BCS .done
CMP.l BossIds, X : BNE -
; match found, move it
PLX : SEC : RTS
.done ; don't move it
PLX : CLC : RTS
BossIds:
db $53, $54, $09, $92, $8c, $8d, $88, $ce
db $a2, $a3, $a4, $bd, $cb, $cc, $cd, $ff
;================================================================================
; Fix the gibdo key drop in skull woods before the boss room - USELESS CODE
;--------------------------------------------------------------------------------
;gibdo_drop_key:
; LDA.b RoomIndex : CMP.b #$39 : BNE .no_key_drop ; Check if the room id is skullwoods before boss
; LDA.w SpriteAITable, X : CMP.b #$09 : BNE .no_key_drop ; Check if the sprite is alive
; LDA.b #$01 : STA.w SpriteForceDrop, X;set key
;
;.no_key_drop
; JSL $86DC5C ;Restore draw shadow
; RTL
;--------------------------------------------------------------------------------
;================================================================================
; Set a flag to draw kholdstare shell on next NMI
;--------------------------------------------------------------------------------
new_kholdstare_code:
LDA.w SpriteForceDrop : BNE .already_iced
LDA.b #$01 : STA.w SpriteForceDrop
LDA.b #$01 : STA.l !SHELL_DMA_FLAG ; tell our NMI to draw the shell
.already_iced
; restore code
JSL Kholdstare_Draw ; sprite_kholdstare.asm (154) : JSL Kholdstare_Draw
RTL
;--------------------------------------------------------------------------------
;================================================================================
; Set a flag to draw trinexx shell on next NMI
;--------------------------------------------------------------------------------
new_trinexx_code:
LDA.w SpriteForceDrop : BNE .already_rocked
LDA.b #$01 : STA.w SpriteForceDrop
LDA.b #$02 : STA.l !SHELL_DMA_FLAG ; tell our NMI to draw the shell
.already_rocked
; restore code
LDA.b #$03 : STA.w SpriteGFXControl, X ; sprite_trinexx.asm (62) : LDA.b #$03 : STA $0DC0, X
RTL
;--------------------------------------------------------------------------------
;================================================================================
; Check if water tile in Swamp boss room, skip interaction
;--------------------------------------------------------------------------------
swamp_boss_tile_interaction:
LDA.l Sprite_ReducedTileInteractionTable, X : BEQ .return
CPX.b #$09 : BNE .return ; return if non-water tile
LDX.b IndoorsFlag : BEQ .return ; return if overworld
LDX.b RoomIndex : CPX.b #$06 : BNE .return ; return if not swamp boss room
LDA.b #$00
.return
RTL
;--------------------------------------------------------------------------------

View File

@@ -1,45 +0,0 @@
sprite_bush_spawn:
{
STY.b Scrap0D ; restored code
LDA.l !BUSHES_FLAG ; That byte is the flag to activate random enemies under bush
BNE .continue
CPY.b #$04 : BNE .not_random_old
JSL GetRandomInt : AND.b #$03 : !ADD.b #$13 : TAY
.not_random_old
LDA.w $81F3, Y;restored code
RTL
.continue
PHX : PHY ; save x,y just to be safe
PHB : PHK : PLB ; setbank to 40
CPY.b #$04 : BNE .not_random
JSL GetRandomInt : AND.b #$03 : TAY
LDA.w sprite_bush_spawn_table_random_sprites, Y
BRL .return
.not_random
CPY.b #$0F : BEQ .newSpriteSpawn
CPY.b #$11 : BEQ .newSpriteSpawn
CPY.b #$10 : BEQ .newSpriteSpawn
;CPY.b #$0E : BEQ .newSpriteSpawn
LDA.w item_drop_table_override, Y
BRA .return
.newSpriteSpawn
LDA.l OverworldIndexMirror : TAY ; load the area ID
LDA.l ProgressIndicator : CMP.b #$03 : !BLT .dontGoPhase2 ; check if agahnim 1 is alive
; aga1 is dead
LDA.l OverworldIndexMirror : CMP.b #$40 : !BGE .dontGoPhase2 ; check if we are in DW, if so we can skip shifting table index
!ADD.b #$90 : TAY ; agahnim 1 is dead, so we need to go to the 2nd phase table for LW
.dontGoPhase2
LDA.w sprite_bush_spawn_table_overworld, Y ;LDA 408000 + area id
.return
PLB ; restore bank to where it was
PLY : PLX ; restore x,y
RTL
}

View File

@@ -1,21 +0,0 @@
sprite_bush_spawn_table:
{
; SPRITE DATA TABLE GENERATED BY ENEMIZER
.overworld
; Skip 0x128(overworld [way overkill]) + 0x128 (dungeons)
skip $128
.dungeons
skip $128
;Old sprite table - Could be changed as well (for the item id 04)
.random_sprites ; if item == 04
db #$00, #$D8, #$E3, #$D8
}
warnpc $B68374
; the drop table has $E1 at B6837D which needs to be #$DA with retro bow
item_drop_table_override:
db #$00, #$D9, #$3E, #$79, #$D9, #$DC, #$D8, #$DA, #$E4, #$E1, #$DC
db #$D8, #$DF, #$E0, #$0B, #$42, #$D3, #$41, #$D4, #$D9, #$E3, #$D8

View File

@@ -1,11 +0,0 @@
CheckIfLinkShouldDie:
; before this we should have:
; LDA $7EF36D - this gets hooked, but we should have LDA at the end of it
CMP.b Scrap00 : BCC .dead
SEC : SBC.b Scrap00
BRA .done
.dead
LDA.b #$00
.done
RTL

View File

@@ -1,3 +0,0 @@
enemizer_info_table:
skip $100
; contains information about settings and enemizer version used to generate rom

View File

@@ -1,45 +0,0 @@
; ;Enemizer Flags
EnemizerFlags:
.randomize_bushes
db #$00 ;368100 ; Enable random enemy under bushes
.close_blind_door
db #$00 ;408101 : 200101 ; Enable blind's door closing for other bosses
.moldorm_eye_count
db #$01 ;408102 : 200102 ; Moldorm eye count, default to 2 eyes (1)
EnemizerFlag_Randomize_Sprites:
db #$00 ;408103 : 200103 ; Randomize Sprites.
.agahnim_fun_balls
db #$00 ;408104 : 200104 ; make Agahnim balls deflect back
.enable_mimic_override
db #$00 ;408105 : 200105 ; toggle mimic code between new and old
; free byte ;408106 : 200106
db #$00
.center_boss_drops
db #$00 ;368107
.killable_theives_id ; must be set to C4 to make thieves killable...
db #$B8 ;368108
.enemies_live_upon_falling
db #$00 ; 368109 ; when set to 1 enemies don't die when falling into a hole
db #$00 ;40810A : 20010A
db #$00 ;40810B : 20010B
db #$00 ;40810C : 20010C
db #$00 ;40810D : 20010D
db #$00 ;40810E : 20010E
db #$00 ;40810F : 20010F
db #$00 ;408110 : 200110
db #$00 ;408111 : 200111
db #$00 ;408112 : 200112
db #$00 ;408113 : 200113
db #$00 ;408114 : 200114
db #$00 ;408115 : 200115
db #$00 ;408116 : 200116
db #$00 ;408117 : 200117
db #$00 ;408118 : 200118
db #$00 ;408119 : 200119
db #$00 ;40811A : 20011A
db #$00 ;40811B : 20011B
db #$00 ;40811C : 20011C
db #$00 ;40811D : 20011D
db #$00 ;40811E : 20011E
db #$00 ;40811F : 20011F

View File

@@ -1,16 +0,0 @@
pushpc
org $868536
JSL CheckFallingDeathFlag
org $86FBF8
JSL CheckFallingDeathFlag
pullpc
CheckFallingDeathFlag:
LDA.l !ENEMY_FALLING_STAY_ALIVE
BEQ +
RTL
+ JML Sprite_ManuallySetDeathFlagUW ; original code

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,26 +0,0 @@
incsrc hooks/NMI_hook.asm
incsrc hooks/bushes_hooks.asm
incsrc hooks/bossdrop_hooks.asm
incsrc hooks/blinddoor_hooks.asm
incsrc hooks/bosses_hooks.asm
incsrc hooks/moldorm_hooks.asm
incsrc hooks/damage_hooks.asm
incsrc hooks/overworld_sprite_hooks.asm
incsrc hooks/underworld_sprite_hooks.asm
org $85B8BA
JSL GeldmanDrawOverride
org $9EAAAC
JSL StalfosKnightDrawOverride
org $9EB209
JSL BlobDrawOverride

View File

@@ -1,9 +0,0 @@
;================================================================================
; NMI Hook
;--------------------------------------------------------------------------------
; rando already hooks the Bank00.asm : 164 (PHA : PHX : PHY : PHD : PHB) so we have to hook after that
org $8080D0 ; <- D0 - Bank00.asm : 164-167 (PHB, LDA.w #$0000)
JML NMIHookActionEnemizer
org $8080D5 ; <- D5 - Bank00.asm : 164-167 (PHB, LDA.w #$0000)
NMIHookReturnEnemizer:
;--------------------------------------------------------------------------------

View File

@@ -1,11 +0,0 @@
;================================================================================
; Blind door close
;--------------------------------------------------------------------------------
;
org $828849 ; Bank02.asm(1588) - original code : JSL $078000 //Hook on player main when transition are over execute player code
JSL check_special_action ;using the variable 7E0CF3 if it not 00 then trap the player in that room
;could be changed easily to support more than only 1 function
;--------------------------------------------------------------------------------
org $878000
Player_Main:

View File

@@ -1,6 +0,0 @@
;================================================================================
; Change heart container drop location
;--------------------------------------------------------------------------------
org $85EF62
JSL change_heartcontainer_position
;--------------------------------------------------------------------------------

View File

@@ -1,50 +0,0 @@
; *$4C114-$4C174 LONG
org $89C114
Dungeon_ResetSprites: ; Bank09.asm(822)
; *$4C44E-$4C498 LONG
org $89C44E
Sprite_ResetAll: ; Bank09.asm(1344)
;--------------------------------------------------------------------------------
;================================================================================
; On Room Transition -> Move Sprite depending on the room loaded
;--------------------------------------------------------------------------------
if not(!FEATURE_FIX_BASEROM)
org $828979 ; JSL Dungeon_ResetSprites ; REPLACE THAT (Sprite initialization) original jsl : $09C114
JSL boss_move
org $828C16 ; JSL Dungeon_ResetSprites ; REPLACE THAT (Sprite initialization) original jsl : $09C114
JSL boss_move
org $829338 ; JSL Dungeon_ResetSprites ; REPLACE THAT (Sprite initialization) original jsl : $09C114
JSL boss_move
org $828256 ; JSL Dungeon_ResetSprites ; REPLACE THAT (Sprite initialization) original jsl : $09C114
JSL boss_move
endif
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
;================================================================================
; Draw kholdstare shell
;--------------------------------------------------------------------------------
org $8DD97F ; jump point
Kholdstare_Draw:
org $9E9518 ; sprite_kholdstare.asm (154) : JSL Kholdstare_Draw
JSL new_kholdstare_code ; Write new gfx in the vram
;--------------------------------------------------------------------------------
;================================================================================
; Draw trinexx shell
;--------------------------------------------------------------------------------
org $1DAD67 ; sprite_trinexx.asm (62) : LDA.b #$03 : STA $0DC0, X
JSL new_trinexx_code : NOP
;--------------------------------------------------------------------------------
;================================================================================
; Swamp Boss Room Water Fix
;--------------------------------------------------------------------------------
org $06E81A
JSL swamp_boss_tile_interaction
;--------------------------------------------------------------------------------

View File

@@ -1,12 +0,0 @@
;================================================================================
; New bush mob randomization
;--------------------------------------------------------------------------------
org $868279
BRA +
MaybeSkipTerrainDebris:
JSL MaybeSkipTerrainDebris_long : RTS ; sticking this here, no other free space in bank 06
NOP #3
+
JSL sprite_bush_spawn
NOP ; we keep the branch
;--------------------------------------------------------------------------------

View File

@@ -1,12 +0,0 @@
org $8780CA ; Bank07.asm(179)
JSL CheckIfLinkShouldDie : NOP : NOP : NOP
;SEC : SBC.b Scrap00 : CMP.b #$00 : BEQ .linkIsDead ; Bank07.asm(179) -
org $8780D1
BNE linkNotDead : NOP : NOP ; Bank07.asm(183) - CMP.b #$A8 : BCC .linkNotDead
org $8780D5
linkIsDead:
org $8780F7
linkNotDead:

View File

@@ -1,20 +0,0 @@
; adjust oam position after drawing eyes
;ED88E
org $9DD88E
{
; original: GiantMoldorm_Draw+5lines (sprite_giant_moldorm.asm)
; lda.b OAMPtr : add.w #$0008 : sta.b OAMPtr
; INC.b OAMPtr+2 : INC.b OAMPtr+2
JSL Moldorm_UpdateOamPosition
NOP #08
}
; set number of eyes
;org $9DDBB2 ;$0EDBB2
;{
; LDX.b #$01
; number of eyes (-1)
;0EDBB2 0EDBB3
; LDX.b #$01
;}

View File

@@ -1,57 +0,0 @@
org $89C4E3
JSL Overworld_LoadSprites_Decision
org $89C50B ; 0x4C50B
{
; .loadData
; ; $4C50B-
; STA.b Scrap01 ; 85 01
; ; $4C50D-
; LDY.w #$0000 ; A0 00 00
JSL LoadOverworldSprites
NOP
}
org $89C510 ; 0x4C510
LDA.b [Scrap00], Y ; replace LDA ($00), Y
; CMP.b #$FF : BEQ .stopLoading
; INY #2
org $89C518 ; 0x4C518
LDA.b [Scrap00], Y ; replace LDA ($00), Y
; DEY #2 : CMP.b #$F4 : BNE .notFallingRocks
; INC.w $0FFD
; INY #3
; BRA .nextSprite
; .notFallingRocks ; Anything other than falling rocks.
org $89C528 ; 0x4C528
LDA.b [Scrap00], Y ; replace LDA ($00), Y
; PHA : LSR #4 : ASL #2 :
org $89C531 ; 0x4C531
STA.b Scrap0A ; STA.b $02
; INY
org $89C534 ; 0x4C534
LDA.b [Scrap00], Y ; replace LDA ($00), Y
; LSR #4 : CLC
org $89C53B ; 0x4C53B
ADC.b Scrap0A ; ADC.b $02
; STA.b $06
; PLA : ASL #4 : STA.b $07
org $89C546 ; 0x4C546
LDA.b [Scrap00], Y ; replace LDA ($00), Y
; AND.b #$0F : ORA.b $07 : STA.b $05
; INY
org $89C54F ; 0x4C54F
LDA.b [Scrap00], Y ; replace LDA ($00), Y
; LDX.b Scrap05 : INC A : STA.l $7FDF80, X
; ; $4C558-
; ; Move on to the next sprite / overlord.
; INY ; C8
; ; $4C559-
; BRA .nextSprite ; 80 B5
; .stopLoading
; ; $4C55B-
; SEP #$10 ; E2 10
; ; $4C55D-
; RTS ; 60

View File

@@ -1,63 +0,0 @@
org $89C29A
JSL LoadUnderworldSprites : NOP
; these hooks change the LDA.b ($00) commands to use LDA.b [$00] commands
; so we can store the sprites in a different bank
; also needs to change the use of $02 to $03 for slot index to make that possible
org $89C2B2
LDA.b [Scrap00]
org $89C2C1
LDA.b [Scrap00],Y
org $89C2CA
INC.b Scrap03 ; change slot variable to $03
;org $09C329 standing items overwrote this one
;LDA.b [Scrap00],Y
org $89C332
LDA.b [Scrap00],Y
org $89C345
DEC.b Scrap03 : LDX.b Scrap03
org $89C350
LDA.b [Scrap00],Y
org $89C35A
DEC.b Scrap03
org $89C36E
JSL GetSpriteSlot16Bit ; depended on high bit being zero, which it isn't anymore
org $89C383
LDX.b Scrap03
org $89C38C
LDA.b [Scrap00],Y
org $89C398
LDA.b [Scrap00],Y
org $89C3AA
LDA.b [Scrap00],Y
org $89C3BF
LDA.b [Scrap00],Y
org $89C3DF
LDA.b Scrap03
org $89C3F3
LDA.b [Scrap00],Y
org $89C3FB
LDA.b [Scrap00],Y
org $89C404
LDA.b [Scrap00],Y
org $89C416
LDA.b [Scrap00],Y

View File

@@ -1,28 +0,0 @@
pushpc
org $9EC147
JSL NewKodongoCollision
BRA + : NOP #3 : +
org $9EC152
Kodongo_SetDirection:
pullpc
NewKodongoCollision:
LDA.w SpriteMoveDirection, X : INC A : AND.b #$03 : STA.w SpriteMoveDirection, X
JSL Kodongo_InVanillaRoom : BEQ .continue
;If they collide more than 4 times just set direction
LDA.w SpriteAuxTable, X : INC A : STA.w SpriteAuxTable, X : CMP.b #$04 : BCC .continue
PLA : PLA : PEA.w Kodongo_SetDirection-1
.continue
RTL
Kodongo_InVanillaRoom:
LDA.b RoomIndex+1 : BNE .return
LDA.b RoomIndex : CMP.b #$19 : BEQ .return
CMP.b #$27 : BEQ .return
CMP.b #$77 : BEQ .return
.return
RTL
nop #10

View File

@@ -1,56 +0,0 @@
; Intended to be a migration of code generated by enemizer
lorom
;=Constants======================================================================
!BUSHES_FLAG = "$368100"
!BLIND_DOOR_FLAG = "$368101"
!MOLDORM_EYES_FLAG = "$368102"
!RANDOM_SPRITE_FLAG = "$368103"
!AGAHNIM_FUN_BALLS = "$368104"
!ENABLE_MIMIC_OVERRIDE = "$368105"
; free byte
!CENTER_BOSS_DROP_FLAG = "$368107"
!KILLABLE_THIEVES_ID = "$368108"
!ENEMY_FALLING_STAY_ALIVE = "$368109"
; Enemizer reserved memory
; $7F50B0 - $7F50BF - Downstream Reserved (Enemizer)
!SHELL_DMA_FLAG = "$7F50B0"
!SOUNDFX_LOADED = "$7F50B1"
;================================================================================
incsrc hooks.asm
incsrc DMA.asm
org $B68000 ; the original org is 368000 and B6 is the same bank but fastrom
EnemizerTablesStart:
incsrc enemizer_info_table.asm ; B68000-B680FF
incsrc enemizerflags.asm ; B68100-B6811F
incsrc bushes_table.asm ; B68120-B6373
EnemizerCodeStart:
incsrc bushes.asm
incsrc NMI.asm
incsrc special_action.asm
incsrc bosses_moved.asm
incsrc damage.asm
incsrc bossdrop.asm
incsrc moldorm.asm
incsrc kodongo_fixes.asm
incsrc mimic_fixes.asm
incsrc swamola_fix.asm
; vitreous key fix for boss shuffle - uses FixPrizeOnTheEyes flag
incsrc overworld_sprites.asm
incsrc underworld_sprites.asm
incsrc blindboss.asm
incsrc falling_death.asm
incsrc shell_gfx.asm
warnpc $B6FFFF ;if we hit this we need to split stuff by bank
org $9EC6FA ;F46FA
SpritePrep_Eyegore:

View File

@@ -1,111 +0,0 @@
pushpc
org $8691B6
SpritePrep_Eyegore_bounce:
JSL SpritePrep_EyegoreNew
org $868839 ; 0xEF
dw SpritePrep_Eyegore_bounce
dw SpritePrep_Eyegore_bounce
;org $869468 ; These need to go else where
;dw #$BFF7 ; SpriteModule_Active_Bank1E_bounce
;dw #$BFF7 ; SpriteModule_Active_Bank1E_bounce
;org $9E8B21
;JSL FixVectorForMimics
;org $9E8BBB ; New vectors for mimics
;dw #$C795
;dw #$C795
org $9EC70D
SpritePrep_Eyegore_become_mimic:
;org $86EC08 ; Sprite_AttemptZapDamage
;JSL resetSprite_Mimic : NOP
org $86ED9E ; Sprite_ApplyCalculatedDamage, skip high sprite id early exit
JSL IsItReallyAMimic : NOP
org $86EDA6 ; Sprite_ApplyCalculatedDamage .not_absorbable
JSL notItemSprite_Mimic
pullpc
;FixVectorForMimics:
; CMP.w $#00EF : BCC .end
; SBC.w #$0032 ; this puts the vector at the unused bytes at UNREACHABLE_1E8BBB
; .end
; AND.w #$00FF ; what we wrote over
; ASL A
;RTL
; replace SpritePrep_Eyegore if flag is on
SpritePrep_EyegoreNew:
{
LDA.l !ENABLE_MIMIC_OVERRIDE : BNE .new
; old
JSL SpritePrep_Eyegore
RTL
.new
LDA.w SpriteTypeTable, X : CMP.b #$EF : BCS .mimic ;If sprite id >= EF (unused somaria platform)
; seems unnecessary it's just an rtl?
; JSL $9EC71A ; 0xF471A set eyegore to be only eyegore (.not_goriya?)
RTL
.mimic
SBC.b #$6C : STA.w SpriteTypeTable, X : JSL SpritePrep_LoadProperties ; pretending to be $83 or $84
JSL SpritePrep_Eyegore_become_mimic
; LDA.w SpriteTypeTable, X : ADC.b #$6C : STA.w SpriteTypeTable, X ; set the sprite back to special mimic
; todo? unsure about this code - seems unnecessary
; LDA.w $0CAA, X : AND.b #$FB : ORA.b #$80 : STA.w $0CAA, X ; STZ.w $0CAA, X
RTL
}
;resetSprite_Mimic:
; LDA.l !ENABLE_MIMIC_OVERRIDE : BEQ .notMimic ; skip to what it would have done normally
;
; LDA.w SpriteTypeTable, X
; CMP.b #$EF : BCC .notMimic
; LDA.w SpriteTypeTable, X : SBC.b #$6C : STA.w SpriteTypeTable, X ; overwrite the sprite id with eyegore id
;
;.notMimic
; restore code
; LDA.w SpriteTypeTable, X : CMP.b #$7A
;RTL
IsItReallyAMimic:
LDA.l !ENABLE_MIMIC_OVERRIDE : BEQ .continue
LDA.w SpriteTypeTable,X : CMP.b #$EF : BEQ .is_mimic
CMP.b #$F0 : BNE .continue
.is_mimic
CLC : RTL
.continue ; code we hijacked
LDA.w SpriteTypeTable,X
CMP.b #$D8
RTL
; this is just for killable thieves now
notItemSprite_Mimic:
; if we set killable thief we want to update the sprite id so it can be killed
LDA.w SpriteTypeTable, X
CMP.l !KILLABLE_THIEVES_ID : BNE .continue ; thief #$C4 (default is B8/dialog tester)
; if we don't have mimic code turned on we want to skip, but we also need to reload the sprite id because we just smoked it with this LDA
; LDA.l !ENABLE_MIMIC_OVERRIDE : BEQ .reloadSpriteIdAndSkipMimic ; skip to what it would have done normally
; LDA.w SpriteTypeTable, X ; I hate assembly
; CMP.b #$EF : BCC .continue
; SBC.b #$6C : BRA .continue
.changeSpriteId
LDA.b #$83 ; load green eyegore sprite id so we can kill the thing
.continue
; restore code
REP #$20 : ASL #2
RTL

View File

@@ -1,14 +0,0 @@
Moldorm_UpdateOamPosition:
{
PHX
LDA.l !MOLDORM_EYES_FLAG : TAX
.more_eyes
LDA.b OAMPtr : CLC : ADC.w #$0004 : STA.b OAMPtr
LDA.b OAMPtr+2 : CLC : ADC.w #$0001 : STA.b OAMPtr+2
DEX : BPL .more_eyes ; X >= 0
PLX
RTL
}

View File

@@ -1,16 +0,0 @@
LoadOverworldSprites:
; restore code
STA.b Scrap01 ; 85 01
LDY.w #$0000 ; A0 00 00
; set bank
LDA.b #$09 : STA.b Scrap02 ; default is bank 9
RTL
; return A = $03 for post-aga enemies, $02 for pre-aga enemies, else rain state enemies
Overworld_LoadSprites_Decision:
PHY : SEP #$10
JSL ClearSpriteData_shared
REP #$10 : PLY
LDA.l ProgressIndicator ; what we wrote over
RTL

View File

@@ -1,12 +0,0 @@
;================================================================================
; insert kholdstare & trinexx shell gfx file
;--------------------------------------------------------------------------------
GFX_Kholdstare_Shell:
incbin gfx/shell.gfx
GFX_Trinexx_Shell:
incbin gfx/rocks.gfx
GFX_Trinexx_Shell2:
incbin gfx/rocks2.gfx
;--------------------------------------------------------------------------------

View File

@@ -1,12 +0,0 @@
;================================================================================
; Special action
;================================================================================
check_special_action:
{
LDA.w BossSpecialAction : BEQ .no_special_action
LDA.b #$05 : STA.b GameSubMode
STZ.w BossSpecialAction
.no_special_action
JSL Player_Main
RTL
}

View File

@@ -1,18 +0,0 @@
pushpc
org $8683B5
JSL MaybeDoCachedSprites ; JSL ExecuteCachedSprites
org $9DE9DA
ExecuteCachedSprites:
pullpc
MaybeDoCachedSprites:
LDA.l EnemizerFlag_Randomize_Sprites
BNE .enemizer
JML ExecuteCachedSprites ; what we copied over
.enemizer
RTL

View File

@@ -1,52 +0,0 @@
LoadUnderworldSprites:
STA.b Scrap00 ; part one of what we replaced
if !FEATURE_FIX_BASEROM
LDA.w #$89
else
LDA.w #UWSpritesData>>16 ; set the bank to 28 for now
endif
STA.b Scrap02
LDA.w $048E
RTL
GetSpriteSlot16Bit:
LDA.b Scrap03 : AND.w #$00FF
ASL A
TAY
RTL
GeldmanDrawOverride:
PLA : PLA : PLA ; fix the call stack
LDA.l DRFlags+1 : AND.b #$08 : BEQ .vanilla
LDA.b #$01
STA.w $0DC0,X
JML Sprite_4C_Geldman_do_indeed_draw
.vanilla
JSL Sprite_PrepOAMCoordLong
JML Sprite_4C_Geldman_continue
StalfosKnightDrawOverride:
LDA.l DRFlags+1 : AND.b #$08 : BEQ .vanilla
JSL Sprite_PrepOAMCoordLong
LDA.b #$12
JML Sprite_DrawShadowLong
.vanilla
JSL Sprite_PrepOAMCoordLong
RTL
BlobDrawOverride:
PLA : PLA : PLA ; fix the call stack
LDA.l DRFlags+1 : AND.b #$08 : BEQ .vanilla
LDA.b #$05
STA.w $0DC0,X
JML SpriteDraw_Blob_head_popping_out
.vanilla
JSL Sprite_PrepOAMCoordLong
JML SpriteDraw_Blob_bad_gfx

View File

@@ -9,18 +9,18 @@ LockAgahnimDoors:
LDA.w #$0000 : RTL
+ : CMP.w #$0001 : BNE +
LDA.l ProgressIndicator : AND.w #$000F : CMP.w #$0002 : !BGE .unlock ; if we rescued zelda, skip
JSR LockAgahnimDoorsCore : RTL
JSR.w LockAgahnimDoorsCore : RTL
+ : CMP.w #$0002 : BNE +
JSR LockAgahnimDoorsCore : BEQ .unlock
JSR.w LockAgahnimDoorsCore : BEQ .unlock
PHX : PHY
SEP #$30
JSL CheckTowerOpen
JSL.l CheckTowerOpen
REP #$30
PLY : PLX
!BGE .crystalOrUnlock
LDA.w #$0001 : RTL
.crystalOrUnlock
LDA.l SwapAgaGanonsTower : AND.w #$00FF : BEQ .unlock
LDA.l InvertedMode : AND.w #$00FF : BEQ .unlock
LDA.l OverworldEventDataWRAM+$43 : AND.w #$0020 : BNE .unlock ; Check if GT overlay is already on or not
LDA.w AButtonAct : AND.w #$0080 : BEQ ++ ;If we are holding an item
@@ -29,7 +29,7 @@ LockAgahnimDoors:
LDA.w #$0001 : RTL ;Keep the door locked
++
SEP #$30
JSL AncillaAdd_GTCutscene ;Add tower break seal
JSL $899B6F ;Add tower break seal
REP #$30
LDA.w #$0001 ;Prevent door from opening that frame otherwise it glitchy
RTL
@@ -42,7 +42,7 @@ LockAgahnimDoors:
RTL
;---------------------------------------------------------------------------------
FlagAgahnimDoor:
LDA.l SwapAgaGanonsTower : BEQ .vanilla
LDA.l InvertedMode : BEQ .vanilla
LDA.l OverworldEventDataWRAM+$43 : ORA.b #$20 : STA.l OverworldEventDataWRAM+$43 ; activate GT overlay
@@ -63,16 +63,16 @@ RTS
RTS
;--------------------------------------------------------------------------------
SmithDoorCheck:
LDA.l FollowerTravelAllowed : AND.w #$00FF : BEQ .orig
;If FollowerTravelAllowed is set Frog/Smith can enter multi-entrance overworld doors
JML Overworld_Entrance_BRANCH_RHO
LDA.l SmithTravelsFreely : AND.w #$00FF : BEQ .orig
;If SmithTravelsFreely is set Frog/Smith can enter multi-entrance overworld doors
JML.l Overworld_Entrance_BRANCH_RHO
.orig ; The rest is equivlent to what we overwrote
CPX.w #$0076 : !BGE +
JML Overworld_Entrance_BRANCH_LAMBDA
JML.l Overworld_Entrance_BRANCH_LAMBDA
+
JML Overworld_Entrance_BRANCH_RHO
JML.l Overworld_Entrance_BRANCH_RHO
;--------------------------------------------------------------------------------
AllowStartFromSingleEntranceCave:
; 16 Bit A, 16 bit XY
@@ -80,14 +80,15 @@ AllowStartFromSingleEntranceCave:
LDA.l StartingEntrance : AND.w #$00FF ; What we wrote over
PHA
TAX
LDA.l StartingAreaExitOffset, X : AND.w #$00FF
LDA.l StartingAreaExitOffset, X
AND.w #$00FF
BNE +
JMP .done
+
DEC
STA.b Scrap00
ASL #2 : !ADD.l Scrap00 : ASL #2 ; mult by 20
ASL #2 : !ADD Scrap00 : ASL #2 ; mult by 20
TAX
LDA.w #$0016 : STA.l EN_MAINDESQ ; Cache the main screen designation
@@ -125,7 +126,7 @@ AllowStartFromSingleEntranceCave:
LDA.l StartingEntrance : TAX
LDA.l StartingAreaOverworldDoor, X : STA.l PreviousOverworldDoor ;Load overworld door
REP #$20 ; reset 16-bit accumulator
JSL CacheDoorFrameData
JSL.l CacheDoorFrameData
.done
PLA
@@ -137,15 +138,15 @@ AllowStartFromExit:
LDA.l ShouldStartatExit, X : BNE .doStart
LDA.l StartingEntrance ; what we wrote over
JML AllowStartFromExitReturn
JML.l AllowStartFromExitReturn
.doStart
LDA.l Module1B_SpawnSelect_spawns, X
LDA.l $828481, X ;Module_LocationMenu_starting_points
ASL : TAX
LDA.l SpawnPointData_room_id, X : STA.b RoomIndex
LDA.l SpawnPointData_room_id+1, X : STA.b RoomIndex+1
LDA.l $82D8D2, X : STA.b RoomIndex
LDA.l $82D8D3, X : STA.b RoomIndex+1
; Go to pre-overworld mode
LDA.b #$08 : STA.b GameMode
@@ -157,7 +158,7 @@ JML AllowStartFromExitReturn
LDA.b #$01 : STA.l UpdateHUDFlag
JSL Equipment_SearchForEquippedItemLong
JSL HUD_RebuildIndoor_Palace
JSL HUD_RebuildLong2
JSL Equipment_UpdateEquippedItemLong
RTL
@@ -165,9 +166,9 @@ RTL
CheckHole:
LDX.w #$0024
.nextHoleClassic
LDA.b Scrap00 : CMP.l Overworld_GetPitDestination_map16, X
LDA.b Scrap00 : CMP.l $9BB800, X
BNE .wrongMap16Classic
LDA.b OverworldIndex : CMP.l Overworld_GetPitDestination_screen, X
LDA.b OverworldIndex : CMP.l $9BB826, X
BEQ .matchedHoleClassic
.wrongMap16Classic
DEX #2 : BPL .nextHoleClassic
@@ -192,16 +193,16 @@ JML Overworld_Hole_End
;--------------------------------------------------------------------------------
PreventEnterOnBonk:
STA.b Scrap00 ; part of what we wrote over
LDX.b OverworldIndex : LDA.l OWTileMapAlt, X : AND.w #$0001 : BEQ .done
LDA.l InvertedMode : AND.w #$00FF : BEQ .done
LDA.b LinkState : AND.w #$00FF : CMP.w #$0014 : BNE .done ;in mirror mode?
LDA.l OWTileWorldAssoc, X : AND.w #$00FF : CMP.b WorldCache : BEQ .done ; Are we bonking, or doing the superbunny glitch?
LDA.b OverworldIndex : AND.w #$0040 : CMP.b WorldCache : BEQ .done ; Are we bonking, or doing the superbunny glitch?
; If in inverted, are in mirror mode, and are bonking then do not enter
JML PreventEnterOnBonk_BRANCH_IX
JML.l PreventEnterOnBonk_BRANCH_IX
.done
LDX.w #$0102 ; rest of what we wrote over
JML PreventEnterOnBonk_return
JML.l PreventEnterOnBonk_return
;--------------------------------------------------------------------------------
TurtleRockEntranceFix:
LDA.l TurtleRockAutoOpenFix : BEQ .done
@@ -212,15 +213,15 @@ TurtleRockEntranceFix:
RTL
;--------------------------------------------------------------------------------
AnimatedEntranceFix: ;when an entrance animation tries to start
PHA : PHX
LDA.b OverworldIndex : TAX : AND.b #$40 : BNE + ; on a light world screen
LDA.l OWTileMapAlt, X : BNE + ; tile is flipped
PLX : PLA
PHA
LDA.l InvertedMode : BEQ + ;If we are in inverted mode
LDA.b OverworldIndex : AND.b #$40 : BNE + ;and in the light world
PLA
STZ.w OWEntranceCutscene ; skip it.
LDA.b #$00
RTL
+
PLX : PLA
PLA
STA.w CutsceneFlag ;what we wrote over
STA.w FreezeSprites ;what we wrote over
STA.w SkipOAM ;what we wrote over

View File

@@ -5,78 +5,60 @@ OnPrepFileSelect:
+
PHA : PHX
REP #$10
JSL LoadAlphabetTilemap
JSL LoadFullItemTiles
JSL.l LoadAlphabetTilemap
JSL.l LoadFullItemTiles
SEP #$10
PLX : PLA
RTL
;--------------------------------------------------------------------------------
OnDrawHud:
JSL DrawChallengeTimer ; this has to come before NewDrawHud because the timer overwrites the compass counter
JSL NewDrawHud
JSL DrHudOverride
JSL SwapSpriteIfNecessary
JSL CuccoStorm
JSL PollService
JML ReturnFromOnDrawHud
JSL.l DrawChallengeTimer ; this has to come before NewDrawHud because the timer overwrites the compass counter
JSL.l NewDrawHud
JSL.l SwapSpriteIfNecessary
JSL.l CuccoStorm
JSL.l PollService
JML.l ReturnFromOnDrawHud
;--------------------------------------------------------------------------------
OnDungeonEntrance:
STA.l PegColor ; thing we wrote over
JSL MaybeFlagDungeonTotalsEntrance
LDA.w #$0001 : STA.l UpdateHUDFlag
SEP #$30
JSL DynamicDropGFXClear
REP #$30
RTL
;--------------------------------------------------------------------------------
OnDungeonBossExit:
JSL StatTransitionCounter
JSL ClearMultiworldText
JSL DynamicDropGFXClear
JSL.l StatTransitionCounter
RTL
;--------------------------------------------------------------------------------
OnPlayerDead:
PHA
JSL SetDeathWorldChecked
JSL DynamicDropGFXClear
JSL SetSilverBowMode
JSL RefreshRainAmmo
JSL.l SetDeathWorldChecked
JSL.l SetSilverBowMode
JSL.l RefreshRainAmmo
PLA
RTL
;--------------------------------------------------------------------------------
OnDungeonExit:
PHA : PHP
SEP #$20 ; set 8-bit accumulator
JSL SQEGFix
JSL DynamicDropGFXClear
JSL.l SQEGFix
PLP : PLA
STA.w DungeonID : STZ.w Map16ChangeIndex ; thing we wrote over
PHA : PHP
LDA.w #$0001 : STA.l UpdateHUDFlag
JSL HUD_RebuildLong
JSL FloodGateResetInner
JSL SetSilverBowMode
JSL.l HUD_RebuildLong
JSL.l FloodGateResetInner
JSL.l SetSilverBowMode
PLP : PLA
RTL
;--------------------------------------------------------------------------------
OnSave:
LDA.b #$70 : PHA : PLB ; thing we wrote over - data bank change
JSL DarkWorldSaveFix
JML MSUResumeReset
;--------------------------------------------------------------------------------
OnQuit:
JSL SQEGFix
JSL.l SQEGFix
LDA.b #$00 : STA.l AltTextFlag ; bandaid patch bug with mirroring away from text
LDA.b #$10 : STA.b MAINDESQ ; thing we wrote over
RTL
;--------------------------------------------------------------------------------
OnDeathNoSave:
JSL MSUResumeReset
LDA.b #$05 : STA.b $10 ; what we wrote over
RTL
;--------------------------------------------------------------------------------
OnUncleItemGet:
PHA
@@ -85,9 +67,8 @@ OnUncleItemGet:
BIT.b #$02 : BEQ + : STA.l InfiniteBombs : +
BIT.b #$01 : BEQ + : STA.l InfiniteArrows : +
LDA.l UncleItem_Player : STA.l !MULTIWORLD_ITEM_PLAYER_ID
PLA
JSL Link_ReceiveItem
JSL.l Link_ReceiveItem
LDA.l UncleRefill : BIT.b #$04 : BEQ + : LDA.b #$80 : STA.l MagicFiller : + ; refill magic
LDA.l UncleRefill : BIT.b #$02 : BEQ + : LDA.b #50 : STA.l BombsFiller : + ; refill bombs
@@ -107,8 +88,8 @@ RTL
;--------------------------------------------------------------------------------
OnAga1Defeated:
STA.l ProgressIndicator ; vanilla game state stuff we overwrote
; seems light_speed option to auto triforce room is unused for now
BRA +
LDA.l GanonVulnerableMode
CMP.b #$06 : BNE +
.light_speed
REP #$20
LDA.w #$0019 : STA.b GameMode
@@ -121,13 +102,13 @@ OnAga1Defeated:
RTL
;--------------------------------------------------------------------------------
OnAga2Defeated:
JSL Dungeon_SaveRoomData_justKeys ; thing we wrote over, make sure this is first
JSL.l Dungeon_SaveRoomData_justKeys ; thing we wrote over, make sure this is first
LDA.b #$01 : STA.l Aga2Duck
LDA.w DungeonID : CMP.b #$1A : BNE +
LDA.l DungeonsCompleted : ORA.b #$04 : STA.l DungeonsCompleted
+
LDA.b #$FF : STA.w DungeonID
JML IncrementAgahnim2Sword
JML.l IncrementAgahnim2Sword
;--------------------------------------------------------------------------------
OnFileCreation:
PHB
@@ -139,12 +120,12 @@ OnFileCreation:
LDA.w #$010C
LDX.w #$B3E3
LDY.w #$03E3
MVN CartridgeSRAM>>16, InitSRAMTable>>16
MVN CartridgeSRAM>>16, InitSRAMTable>>16
PLB
; Resolve instant post-aga if standard
SEP #$20
LDA.l InitProgressIndicator : BIT.b #$80 : BEQ +
LDA.l InitProgressIndicator : BIT #$80 : BEQ +
LDA.b #$00 : STA.l ProgressIndicatorSRAM ; set post-aga after zelda rescue
LDA.b #$00 : STA.l OverworldEventDataSRAM+$02 ; keep rain state vanilla
+
@@ -152,43 +133,40 @@ OnFileCreation:
; Set validity value and do some cleanup. Jump to checksum done.
LDA.w #$55AA : STA.l FileValiditySRAM
JSL WriteSaveChecksumAndBackup
JSL.l WriteSaveChecksumAndBackup
STZ.b Scrap00
STZ.b Scrap01
JML InitializeSaveFile_checksum_done
JML.l InitializeSaveFile_checksum_done
;--------------------------------------------------------------------------------
OnFileLoad:
REP #$10 ; set 16 bit index registers
JSL EnableForceBlank ; what we wrote over
REP #$20 : LDA.l TotalItemCount : STA.l MultiClientFlagsWRAM+1 : SEP #$20
LDA.l MultiClientFlagsROM : STA.l MultiClientFlagsWRAM
JSL.l EnableForceBlank ; what we wrote over
LDA.b #$07 : STA.w BG34NBA ; Restore screen 3 to normal tile area
LDA.l FileMarker : BNE +
JSL OnNewFile
JSL.l OnNewFile
LDA.b #$FF : STA.l FileMarker
+
LDA.w DeathReloadFlag : BNE + ; don't adjust the worlds for "continue" or "save-continue"
LDA.l MosaicLevel : BNE + ; don't adjust worlds if mosiac is enabled (Read: mirroring in dungeon)
JSL DoWorldFix
JSL.l DoWorldFix
+
JSL MasterSwordFollowerClear
JSL.l MasterSwordFollowerClear
LDA.b #$FF : STA.l RNGLockIn ; reset rng item lock-in
LDA.l GenericKeys : BEQ +
LDA.l CurrentGenericKeys : STA.l CurrentSmallKeys ; copy generic keys to key counter
+
JSL SetSilverBowMode
JSL RefreshRainAmmo
JSL SetEscapeAssist
JSL.l SetSilverBowMode
JSL.l RefreshRainAmmo
JSL.l SetEscapeAssist
LDA.l IsEncrypted : CMP.b #01 : BNE +
JSL LoadStaticDecryptionKey
+
SEP #$10 ; restore 8 bit index registers
JSL DynamicDropGFXClear
RTL
;--------------------------------------------------------------------------------
OnNewFile:
@@ -214,40 +192,21 @@ RTL
;--------------------------------------------------------------------------------
OnInitFileSelect:
LDA.b #$51 : STA.w $0AA2 ;<-- Line missing from JP1.0, needed to ensure "extra" copy of naming screen graphics are loaded.
JSL EnableForceBlank
JSL.l EnableForceBlank
RTL
;--------------------------------------------------------------------------------
OnGloomDamage:
LDA.b #$01
STA.l UpdateHUDFlag
LDA.l MaximumHealth
SEC : SBC.b #$08
STA.l CurrentHealth
BEQ +
STA.l MaximumHealth
+ RTL
;--------------------------------------------------------------------------------
OnLinkDamaged:
JSL IncrementDamageTakenCounter_Arb
LDA.l ChallengeModes : AND.b #$03 : CMP.b #$02 : BEQ .gloom
JML OHKOTimer
.gloom
STZ.b $00
JML OnGloomDamage
JSL.l IncrementDamageTakenCounter_Arb
JML.l OHKOTimer
;--------------------------------------------------------------------------------
;OnEnterWater:
; JSL UnequipCapeQuiet ; what we wrote over
; JSL.l UnequipCapeQuiet ; what we wrote over
;RTL
;--------------------------------------------------------------------------------
OnLinkDamagedFromPit:
LDA.l ChallengeModes : AND.b #$03 : CMP.b #$02 : BEQ .gloom
JSL OHKOTimer
BRA +
.gloom
JSL OnGloomDamage
CLC : ADC.b #$08 : STA.l CurrentHealth
JSL.l OHKOTimer
+ LDA.l AllowAccidentalMajorGlitch
LDA.l AllowAccidentalMajorGlitch
BEQ ++
-- LDA.b #$14 : STA.b GameSubMode ; thing we wrote over
@@ -259,16 +218,11 @@ OnLinkDamagedFromPit:
RTL
;--------------------------------------------------------------------------------
OnLinkDamagedFromPitOutdoors:
LDA.l ChallengeModes : AND.b #$03 : CMP.b #$02 : BEQ .gloom
JML OHKOTimer ; make sure this is last
.gloom
JSL OnGloomDamage
CLC : ADC.b #$08
RTL
JML.l OHKOTimer ; make sure this is last
;--------------------------------------------------------------------------------
OnOWTransition:
JSL FloodGateReset
JSL StatTransitionCounter
JSL.l FloodGateReset
JSL.l StatTransitionCounter
PHP
SEP #$20 ; set 8-bit accumulator
LDA.b #$FF : STA.l RNGLockIn ; clear lock-in
@@ -277,7 +231,6 @@ OnOWTransition:
RTL
;--------------------------------------------------------------------------------
OnLoadDuckMap:
JSL SelectFirstFluteSpot
LDA.l DuckMapFlag
BNE +
INC : STA.l DuckMapFlag
@@ -292,7 +245,7 @@ PreItemGet:
RTL
;--------------------------------------------------------------------------------
PostItemGet:
STZ.w ProgressiveFlag
STZ.w ShopPurchaseFlag
LDA.w ItemReceiptMethod : CMP.b #$01 : BEQ +
LDX.w CurrentSpriteSlot
STZ.w SpriteMetaData,X
@@ -304,28 +257,40 @@ PostItemAnimation:
LDA.b #$00 : STA.l BusyItem ; mark item as finished
LDA.l TextBoxDefer : BEQ +
STZ.w TextID : STZ.w TextID+1 ; reset decompression buffer
JSL Main_ShowTextMessage_Alt
JSL.l Main_ShowTextMessage_Alt
LDA.b #$00 : STA.l TextBoxDefer
+
LDA.w ItemReceiptMethod : CMP.b #$01 : BNE +
LDA.b LinkDirection : BEQ +
JSL IncrementChestTurnCounter
LDA.b LinkDirection : BEQ +
JSL.l IncrementChestTurnCounter
+
LDA.b IndoorsFlag : BEQ +
REP #$20 : LDA.b RoomIndex : STA.l !MULTIWORLD_ROOMID : SEP #$20
LDA.w RoomItemsTaken : STA.l !MULTIWORLD_ROOMDATA
+
LDA.l !MULTIWORLD_ITEM_PLAYER_ID : BEQ +
STZ.w ItemReceiptMethod
LDA.b #$00 : STA.l !MULTIWORLD_ITEM_PLAYER_ID
PLB
JML Ancilla_ReceiveItem_objectFinished
+
REP #$20
PEA.w $7E00
PLB : PLB
LDA.w TransparencyFlag : BNE .SP05
LDA.l PalettesCustom_off_black+$00 : STA.w PaletteBuffer+$0170 : STA.w PaletteBufferAux+$0170
LDA.l PalettesCustom_off_black+$02 : STA.w PaletteBuffer+$0172 : STA.w PaletteBufferAux+$0172
STA.w PaletteBuffer+$0174 : STA.w PaletteBufferAux+$0174
STA.w PaletteBuffer+$0176 : STA.w PaletteBufferAux+$0176
STA.w PaletteBuffer+$0178 : STA.w PaletteBufferAux+$0178
STA.w PaletteBuffer+$017A : STA.w PaletteBufferAux+$017A
STA.w PaletteBuffer+$017C : STA.w PaletteBufferAux+$017C
STA.w PaletteBuffer+$017E : STA.w PaletteBufferAux+$017E
BRA .done
.SP05
LDA.l PalettesCustom_off_black+$00 : STA.w PaletteBuffer+$01B0 : STA.w PaletteBufferAux+$01B0
LDA.l PalettesCustom_off_black+$02 : STA.w PaletteBuffer+$01B2 : STA.w PaletteBufferAux+$01B2
STA.w PaletteBuffer+$01B4 : STA.w PaletteBufferAux+$01B4
STA.w PaletteBuffer+$01B6 : STA.w PaletteBufferAux+$01B6
STA.w PaletteBuffer+$01B8 : STA.w PaletteBufferAux+$01B8
STA.w PaletteBuffer+$01BA : STA.w PaletteBufferAux+$01BA
STA.w PaletteBuffer+$01BC : STA.w PaletteBufferAux+$01BC
STA.w PaletteBuffer+$01BE : STA.w PaletteBufferAux+$01BE
.done
INC.b NMICGRAM
SEP #$20
STZ.w ItemReceiptMethod : LDA.w AncillaGet, X ; thing we wrote over to get here
PLB
JML Ancilla_ReceiveItem_optimus+6
RTL
;--------------------------------------------------------------------------------

View File

@@ -27,7 +27,7 @@ DontUseZSNES:
LDA.b #$00
STA.l NMITIMEN ; disable NMI and IRQ
STA.l HDMAENABLE ; disable HDMA
STA.l HDMAEN ; disable HDMA
ROR ; A = 0x80 from carry
STA.l INIDISP
@@ -48,7 +48,7 @@ DontUseZSNES:
STA.l DAS0L
LDA.w #$0001
STA.l DMAENABLE
STA.l MDMAEN
JSR ConfigurePPUForFailureReport
JSR ConfigureBSODVWF
@@ -93,7 +93,7 @@ Crashed:
LDA.b #$00
STA.l NMITIMEN ; disable NMI and IRQ
STA.l HDMAENABLE ; disable HDMA
STA.l HDMAEN ; disable HDMA
ROR ; A = 0x80 from carry
STA.l INIDISP
@@ -114,7 +114,7 @@ Crashed:
STA.l DAS0L
LDA.w #$0001
STA.l DMAENABLE
STA.l MDMAEN
;===================================================================================================
@@ -312,7 +312,7 @@ DrawVWFMessage:
STZ.w A1B0
LDA.b #$01
STA.w DMAENABLE
STA.w MDMAEN
REP #$20
@@ -376,7 +376,7 @@ DrawFailureVWFChar:
LDY.w #$0000
.next_row
LDA.b (Scrap08),Y
LDA.b ($08),Y
AND.w #$00FF
XBA
LDX.w VWFS
@@ -427,7 +427,7 @@ LoadBSODHexFont:
STA.w A1B0
LDA.b #$01
STA.w DMAENABLE
STA.w MDMAEN
REP #$30
@@ -467,7 +467,7 @@ ConfigureBSODVWF:
PEA.w $0001
LDA.w #15
STA.w LinkRecoilX
STA.w $28
LDA.w #$0042>>1
BRA .start
@@ -475,13 +475,13 @@ ConfigureBSODVWF:
.next_row
PHA
LDA.w LinkPosY
LDA.w $20
CLC
LDA.w LinkPosY
LDA.w $20
ADC.w #32
.start
STA.w LinkPosY
STA.w $20
STA.b VMADDL
PLA
@@ -494,7 +494,7 @@ ConfigureBSODVWF:
DEY
BNE .next_char
DEC.w LinkRecoilX
DEC.w $28
BNE .next_row
LDA.w #$0000

View File

@@ -27,9 +27,9 @@ RTL
FairyPond_Init:
LDA.l Restrict_Ponds : BNE +
LDA.b #$48
JML Sprite_ShowMessageFromPlayerContact
JML.l Sprite_ShowMessageFromPlayerContact
+
PHY : JSL Sprite_CheckDamageToPlayerSameLayerLong : BCC +
PHY : JSL.l Sprite_CheckDamageToPlayerSameLayerLong : BCC +
LDA.l BottleContentsOne : CMP.b #$02 : BNE ++ : LDA.b #$1C : PHA : BRA .emptyBottle : ++
LDA.l BottleContentsTwo : CMP.b #$02 : BNE ++ : LDA.b #$1D : PHA : BRA .emptyBottle : ++
LDA.l BottleContentsThree : CMP.b #$02 : BNE ++ : LDA.b #$1E : PHA : BRA .emptyBottle : ++
@@ -38,7 +38,7 @@ FairyPond_Init:
LDA.b #$0A : STA.w SpriteActivity, X
LDA.b #$51
LDY.b #$01
JSL Sprite_ShowMessageFromPlayerContact
JSL.l Sprite_ShowMessageFromPlayerContact
JMP .cleanup
.emptyBottle

View File

@@ -23,7 +23,7 @@ FlagFastCredits:
TSB.b FastCreditsActive
.slow
LDA.b GameSubMode
LDA.b $11
ASL
TAX
@@ -79,10 +79,10 @@ FastCreditsCutsceneScrollY:
FastCreditsCutsceneScroll:
LDA.w $00E2,Y
CMP.l Credits_ScrollScene_target_y,X ; compare to target
CMP.l $8EC308,X ; compare to target
ROL.b Scrap00 ; put carry in here
LDA.l Credits_ScrollScene_movement_y,X ; get movement
LDA.l $8EC348,X ; get movement
BPL ++ ; if positive, leave saved carry alone
INC.b Scrap00 ; otherwise, flip it
++ ROR.b Scrap00 ; recover carry

File diff suppressed because it is too large Load Diff

View File

@@ -23,12 +23,12 @@ macro fs_draw16x8(screenrow,screencol)
endmacro
macro fs_draw8x16(screenrow,screencol)
%fs_draw8x8(<screenrow>,<screencol>)
!ADD.w #$0010
!ADD #$0010
%fs_draw8x8(<screenrow>+1,<screencol>)
endmacro
macro fs_draw16x16(screenrow,screencol)
%fs_draw16x8(<screenrow>,<screencol>)
!ADD.w #$000F
!ADD #$000F
%fs_draw16x8(<screenrow>+1,<screencol>)
endmacro
@@ -248,12 +248,8 @@ DrawPlayerFileShared:
; Flute
LDA.l InventoryTrackingSRAM : AND.w #$0003 : BEQ +
LDA.l $7003C2 : AND.w #$00FF : BNE .pseudo
%fs_drawItem(7,16,FileSelectItems_flute)
BRA ++
.pseudo
%fs_drawItem(7,16,FileSelectItems_flute_green)
BRA ++
+
%fs_drawItemGray(7,16,FileSelectItems_flute)
++
@@ -303,13 +299,7 @@ DrawPlayerFileShared:
%fs_drawItemBasic(EquipmentSRAM+$12,9,18,FileSelectItems_cape)
; Mirror
LDA.l EquipmentSRAM+$13 : AND.w #$00FF : BEQ +
CMP.w #$0001 : BNE +
%fs_drawItem(9,20,FileSelectItems_mirrorScroll)
BRA ++
+
%fs_drawItemBasic(EquipmentSRAM+$13,9,20,FileSelectItems_mirror)
++
%fs_drawItemBasic(EquipmentSRAM+$13,9,20,FileSelectItems_mirror)
; Bottles
%fs_drawBottle(EquipmentSRAM+$1C,3,23)
@@ -395,7 +385,7 @@ DrawPlayerFileShared:
++
LDA.l EquipmentSRAM+$0130 : AND.w #$00FF
JSL HexToDec
JSL.l HexToDec
LDA.l HexToDecDigit4 : AND.w #$00FF : ORA.w #!FS_COLOR_BW|$02E0 : %fs_draw8x8(11,26)
LDA.l HexToDecDigit5 : AND.w #$00FF : ORA.w #!FS_COLOR_BW|$02E0 : %fs_draw8x8(11,27)
@@ -543,8 +533,6 @@ FileSelectItems:
dw #$0264|!FS_COLOR_BROWN, #$0265|!FS_COLOR_BROWN, #$0274|!FS_COLOR_BROWN, #$0275|!FS_COLOR_BROWN
.flute
dw #$0266|!FS_COLOR_BLUE, #$0267|!FS_COLOR_BLUE, #$0276|!FS_COLOR_BLUE, #$0277|!FS_COLOR_BLUE
.flute_green
dw #$0266|!FS_COLOR_GREEN, #$0267|!FS_COLOR_GREEN, #$0276|!FS_COLOR_GREEN, #$0277|!FS_COLOR_GREEN
.book
dw #$026A|!FS_COLOR_GREEN, #$026B|!FS_COLOR_GREEN, #$027A|!FS_COLOR_GREEN, #$027B|!FS_COLOR_GREEN
.redcane
@@ -555,8 +543,6 @@ FileSelectItems:
dw #$0288|!FS_COLOR_RED, #$0289|!FS_COLOR_RED, #$0298|!FS_COLOR_RED, #$0299|!FS_COLOR_RED
.mirror
dw #$028A|!FS_COLOR_BLUE, #$028B|!FS_COLOR_BLUE, #$029A|!FS_COLOR_BLUE, #$029B|!FS_COLOR_BLUE
.mirrorScroll
dw #$02C2|!FS_COLOR_YELLOW, #$02C3|!FS_COLOR_YELLOW, #$02D2|!FS_COLOR_YELLOW, #$02d3|!FS_COLOR_YELLOW
.flippers
dw #$024E|!FS_COLOR_BLUE, #$024F|!FS_COLOR_BLUE, #$025F|!FS_COLOR_BLUE|!FS_HFLIP, #$025F|!FS_COLOR_BLUE
@@ -630,7 +616,7 @@ FileSelectItems:
FileSelectDrawHudBar:
LDA.w #$02DB|!FS_COLOR_GREEN : %fs_draw16x8(0,10)
LDA.l DisplayRupeesSRAM
JSL HUDHex4Digit_Long
JSL.l HUDHex4Digit_Long
LDA.b Scrap04 : AND.w #$00FF : !ADD.w #$0250+!FS_COLOR_BW : %fs_draw8x8(1,9)
LDA.b Scrap05 : AND.w #$00FF : !ADD.w #$0250+!FS_COLOR_BW : %fs_draw8x8(1,10)
LDA.b Scrap06 : AND.w #$00FF : !ADD.w #$0250+!FS_COLOR_BW : %fs_draw8x8(1,11)
@@ -638,7 +624,7 @@ FileSelectDrawHudBar:
LDA.w #$02CB|!FS_COLOR_BLUE : %fs_draw16x8(0,14)
LDA.l BombsEquipmentSRAM : AND.w #$00FF
JSL HUDHex2Digit_Long
JSL.l HUDHex2Digit_Long
TYA : AND.w #$00FF : !ADD.w #$0250+!FS_COLOR_BW : %fs_draw8x8(1,14)
TXA : AND.w #$00FF : !ADD.w #$0250+!FS_COLOR_BW : %fs_draw8x8(1,15)
@@ -649,7 +635,7 @@ FileSelectDrawHudBar:
LDA.w #$02C9|!FS_COLOR_BROWN : %fs_draw16x8(0,17)
++
LDA.l CurrentArrowsSRAM : AND.w #$00FF
JSL HUDHex2Digit_Long
JSL.l HUDHex2Digit_Long
TYA : AND.w #$00FF : !ADD.w #$0250+!FS_COLOR_BW : %fs_draw8x8(1,17)
TXA : AND.w #$00FF : !ADD.w #$0250+!FS_COLOR_BW : %fs_draw8x8(1,18)
RTS
@@ -793,7 +779,7 @@ LoadFullItemTiles:
LDA.b #FileSelectNewGraphics>>16 : STA.w A1B0
LDX.w #FileSelectNewGraphics : STX.w A1T0L
LDX.w #$0C00 : STX.w DAS0L
LDA.b #$01 : STA.w DMAENABLE
LDA.b #$01 : STA.w MDMAEN
RTL
;--------------------------------------------------------------------------------
; z colon @
@@ -810,7 +796,7 @@ LoadLowerCaseLettersSymbols:
LDX.w #NewFont+$400 : STX.w A1T0L
LDX.w #$0400 : STX.w DAS0L
LDX.w #$2D00 : STX.w VMADDL
LDA.b #$01 : STA.w DMAENABLE
LDA.b #$01 : STA.w MDMAEN
; : @ #
LDA.b #NewFont>>16 : STA.w A1B0
@@ -820,9 +806,9 @@ LoadLowerCaseLettersSymbols:
LDX.w #$0030 : STX.w DAS0L : STX.w DAS1L
LDX.w #$2E50 : STX.w VMADDL
LDA.b #$01 : STA.w DMAENABLE
LDA.b #$01 : STA.w MDMAEN
LDX.w #$2ED0 : STX.w VMADDL
LDA.b #$02 : STA.w DMAENABLE
LDA.b #$02 : STA.w MDMAEN
RTL
;--------------------------------------------------------------------------------
LoadFileSelectVanillaItems:
@@ -836,7 +822,7 @@ LoadFileSelectVanillaItems:
LDX.w #DecompBuffer2 : STX.w A1T0L
LDX.w #$0600 : STX.w DAS0L
LDX.w #$2F00 : STX.w VMADDL
LDA.b #$01 : STA.w DMAENABLE
LDA.b #$01 : STA.w MDMAEN
SEP #$10
RTL
@@ -845,10 +831,10 @@ SetFileSelectPalette:
LDA.b GameMode : CMP.b #$04 : BNE +
; load the vanilla file select screen BG3 palette for naming screen
LDA.b #$01 : STA.w $0AB2
JSL Palette_Hud
JSL.l Palette_Hud
BRA .done
+
JSL LoadCustomHudPalette
JSL.l LoadCustomHudPalette
.done
JML Palette_SelectScreen ; Jump to the subroutine whose call we wrote over
@@ -881,7 +867,7 @@ DrawPlayerFile_credits:
%fs_draw8x16(3,7)
LDA.l EquipmentSRAM+$9F : ORA.w #!FS_COLOR_BW
%fs_draw8x16(3,8)
LDA.l EquipmentSRAM+$2C : AND.w #$00FF : LSR #3 : STA.b Scrap02
%fs_LDY_screenpos(0,20)
LDA.l HUDHeartColors_index : ASL : TAX
@@ -966,8 +952,8 @@ MaybeForceFileName:
BRA -
.done
SEP #$20
JML InitializeSaveFile
JML.l InitializeSaveFile
+
JML NameFile_MakeScreenVisible
JML.l NameFile_MakeScreenVisible
;--------------------------------------------------------------------------------

View File

@@ -3,12 +3,12 @@
;--------------------------------------------------------------------------------
; Written over and used by OnEnterWater hook.
; UnequipCapeQuiet:
; LDA.b #$20 : STA.w PoofTimer
; STZ.w NoDamage
; STZ.b CapeOn
; STZ.w LinkZap
; RTL
UnequipCapeQuiet:
LDA.b #$20 : STA.w PoofTimer
STZ.w NoDamage
STZ.b CapeOn
STZ.w LinkZap
RTL
protectff:
LDA.l AllowAccidentalMajorGlitch
@@ -43,7 +43,7 @@ protectff:
BMI .special_overworld
AND.b #$3F
CMP.l Overworld_ActualScreenID,X
CMP.l $82A4E3,X
BEQ ++
.protect
@@ -71,26 +71,3 @@ protectff:
.spow
db $80, $81, $81, $FF, $FF, $FF, $FF, $FF
db $FF, $81, $81, $FF, $FF, $FF, $FF, $FF
FlipperScrollWarp:
STZ.b Scrap00 : STZ.b Scrap02 ; what we wrote over
LDA.l AllowAccidentalMajorGlitch : BEQ .checkX : RTL
.checkX
LDA.b LinkPosX : CMP.w $0604 : BCC +
CMP.w CameraTargetE : BCS +
BRA .checkY
+ LDA.l $7EC186
STA.b LinkPosX
.checkY
LDA.b LinkPosY : CMP.w $0600 : BCC +
CMP.w CameraTargetS : BCS +
RTL
+ LDA.l $7EC184
STA.b LinkPosY
RTL
pushpc
; fixes incorrect vanilla camera scroll boundary values for Zora's Domain
org $82E4E9 : dw $0600
org $82E529 : dw $0600
pullpc

View File

@@ -2,7 +2,7 @@
; Floodgate Softlock Fix
;--------------------------------------------------------------------------------
FloodGateAndMasterSwordFollowerReset:
JSL MasterSwordFollowerClear
JSL.l MasterSwordFollowerClear
FloodGateReset:
LDA.l PersistentFloodgate : BNE +
LDA.l OverworldEventDataWRAM+$3B : AND.b #$DF : STA.l OverworldEventDataWRAM+$3B ; reset water outside floodgate
@@ -10,23 +10,16 @@ FloodGateReset:
LDA.l RoomDataWRAM[$010B].low : AND.b #$7F : STA.l RoomDataWRAM[$010B].low ; clear water inside floodgate
LDA.l RoomDataWRAM[$28].high : AND.b #$FE : STA.l RoomDataWRAM[$28].high ; clear water front room (room 40)
+
; note - official sram for getting keys under pots has changed for DR, see RoomPotData
FloodGateResetInner:
LDA.l Bugfix_SwampWaterLevel : BEQ .done
LDA.l DRMode : BEQ .check_room_35; Only do the check for room 37 if on door rando
LDA.l SwampDrain1HasItem : BEQ .flipper_check
LDA.l $7F666F : AND.b #$80 : BEQ .drain_room_37 ; Check if key in room 37 has been collected.
.flipper_check
LDA.l FlippersEquipment : AND.b #$01 : BNE .check_room_35 ; Check for flippers. This can otherwise softlock doors if flooded without flippers and no way to reset.
.drain_room_37
LDA.l RoomDataWRAM[$37].low : AND.b #$7F : STA.l RoomDataWRAM[$37].low ; clear water room 37 - outer room you shouldn't be able to softlock except in major glitches
.check_room_35
LDA.l SwampDrain2HasItem : BEQ .done
LDA.l $7F666B : AND.b #$80 : BNE .done ; Check if key in room 35 has been collected.
; no need to check for flippers on the inner room, as you can't get to the west door no matter what, without flippers.
LDA.l RoomDataWRAM[$35].low : AND.b #$7F : STA.l RoomDataWRAM[$35].low ; clear water room 35 - inner room with the easy key flood softlock
.done
LDA.l Bugfix_SwampWaterLevel : BEQ +++
LDA.l RoomDataWRAM[$37].low : AND.b #$04 : BEQ + ; Check if key in room 55 has been collected.
LDA.l FlippersEquipment : AND.b #$01 : BNE ++ ; Check for flippers. This can otherwise softlock doors if flooded without flippers and no way to reset.
+
LDA.l RoomDataWRAM[$37].low : AND.b #$7F : STA.l RoomDataWRAM[$37].low ; clear water room 55 - outer room you shouldn't be able to softlock except in major glitches
++
LDA.l RoomDataWRAM[$35].high : AND.b #$04 : BNE +++ ; Check if key in room 53 has been collected.
; no need to check for flippers on the inner room, as you can't get to the west door no matter what, without flippers.
LDA.l RoomDataWRAM[$35].low : AND.b #$7F : STA.l RoomDataWRAM[$35].low ; clear water room 53 - inner room with the easy key flood softlock
+++
RTL
;================================================================================

View File

@@ -5,14 +5,10 @@ SpawnHauntedGroveItem:
LDA.b OverworldIndex : CMP.b #$2A : BEQ + : RTL : + ; Skip if not the haunted grove
LDA.b IndoorsFlag : BEQ + : RTL : + ; Skip if indoors
; todo - how does this work now?
LDA.l HauntedGroveItem_Player : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.b #$EB
STA.l MiniGameTime
JSL Sprite_SpawnDynamically
LDA.b #$01 : STA.w SprRedrawFlag, Y
LDX.b #$00
LDA.b LinkDirection : CMP.b #$04 : BEQ + : INX : +
@@ -55,15 +51,13 @@ RTL
FluteBoy:
LDA.b GameMode : CMP.b #$1A : BEQ +
LDA.b #$01 : STA.w $0FDD
JML FluteBoy_Abort
JML.l FluteBoy_Abort
+
LDA.w SpriteActivity, X : CMP.b #$03 ; thing we wrote over
JML FluteBoy_Continue
JML.l FluteBoy_Continue
;--------------------------------------------------------------------------------
FreeDuckCheck:
LDA.l OWMode+1 : AND.b #!FLAG_OW_MIXED : BNE .skipInvertedCheck
LDA.l InvertedMode : BEQ .done
.skipInvertedCheck
LDA.l InvertedMode : BEQ .done
LDA.l FluteEquipment : CMP.b #$03 : BEQ .done ; flute is already active
; check the area, is it #$18 = 30?

View File

@@ -1,942 +0,0 @@
pushpc
; follower hooks
org $81EBB6
JSL MaybeSetZeldaCheckpoint
org $899FA1
db $FF, $FF, $FF ; disable timed follower messages
org $89A647
JSL MaybeSkipFollowerTrigger : NOP
org $89F544
JSL MaybeDeleteFollowersOnDeath
org $85EBCF
JSL SpritePrep_ZeldaFollower : NOP #2
org $85EC9E
JSL SpriteDraw_ZeldaMaiden
org $85ECD9
JSL Zelda_WaitingInCell
org $85ED46
JSL Zelda_BecomeFollower : NOP #2
org $9EE902
JSL SpritePrep_OldManFollower : NOP #2 : db $F0 ; BEQ
org $9DFF18
JSL SpriteDraw_OldManFollower
org $9EE9BC
JSL Follower_CheckMessageCollision
org $9EE9CC
JSL OldMan_BecomeFollower : NOP #2
org $86899C
JSL SpritePrep_BlindMaiden : NOP #2
org $8689A7
JSL BlindZeldaDespawnFix : NOP #2
org $9EE8B0
JSL SpriteDraw_ZeldaMaiden
org $9EE8CD
JSL Follower_CheckCollision
org $9EE8D7
JSL BlindMaiden_BecomeFollower : NOP
org $868A7E
JSL SpritePrep_SmithyFrog : BRA + : NOP #8 : +
org $86B2AA
JSL Follower_CheckMessageCollision
org $86B2B4
JSL Frog_BecomeFollower : NOP #2
org $86B341
JSL SpriteDraw_FrogFollower
org $868A53
JSL SpritePrep_PurpleChest : NOP #2
org $9EE0D7
JSL SpriteDraw_PurpleChest
org $9EE0E7
JSL Follower_CheckMessageCollision
org $9EE0ED
JSL PurpleChest_FollowCheck
org $9EE0F7
JSL PurpleChest_BecomeFollower : NOP
org $868A0A
JSL SpritePrep_SuperBomb
org $868A4A
SuperBomb_BecomeFollower_exit:
org $9EE16E
BRA + : NOP #6 : + ; fix bomb shop dialog for dwarfless big bomb
org $9EE1E8
JSL SuperBomb_FollowCheck
org $9EE1F1
JSL SuperBomb_BecomeFollower : NOP #2
org $9EE2C0
JSL SpriteDraw_SuperBomb
org $868D51
JSL SpritePrep_Kiki : NOP #2
org $9EE3E6
JSL Kiki_OfferToFollow
org $9EE495
JSL Kiki_FollowCheck : BRA + : NOP #12 : +
org $9EE4AF
JSL Kiki_BecomeFollower : NOP #2
org $9EE4F7
JSL Kiki_FixTeleportOnExit
org $89A1B2
JSL Kiki_DontScareTheMonke : NOP #3
org $868D63
JSL SpritePrep_Locksmith : NOP #2 : db $90 ; BCC
org $868D7E
db $80 ; BRA
org $86BCD9
JML Locksmith_Chillin_PostMessage
org $86BD09
JSL Locksmith_BecomeFollower : NOP #2
org $86BD7A ; allow follower pickup after purple chest item
LDA.b #$00 : STA.w SpriteActivity, X
JSL Locksmith_RespondToAnswer_PostItem
org $86BDB4
JSL SpriteDraw_LocksmithFollower
pullpc
MaybeSkipFollowerTrigger:
LDA.b GameMode : AND.w #$00FF : CMP.w #$0010 : BNE .normal
.no_trigger
INC : RTL
.normal
LDA.w $02F2 : AND.b Scrap06 ; what we wrote over
RTL
MaybeDeleteFollowersOnDeath:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
; s+q = favor keeping current follower
; death = favor replacing with unfulfilled starting followers
; during escape = always favor keeping zelda
LDA.b GameMode : CMP.b #$17 : BEQ .keep
LDA.w DungeonID : NOP #2 : BPL .keep
LDA.l InitFollowerIndicator : BEQ .keep
JSL DetermineFollowerSpawn_check_resolved : BCS .keep
LDA.l ProgressIndicator : CMP.b #$02 : BCS .delete
LDA.l FollowerIndicator : CMP.b #$01 : BEQ .keep
.delete
PLA : PLA : PEA.w $89F558-1
RTL
.keep
PLA : PLA : PEA.w $89F55E-1
RTL
.vanilla
LDA.l FollowerIndicator ; what we wrote over
RTL
StartingFollower:
LDA.l InitFollowerIndicator : BEQ .return
PHA
REP #$20
; possible spawn points
LDA.b RoomIndex : CMP.w #$0104 : BEQ + ; links house
CMP.w #$0012 : BEQ + ; sanc
CMP.w #$00E4 : BEQ + ; old man
CMP.w #$0112 : BEQ + ; dark sanc
CMP.w #$011C : BEQ + ; bomb shop
SEP #$20 : PLA : RTL
+
SEP #$20
LDA.l FollowerIndicator : BEQ +
LDA.l FollowerDropped : CMP.b #$80 : PLA : BCC .return : PHA
+ LDA.l ProgressIndicator : CMP.b #$02 : PLA : BCC .escape_check
PHA
JSL DetermineFollowerSpawn_check_resolved
PLA
BCC .issue_follower
BRA .return
.escape_check
CMP.b #$01 : BNE .return
PHA : LDA.l ProgressFlags : AND.b #$04 : CMP.b #$04 : PLA : BCS .return
.issue_follower
STA.l FollowerIndicator
LDA.b #$00 : STA.l FollowerDropped
.return
RTL
MaybeSetZeldaCheckpoint:
AND.w #$7FFF : TAX ; what we wrote over
SEP #$20
LDA.l ProgressFlags : AND.b #$04 : BNE .return ; zelda rescued
LDA.l StartingEntrance : CMP.b #$02 : BEQ .return ; cell checkpoint set
CMP.b #$04 : BEQ .return ; throne room checkpoint set
LDA.l FollowerIndicator : CMP.b #$01 : BNE .return ; zelda following
LDA.b RoomIndex : CMP.b #$80 : BNE + ;zelda cell
LDA.l Follower_Zelda : CMP.b #$01 : BNE .return
BRA .set_checkpoint
+ CMP.b #$45 : BNE .return ; maiden cell
CPX.w #$0964 : BNE .return ; top big lock
LDA.l Follower_Maiden : CMP.b #$01 : BNE .return
.set_checkpoint
LDA.b #$02 : STA.l StartingEntrance
PHX
SEP #$10
JSL SaveDeathCount
JSL Dungeon_SaveRoomQuadrantData
REP #$10
PLX
.return
REP #$30
RTL
FollowerGfxRedraw:
PHP : SEP #$30
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .return
PHY
LDY.b #$0F
.next
LDA.w SpriteAITable,Y : BEQ ++
LDA.w SpriteTypeTable,Y : CMP.b #$76 : BEQ + ; zelda
CMP.b #$AD : BEQ + ; old man
CMP.b #$B7 : BEQ + ; maiden
CMP.b #$1A : BEQ + ; frog
CMP.b #$39 : BEQ + ; locksmith
CMP.b #$B6 : BEQ + ; kiki
CMP.b #$B4 : BEQ + ; purple chest
CMP.b #$B5 : BNE ++ ; big bomb
LDA.w SpriteJumpIndex,Y : CMP.b #$02 : BEQ +
BRA ++
+ LDA.b #$01 : STA.w SprRedrawFlag,Y
++ DEY : BPL .next
PLY
.return
PLP
RTL
; A = 2 byte VRAM position in OAM2 for head/body
; Scrap06/07/08 = address to OAM group
; Returns with carry flag set if draw occurred
TransferAndDrawFollowerGfx:
PHA
LDA.w SpriteTimerE, X : AND.w #$0008 : BNE .skip_draw ; skip drawing every other frame
LDA.b 1,S
JSR TransferFollowerSpriteGfx ; returns with SEP #$20
LDA.w SpriteTypeTable, X : CMP.b #$39 : BNE +
; locksmith location flicker if quest completed but purple chest remains
LDA.w SpriteAux, X : BNE .continue
JSL DetermineFollowerSpawn : BCS .flicker
+ BRA .continue
.flicker
LDA.w SpriteTimerE, X : NOP #2 : BNE .continue
LDA.b #$0C : STA.w SpriteTimerE, X
.continue
PLA : XBA : PLA : XBA
JSL SpriteDraw_Follower
SEC
RTL
.skip_draw
PLA
SEP #$20
CLC
RTL
; A = 2 byte VRAM position in OAM2 for head/body
TransferFollowerSpriteGfx_skip_transfer:
PLA : PLA
RTS
TransferFollowerSpriteGfx:
PHA : SEP #$20
LDA.w SprRedrawFlag, X : BEQ .skip_transfer
.redraw
STZ.w SprRedrawFlag, X
JSL DetermineFollower
CMP.b #$01 : BNE +
PLA : XBA : LDA.b #$83 ; zelda body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$82 ; zelda head
JMP QueueFollowerSpriteGfx
+ CMP.b #$04 : BNE +
PLA : XBA : LDA.b #$84 ; old man body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$85 ; old man head
JMP QueueFollowerSpriteGfx
+ CMP.b #$06 : BNE +
PLA : XBA : LDA.b #$81 ; maiden body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$80 ; maiden head
JMP QueueFollowerSpriteGfx
+ CMP.b #$07 : BNE +
PLA : XBA : PLA : LDA.b #$11 ; frog
JMP QueueFollowerSpriteGfx
+ CMP.b #$08 : BNE +
PLA : XBA : PLA : LDA.b #$16 ; smith
JMP QueueFollowerSpriteGfx
+ CMP.b #$09 : BNE +
PLA : XBA : LDA.b #$87 ; locksmith body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$86 ; locksmith head
JMP QueueFollowerSpriteGfx
+ CMP.b #$0A : BNE +
PLA : XBA : LDA.b #$13 ; kiki body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$12 ; kiki head
JMP QueueFollowerSpriteGfx
+ CMP.b #$0C : BNE +
PLA : XBA : PLA : LDA.b #$14 ; purple chest
JMP QueueFollowerSpriteGfx
+ PLA : XBA : PLA : LDA.b #$15 ; super bomb
JMP QueueFollowerSpriteGfx
; A = 2 bytes, dest/src
QueueFollowerSpriteGfx:
PHX : REP #$20
PHA
AND.w #$00FF : CMP.w #$00FF : BEQ +
ASL #6 : EOR.w #$8000 : BRA .write_src
+ LDA.w #$0020 ; blank tile
.write_src
LDX.w ItemStackPtr : STA.l ItemGFXStack,X
PLA : XBA
AND.w #$00FF : ASL #4 : EOR.w #$5000
STA.l ItemTargetStack,X
TXA : INC #2 : STA.w ItemStackPtr
SEP #$20 : PLX
RTS
; A = 2 byte VRAM position in OAM2 for head/body
; Scrap06/07/08 = address to OAM group
; Scrap09/0A = address to palette data
SpriteDraw_Follower:
PHB : LDY.b #$7E : PHY : PLB
REP #$20
PHA
LDY.b #$0E
- LDA.b [Scrap06], Y : STA.w SpriteDynamicOAM, Y
DEY #2 : BPL -
LDA.b Scrap09 : STA.b Scrap06
PLA
SEP #$20
STA.w SpriteDynamicOAM+$0C : XBA : STA.w SpriteDynamicOAM+$04
JSL DetermineFollower : PHA
PHX
TAX : DEX
LDA.b Scrap06 : ORA.b Scrap07 : BEQ +
TXY
LDA.b [Scrap06], Y
BRA .set_palette
+
LDA.l .palette_data, X
.set_palette
STA.w SpriteDynamicOAM+$05 : STA.w SpriteDynamicOAM+$0D
PLX
REP #$20
LDA.w #$0002 : STA.b Scrap06
LDA.w #SpriteDynamicOAM : STA.b Scrap08
SEP #$20
PLA : CMP.b #$07 : BCC + : CMP.b #$09 : BEQ + : CMP.b #$0A : BEQ +
; only draw body
PHA
LDA.b #$01 : STA.b Scrap06
LDA.b #SpriteDynamicOAM+8 : STA.b Scrap08
PLA
+
; follower specific adjustments
CMP.b #$04 : BNE +
LDA.w SpriteDynamicOAM+$0A : SEC : SBC.b #8 : STA.w SpriteDynamicOAM+$02 ; old man coords
+
CMP.b #$0A : BNE +
LDA.w SpriteDynamicOAM+$0A : SEC : SBC.b #6 : STA.w SpriteDynamicOAM+$02 ; kiki coords
LDA.w SpriteTypeTable, X : CMP.b #$1A : BEQ ++ : CMP.b #$B4 : BCS ++ : BRA .draw
++ LDA.w SpriteDynamicOAM+$05 : ORA.b #$40
STA.w SpriteDynamicOAM+$05 : STA.w SpriteDynamicOAM+$0D ; kiki horiz flip
+
.draw
JSL Sprite_DrawMultiple_player_deferred
PLB
RTL
.palette_data
; 01 04 06 07 08 09 0A 0C 0D
db $00, $00, $00, $00, $00, $06, $00, $00, $06, $00, $00, $00, $00
DetermineFollower:
LDA.w SpriteAux, X : BEQ .skip_stored : RTL ; stored follower
.skip_stored
+ LDA.w $0E20,X : CMP.b #$1A : BNE +
LDA.l Follower_Frog : BRA .finalize
+ CMP.b #$39 : BNE +
LDA.l Follower_Locksmith : BRA .finalize
+ CMP.b #$AD : BNE +
LDA.l Follower_OldMan : BRA .finalize
+ CMP.b #$B6 : BNE +
LDA.l Follower_Kiki : BRA .finalize
+ CMP.b #$B7 : BNE +
LDA.l Follower_Maiden : BRA .finalize
+ CMP.b #$76 : BNE +
LDA.l Follower_Zelda : BRA .finalize
+ CMP.b #$B4 : BNE +
LDA.l Follower_PurpleChest : BRA .finalize
+ LDA.l Follower_SuperBomb
.finalize
PHA
CMP.b #$07 : BNE +
LDA.l CurrentWorld : BNE +
PLA : LDA.b #$08 : RTL
+
PLA
RTL
SetAndLoadFollower:
LDA.l FollowerIndicator
.skip_current
PHA
LDA.b #$00 : STA.l FollowerDropped
JSL DetermineFollower : STA.l FollowerIndicator
CMP.b #$01 : BNE +
JSL DetermineFollower_skip_stored : CMP.b #$01 : BNE +
LDA.b #$02 : STA.l StartingEntrance
JSL SaveDeathCount
PHX
JSL Dungeon_SaveRoomQuadrantData
PLX
+ CMP.b #$09 : BNE +
LDA.b #$40 : STA.w $02CD : STZ.w $02CE ; locksmith timed message
+
PHX
JSL Tagalong_LoadGfx
PLX
PLA : BNE +
JSL Follower_Initialize
JML Sprite_BecomeFollower
+
RTL
StoreAndLoadFollower:
LDA.l FollowerDropped : BNE .no_storage
LDA.l FollowerIndicator : BEQ .no_storage
PHA
JSL SetAndLoadFollower_skip_current
PLA : STA.w SpriteAux, X
LDA.b #$13 : JSL Sound_SetSfx3PanLong
LDA.b #$01 : STA.w SprRedrawFlag, X
STZ.w SpriteActivity, X
LDA.b #$90 : STA.w SpriteTimerE, X
SEC : RTL
.no_storage
JSL SetAndLoadFollower_skip_current
CLC : RTL
; return SEC if destination resolved
DetermineFollowerSpawn_locksmith_check:
; locksmith location needs to spawn if purple chest reward not acquired
LDA.l FollowerIndicator : CMP.b #$0C : BEQ .always_spawn
JSL DetermineFollower_skip_stored : CMP.l FollowerIndicator : BEQ .matched_following
LDA.l NpcFlagsVanilla : AND.b #$10 : BEQ .always_spawn
BRA DetermineFollowerSpawn
.always_spawn
CLC : RTL
.matched_following
SEC : RTL
DetermineFollowerSpawn_include_stored:
JSL DetermineFollower
BRA DetermineFollowerSpawn_byof
DetermineFollowerSpawn:
JSL DetermineFollower_skip_stored
.byof
CMP.l FollowerIndicator : BEQ .matched_following
.skip_match_check
PHA
; despawn if pre-requisite not met
LDA.w SpriteTypeTable, X : CMP.b #$B4 : BNE +
LDA.l NpcFlagsVanilla : AND.b #$20 : EOR.b #$20 : CMP.b #$20
BRA .prereq_check
+ CMP.b #$B5 : BNE +
LDA.l CrystalsField : AND.b #$05 : CMP.b #$05
LDA.b #$FF : ADC.b #$00 : ROR ; flip carry flag
.prereq_check
PLA : BCC .check_resolved
RTL
+
PLA
.check_resolved
CMP.b #$01 : BNE +
LDA.l ProgressFlags : AND.b #$04 : CMP.b #$04 : RTL
+ CMP.b #$04 : BNE +
JML ItemCheck_OldMan
+ CMP.b #$06 : BNE +
LDA.l RoomDataWRAM[$AC].high : AND.b #$08 : CMP.b #$08 : BCS ++
LDA.l EnemizerFlags_close_blind_door : CMP.b #$01
++
RTL
+ CMP.b #$09 : BCS + ; if frog or smith
LDA.l NpcFlagsVanilla : AND.b #$20 : CMP.b #$20 : RTL
+ CMP.b #$0A : BNE +
LDA.l OverworldEventDataWRAM+$5E : AND.b #$20 : CMP.b #$20 : RTL
+ CMP.b #$0C : BNE +
LDA.l NpcFlagsVanilla : AND.b #$10 : CMP.b #$10 : RTL
+
.always_spawn
CLC : RTL ; big bomb and locksmith have no completion condition in code
.matched_following
SEC : RTL
Follower_CheckMessageCollision:
PHA
LDA.w SpriteTimerE, X : BNE .skip_collision_check
PLA
JML Sprite_ShowMessageFromPlayerContact ; what we wrote over
.skip_collision_check
PLA
CLC : RTL
Follower_CheckTileCollision:
LDA.w SpriteTimerE, X : BNE .skip_collision_check
JML Sprite_CheckTileCollisionLong ; what we wrote over
.skip_collision_check
RTL
Follower_CheckCollision:
LDA.w SpriteTimerE, X : BNE .skip_collision_check
JML Sprite_CheckDamageToPlayerSameLayerLong ; what we wrote over
.skip_collision_check
CLC : RTL
SpritePrep_ZeldaFollower:
LDA.b RoomIndex : CMP.b #$12 : BEQ .no_follower_shuffle_sanc
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_follower_shuffle
JSL DetermineFollowerSpawn : BCC + : RTL : +
LDA.b #$01 : STA.w SprRedrawFlag, X
PLA : PLA : PEA.w $EC4B-1 ; return to spawn
RTL
.no_follower_shuffle
LDA.l FollowerIndicator : CMP.b #$01
RTL
.no_follower_shuffle_sanc
LDA.l FollowerIndicator : CMP.b #$02
RTL
Zelda_WaitingInCell:
JSL Follower_CheckCollision ; what we wrote over, kinda
BCC .return
PHP
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE +
INC.w SpriteActivity, X
PLP
PLA : PLA : PEA.w $ECF9-1 : RTL ; skip sprite movement
+
PLP
.return
RTL
Zelda_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
PLA : PLA
JSL StoreAndLoadFollower : BCC +
PEA.w $ED68-1 : RTL ; jump to avoid sprite despawn
+
PEA.w $ED60-1 ; jump to despawn
RTL
.vanilla
LDA.b #$02 : STA.l StartingEntrance ; what we wrote over
RTL
SpritePrep_BlindMaiden:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn : BCC +
LDA.b #$01 : RTL
+
LDA.b #$01 : STA.w SprRedrawFlag, X
INC.w SpriteAncillaInteract, X
STZ.w FollowerNoDraw
PLA : PLA : PEA.w $89C8-1 ; return to spawn
RTL
.vanilla
LDA.l RoomDataWRAM[$AC].high : AND.b #$08 ; what we wrote over
RTL
; Prevent followers from causing blind/maiden to despawn:
; Door rando: let zelda despawn the maiden.
BlindZeldaDespawnFix:
LDA.l FollowerIndicator ; what we wrote over
CMP.b #06 : BEQ +
LDA.w SpritePosYLow,X : BEQ +
LDA.b #$00 : RTL ; don't despawn follower if maiden isn't "present"
+
LDA.b #$01 : RTL
SpriteDraw_ZeldaMaiden:
LDA.b RoomIndex : CMP.b #$12 : BEQ .vanilla
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
LDA.w SpriteTypeTable, X : CMP.b #$76 : BNE +
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #0000 : STA.b Scrap09
LDA.l Follower_Zelda_vram
BRA .transfer
+
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #.palette_data_maiden : STA.b Scrap09
LDA.l Follower_Maiden_vram
.transfer
JML TransferAndDrawFollowerGfx
.skip_draw
RTL
.vanilla:
JML SpriteDraw_Maiden
.oam_group:
dw 1, -7 : db $20, $00, $00, $02
dw 1, 3 : db $22, $00, $00, $02
.palette_data_maiden
; 01 04 06 07 08 09 0A 0C 0D
db $02, $00, $00, $02, $00, $04, $02, $02, $04, $02, $00, $02, $02
BlindMaiden_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
PLA : PLA
JSL StoreAndLoadFollower : BCS .return
STZ.w SpriteAITable, X
.return
PEA.w $E8EA-1 ; jump ahead on return
RTL
.vanilla
STZ.w SpriteAITable, X : LDA.b #$06 ; what we wrote over
RTL
SpritePrep_OldManFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_follower_shuffle
PLA : PLA
JSL DetermineFollowerSpawn : BCC +
PEA.w $E928-1 ; return to despawn
RTL
+
LDA.b #$01 : STA.w SprRedrawFlag, X
PEA.w $E927-1 ; return to spawn
RTL
.no_follower_shuffle
LDA.l FollowerIndicator : CMP.b #$04
RTL
SpriteDraw_OldManFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.w SpriteJumpIndex, X : CMP.b #$01 : BEQ .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #0000 : STA.b Scrap09
PLA : PEA.w $FF45-1 ; skip vanilla draw
LDA.l Follower_OldMan_vram
JML TransferAndDrawFollowerGfx
.vanilla
LDA.b #$02 : STA.b Scrap06 ; what we wrote over
RTL
.oam_group
dw 0, 0 : db $AC, $00, $00, $02
dw 0, 8 : db $AE, $00, $00, $02
OldMan_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BCC .set_follower_and_despawn
PLA : PLA
JSL StoreAndLoadFollower : BCC +
PEA.w $E9DF-1 : RTL ; jump to avoid sprite despawn
+
PEA.w $E9DC-1 ; jump to despawn
RTL
.set_follower_and_despawn
JSL SetAndLoadFollower
PLA : PLA : PEA.w $E9D6-1
SpritePrep_SmithyFrog:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_follower_shuffle
JSL DetermineFollowerSpawn : BCC +
LDA.b #$01 ; return to despawn
RTL
+
LDA.b #$01 : STA.w SprRedrawFlag, X
DEC ; return to spawn
RTL
.no_follower_shuffle
LDA.l FollowerIndicator : BNE + ; what we wrote over
LDA.l NpcFlagsVanilla : AND.b #$20 ; what we wrote over
+ RTL
SpriteDraw_FrogFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #0000 : STA.b Scrap09
PLA : PEA.w $DCD6-1
LDA.l Follower_Frog_vram
JML TransferAndDrawFollowerGfx
.vanilla
LDA.b #$01 : STA.b Scrap06 ; what we wrote over
RTL
.oam_group:
dw 1, -8 : db $FF, $00, $00, $02
dw 1, 0 : db $C8, $00, $00, $02
Frog_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BCC .set_follower_and_despawn
PLA : PLA
JSL StoreAndLoadFollower : BCC +
PEA.w $B2C7-1 : RTL ; jump to avoid sprite despawn
+
PEA.w $B2C4-1 ; jump to despawn
RTL
.set_follower_and_despawn
JSL SetAndLoadFollower
PLA : PLA : PEA.w $B2C4-1 ; jump to despawn
RTL
SpritePrep_PurpleChest:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn : BCC +
LDA.b #$00 ; return to despawn
RTL
+
PLA : PLA : PEA.w $8A69-1 ; return to spawn
LDA.b #$01 : STA.w SprRedrawFlag, X
RTL
.vanilla
LDA.l FollowerIndicator : CMP.b #$0C
RTL
SpriteDraw_PurpleChest:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #0000 : STA.b Scrap09
LDA.l Follower_PurpleChest_vram
JML TransferAndDrawFollowerGfx
.vanilla
JML Sprite_PrepAndDrawSingleLargeLong ; what we wrote over
.oam_group:
dw 0, -8 : db $C8, $00, $00, $02
dw 0, 0 : db $EE, $00, $00, $02
PurpleChest_FollowCheck:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #$00
RTL
.vanilla
LDA.l FollowerIndicator ; what we wrote over
RTL
PurpleChest_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
PLA : PLA
JSL StoreAndLoadFollower : BCS .return
STZ.w SpriteAITable, X
.return
PEA.w $E10A-1 ; jump ahead on return
RTL
.vanilla
STZ.w SpriteAITable, X : LDA.b #$0C ; what we wrote over
RTL
SpritePrep_SuperBomb:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn : BCC +
LDA.b #$00 ; despawn on exit
RTL
+
LDA.b #$05
RTL
.vanilla
LDA.l CrystalsField ; what we wrote over
RTL
SpriteDraw_SuperBomb:
LDA.w SpriteJumpIndex, X : CMP.b #$02 : BNE .vanilla
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #.palette_data : STA.b Scrap09
PLA : PEA.w $E2E2-1 ; skip vanilla draw
LDA.l Follower_SuperBomb_vram
JML TransferAndDrawFollowerGfx
.vanilla
LDA.b #$01 : STA.b Scrap06 ; what we wrote over
RTL
.oam_group:
dw 0, -8 : db $AE, $08, $00, $02
dw 0, 0 : db $4E, $08, $00, $02
.palette_data
; 01 04 06 07 08 09 0A 0C 0D
db $08, $00, $00, $08, $00, $06, $08, $08, $06, $08, $00, $08, $08
SuperBomb_FollowCheck:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.w SpriteTimerE, X : BNE .skip_follow
LDA.w SpriteAux, X : BEQ .vanilla
PLA : PLA : PEA.w $E1F1-1 ; jump to skip cost, no double charge
RTL
.skip_follow
PLA : PLA : PEA.w $E20C-1 ; jump to exit
RTL
.vanilla
LDA.b #$64 : LDY.b #$00 ; what we wrote over
RTL
SuperBomb_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
PLA : PLA
JSL StoreAndLoadFollower : BCC +
PEA.w $E20C-1 : RTL ; jump to exit
+
PEA.w $E201-1 ; jump to despawn
RTL
.vanilla
LDA.b #$0D : STA.l FollowerIndicator ; what we wrote over
RTL
pushpc
org $868A14
NOP #3 ; fix bomb shop spawn for dwarfless big bomb
LDA.b #$B5 : JSL Sprite_SpawnDynamically
BMI SuperBomb_BecomeFollower_exit
LDA.b #$01 : STA.w SprRedrawFlag, Y ; force redraw for super bomb gfx
pullpc
SpritePrep_Kiki:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn : BCC +
LDA.b #$20 : RTL ; despawn on exit
+
LDA.b #$00
RTL
.vanilla
LDX.b OverworldIndex : LDA.l OverworldEventDataWRAM,X ; what we wrote over
RTL
Kiki_OfferToFollow:
PHA
LDA.w SpriteTimerE, X : BNE .skip_collision_check
PLA
JML Sprite_ShowMessageUnconditional ; what we wrote over
.skip_collision_check
PLA
CLC : RTL
Kiki_FollowCheck:
JSL DetermineFollowerSpawn_include_stored : BCS .skip_follow
LDA.w SpriteTimerE, X
RTL
.skip_follow
LDA.b #$20
RTL
Kiki_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_follower_shuffle
PLA : PLA : PEA.w $E4C2-1 ; jump to exit
STZ.w FollowerNoDraw
JML StoreAndLoadFollower
.no_follower_shuffle
LDA.b #$00 : STA.l FollowerDropped ; defuse bomb
LDA.b #$0A : STA.l FollowerIndicator
RTL
Kiki_FixTeleportOnExit:
REP #$30
LDA.b LinkPosX : STA.w LinkPosXCache
LDA.b LinkPosY : STA.w LinkPosYCache
SEP #$30
LDA.b #$19 : LDY.b #$01 ; what we wrote over
RTL
; on return it checks BEQ and if non-zero, kiki get spook
Kiki_DontScareTheMonke:
LDA.b LinkJumping : BEQ .return
CMP.b #$02 : BEQ .no_spook ; needed for quake usage
LDA.w NoDamage : BNE .no_spook
LDA.w LinkThud : BNE .no_spook
.spook
LDA.b #$01 : RTL
.no_spook
LDA.b #$00
.return
RTL
SpritePrep_Locksmith:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn_locksmith_check : BCS +
LDA.b #$01 : STA.w SprRedrawFlag, X
+
LDA.l FollowerIndicator
RTL
.vanilla
LDA.l FollowerIndicator : CMP.b #$09 ; what we wrote over
BEQ +
CLC : RTL
+
SEC : RTL
SpriteDraw_LocksmithFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #.palette_data : STA.b Scrap09
PLA : PEA.w $DCD6-1 ; skip draw on exit
LDA.l Follower_Locksmith_vram
JML TransferAndDrawFollowerGfx
.vanilla
LDA.b #$02 : STA.b Scrap06 ; what we wrote over
RTL
.oam_group:
dw 0, -8 : db $EA, $00, $00, $02
dw 0, 0 : db $EC, $00, $00, $02
.palette_data
; 01 04 06 07 08 09 0A 0C 0D
db $00, $00, $00, $0E, $00, $00, $0E, $0E, $00, $0E, $00, $0E, $0E
Locksmith_Chillin_PostMessage:
LDA.w SpriteAux, X : BEQ +
; when a follower is stored, merely walk near them
LDA.w SpritePosXLow, X : PHA
JSL Follower_CheckCollision : BCC .return
BRA .continue
+
LDA.w SpritePosXLow, X : PHA
SEC : SBC.b #$10 : STA.w SpritePosXLow, X
LDA.b #$01 : STA.w SpriteVelocityX, X
JSL Sprite_Get16BitCoords_long
JSL Follower_CheckTileCollision : BNE .return
.continue
INC.w SpriteActivity, X ; award follower
LDA.l FollowerIndicator : CMP.b #$0C : BEQ .purple_chest_prize
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ .return
LDA.l FollowerIndicator : CMP.b #$00 : BEQ .return
LDA.b #$05 : STA.w SpriteActivity, X ; forever do nothing
BRA .return
.purple_chest_prize
INC.w SpriteActivity, X ; prep for purple chest prize
.return
PLA : STA.w SpritePosXLow, X
JML $86BD08 ; jump back to immediately RTS
Locksmith_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
STZ.w FollowerNoDraw
PLA : PLA
JSL StoreAndLoadFollower : BCS +
LDA.l FollowerIndicator : CMP.b #$0C : BEQ +
PEA.w $BD24-1 : RTL ; jump to despawn
+
PEA.w $BD27-1 ; jump to exit
RTL
.vanilla
LDA.b #$09 : STA.l FollowerIndicator
RTL
Locksmith_RespondToAnswer_PostItem:
STA.l FollowerIndicator ; what we wrote over
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_despawn
LDA.w SpriteAux, X : CMP.b #$0C : BEQ .despawn
CMP.b #$00 : BNE .no_despawn
LDA.l Follower_Locksmith : CMP.b #$0C : BEQ .despawn
JSL DetermineFollowerSpawn_include_stored : BCC .no_despawn
.despawn
STZ.w SpriteAITable, X
.no_despawn
RTL

View File

@@ -2,10 +2,10 @@
; Frame Hook
;--------------------------------------------------------------------------------
FrameHookAction:
JSL Module_MainRouting
JSL $8080B5 ; Module_MainRouting
JSL CheckMusicLoadRequest
PHP : REP #$30 : PHA
SEP #$20
SEP #$20
LDA.l StatsLocked : BNE ++
REP #$20 ; set 16-bit accumulator
LDA.l LoopFrames : INC : STA.l LoopFrames : BNE +
@@ -18,58 +18,40 @@ FrameHookAction:
REP #$30 : PLA : PLP
RTL
!NMI_MW = "$7F5047"
;--------------------------------------------------------------------------------
NMIHookAction:
PHA : PHX : PHY : PHD ; thing we wrote over, push stuff
LDA.l !NMI_MW : BEQ ++
PHP
SEP #$30
LDA.b #$00 : STA.l !NMI_MW
; Multiworld text
LDA.l !NMI_MW+1 : BEQ +
LDA.b #$00 : STA.l !NMI_MW+1
JSL WriteText
+
PLP
++
LDA.l StatsLocked : AND.w #$00FF : BNE +
LDA.l NMIFrames : INC : STA.l NMIFrames : BNE +
LDA.l NMIFrames+2 : INC : STA.l NMIFrames+2
+
JML NMIHookReturn
PHA : PHX : PHY : PHD ; thing we wrote over, push stuff
LDA.l StatsLocked : AND.w #$00FF : BNE +
LDA.l NMIFrames : INC : STA.l NMIFrames : BNE +
LDA.l NMIFrames+2 : INC : STA.l NMIFrames+2
+
JML.l NMIHookReturn
;--------------------------------------------------------------------------------
PostNMIHookAction:
LDA.w NMIAux : BEQ +
PHK : PEA.w .return-1 ; push stack for RTL return
PHK : PEA .return-1 ; push stack for RTL return
JMP.w [NMIAux]
.return
STZ.w NMIAux ; zero bank byte of NMI hook pointer
+
JSR TransferItemGFX
JSR.w TransferItemGFX
LDA.b INIDISPQ : STA.w INIDISP ; thing we wrote over, turn screen back on
JML PostNMIHookReturn
JML.l PostNMIHookReturn
;--------------------------------------------------------------------------------
TransferItemGFX:
; Only used for shops now but could be used for anything. We should look at how door rando does this
; and try to unify one approach.
REP #$30
LDX.w ItemStackPtr : BEQ .done
TXA : BIT.w #$0040 : BNE .fail ; Crash if we have more than 16 queued (should never happen.)
TXA : BIT #$0040 : BNE .fail ; Crash if we have more than 16 queued (should never happen.)
DEX #2
-
LDA.l ItemGFXStack,X : STA.w ItemGFXPtr
LDA.l ItemTargetStack,X : STA.w ItemGFXTarget
PHX
JSL TransferItemToVRAM
JSL.l TransferItemToVRAM
REP #$10
PLX
DEX #2

View File

@@ -11,7 +11,7 @@ GetAgahnimPalette:
RTL
;--------------------------------------------------------------------------------
GetAgahnimDeath:
STA.w SpriteAncillaInteract, X ; thing we wrote over
STA.w $0BA0, X ; thing we wrote over
LDA.b RoomIndex ; get room id
CMP.b #13 : BNE + ; Agahnim 2 room
LDA.l Bugfix_SetWorldOnAgahnimDeath : BEQ ++
@@ -51,10 +51,10 @@ GetAgahnimSlot:
LDA.b RoomIndex ; get room id
CMP.b #13 : BNE + ; Agahnim 2 room
LDA.b #$01 ; Use Agahnim 2
JML GetAgahnimSlotReturn
JML.l GetAgahnimSlotReturn
+ ; Elsewhere
LDA.b #$00 ; Use Agahnim 1
JML GetAgahnimSlotReturn
JML.l GetAgahnimSlotReturn
;--------------------------------------------------------------------------------
GetAgahnimLightning:
INC.w SpriteAux, X ; thing we wrote over

Some files were not shown because too many files have changed in this diff Show More