diff --git a/.gitignore b/.gitignore
index 193b53a..23e41f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,5 @@ SDL2.dll
/work
smw_assets.dat
__pycache__
+/enhanced/
+*.sfc
\ No newline at end of file
diff --git a/assets/compile_resources.py b/assets/compile_resources.py
index ccb981a..3e51cd1 100644
--- a/assets/compile_resources.py
+++ b/assets/compile_resources.py
@@ -1,6 +1,6 @@
import sys, array, hashlib, struct, argparse, os
import util
-from util import cache
+from util import cache, get_byte, get_word, get_24, get_bytes, get_words
def flatten(xss):
return [x for xs in xss for x in xs]
@@ -30,6 +30,14 @@ def add_asset_packed(name, data):
assert name not in assets
assets[name] = ('packed', pack_arrays(data))
+def add_asset_blob(name, data):
+ assert name not in assets
+ assets[name] = ('blob', pack_blob(data))
+
+def pack_24(v):
+ assert v >= 0 and v < (1 << 24)
+ return struct.pack('I', v)[:3]
+
# Pack arrays and determine automatically the index size
def pack_arrays(arr):
if len(arr) == 0:
@@ -66,6 +74,24 @@ def pack_arrays(arr):
r.append(struct.pack('H', flags))
return b''.join(r)
+def pack_blob(ranges):
+ out = []
+ for a, b in sorted(ranges):
+ if len(out) and a <= out[-1][1]:
+ # continue existing range
+ if b > out[-1][1]:
+ out[-1] = (out[-1][0], b)
+ else:
+ out.append((a, b))
+ off = 2 + len(out) * 6
+ a_arr, b_arr, r_arr = [], [], []
+ for a, b in out:
+ a_arr.append(pack_24(a))
+ b_arr.append(pack_24(off))
+ r_arr.append(util.get_bytes(a, b - a))
+ off += b - a
+ return struct.pack('H', len(out)) + b''.join(a_arr) + b''.join(b_arr) + b''.join(r_arr)
+
def get_stripe_len(ea):
ea_org = ea
while True:
@@ -81,6 +107,18 @@ def get_stripe_len(ea):
else:
ll = ((p2 << 8 | p3) & 0x3fff) + 1
ea += ll
+
+def get_rats_size(p):
+ if p == 0: return 0
+ p -= 8
+ if (p & 0x8000) == 0:
+ p -= 0x8000
+ assert util.get_bytes(p, 4) == b'STAR', hex(p)
+ return get_word(p + 4) + 1
+
+def get_rats_bytes(p):
+ return get_bytes(p, get_rats_size(p))
+
@cache
def unpack_rle(ea):
ea_org = ea
@@ -97,10 +135,34 @@ def unpack_rle(ea):
r.append(y)
return bytes(r), ea + 2 - ea_org
+def unpack_rle_of_size(ea, size):
+ ea_org = ea
+ r = bytearray()
+ while len(r) < size:
+ x = util.get_byte(ea); ea += 1
+ if x & 0x80:
+ y = util.get_byte(ea); ea += 1
+ for i in range((x & 0x7f) + 1):
+ r.append(y)
+ else:
+ for i in range((x & 0x7f) + 1):
+ y = util.get_byte(ea); ea += 1
+ r.append(y)
+ return bytes(r), ea - ea_org
+
+
@cache
-def calc_level_len(ea):
+def calc_level_len(ea, dbg = False):
+ if dbg: print('Now decoding level at 0x%x' % ea)
ea_org = ea
ea += 5
+
+ kObjNames = {
+ 60 : 'StoneBlock',
+ 13 : 'CementBlock',
+ 0x22: 'LmMap16',
+ }
+
while True:
b0 = util.get_byte(ea); ea += 1
if b0 == 0xff:
@@ -108,29 +170,97 @@ def calc_level_len(ea):
b1 = util.get_byte(ea); ea += 1
b2 = util.get_byte(ea); ea += 1
- blocks_object_number = (b1 >> 4) | ((b0 & 0x60) >> 1)
+ obj_id = (b1 >> 4) | ((b0 & 0x60) >> 1)
blocks_size_or_type = b2
- if blocks_object_number == 0 and blocks_size_or_type == 0:
+ if dbg:
+ print(' %.2X %.2X %.2X: 0x%x, 0x%x, %d: %s' % (b0, b1, b2, ea-3, obj_id, blocks_size_or_type, kObjNames.get(obj_id)))
+
+ if obj_id == 0 and blocks_size_or_type == 0:
ea += 1
+ elif obj_id in (0x22, 0x23): # lunar magic
+ ea += 1
+ elif obj_id in (0x24, 0x25): # lunar deprecated
+ ea += 0
+ elif obj_id in (0x27, ):
+ ea += 2
return ea - ea_org
+LUNAR_MAGIC = get_bytes(0xFF0A0, 5) == b'Lunar'
+
+def extra_lunar_magic_text():
+ return '\n\nDo the following steps:\n1) Use Lunar Magic 3.33.\n' + \
+ '2) Open up a level, modify something, save it.\n' + \
+ '3) Open up the 16x16 tile map editor, edit something, save it.\n' + \
+ '4) Open up the Exanim editor for some level. Edit something, save.\n'
+
+
+if LUNAR_MAGIC:
+ s = get_bytes(0xFF0A0, 24).decode('utf8')
+ print('Detected %s' % s, file = sys.stderr)
+ if s != 'Lunar Magic Version 3.33':
+ raise Exception('Invalid Lunar Magic version. Expected 3.33, found "%s"\n' % s + extra_lunar_magic_text())
+
+ if get_byte(0x6F540) != 0xc9:
+ raise Exception('The map16 file format is incorrect. ' + extra_lunar_magic_text())
+
+
+def get_comp_data(ea):
+ data, comp_len = util.decomp(ea, util.get_byte, return_length = True)
+ return util.get_bytes(ea, comp_len)
+
+def decomp_data(ea):
+ data, comp_len = util.decomp(ea, util.get_byte, return_length = True)
+ return data
+
+
+kLmFeature_LmEnabled = 1 << 0
+kLmFeature_Exanim = 1 << 1
+kLmFeature_SkipOverworldDecompress = 1 << 2
+kLmFeature_OverworldTiles4bpp = 1 << 3
+kLmFeature_Copy512colors = 1 << 4
+kLmFeature_WeirdPalette = 1 << 5
+kLmFeature_SkipLoadPaletteHook = 1 << 6
+kLmFeature_GfxUpload = 1 << 7
+kLmFeature_LoadLevel = 1 << 8
+kLmFeature_4bppgfx = 1 << 9
+kLmFeature_CustomTitleScreenDemo = 1 << 10
+kLmFeature_CustomDisplayMessage = 1 << 11
+kLmFeature_DontSetYposForIntroMarch = 1 << 12
+kLmFeature_OwPalette = 1 << 13
+kLmFeature_LevelNamesPatch = 1 << 14
+kLmFeature_DestroyTileAnims = 1 << 15
+kLmFeature_EventStuff = 1 << 16
+kLmFeature_MusicRegTweak = 1 << 17
+kLmFeature_TideWaterTweak = 1 << 18
+kLmFeature_EnemyCollTweak = 1 << 19
+kLmFeature_Ow4bppGfx = 1 << 20
+
+kHack_Walljump = 1 << 0
+
+class LmFeatures:
+ flags = 0
+ kLmLvlInfo_addr = 0
+ kLmLvlInfo_addr_other = 0
+ hacks = 0
+
+ def serialize(self):
+ return struct.pack('IIII', self.flags, self.kLmLvlInfo_addr, self.kLmLvlInfo_addr_other, self.hacks)
def print_all(args):
+ lm_feat = LmFeatures()
r = []
lo, hi, bank = util.get_bytes(0xB992, 50), util.get_bytes(0xB9c4, 50), util.get_bytes(0xB9f6, 50)
for i in range(50):
p = bank[i] << 16 | hi[i] << 8 | lo[i]
- data, comp_len = util.decomp(p, util.get_byte, return_length = True)
- #print('%d: %d: %d' % (i, comp_len, len(data)))
- r.append(data)
+ r.append(get_comp_data(p))
add_asset_packed('kGraphicsPtrs', r)
- data, comp_len = util.decomp(0x88000, util.get_byte, return_length = True)
+ data, comp_len = util.decomp(0x80000 | util.get_word(0xB8D8), util.get_byte, return_length = True)
#print('%d: %d: %d' % (0x32, comp_len, len(data)))
add_asset_uint8('kGfx32', data)
- data, comp_len = util.decomp(0x8bfc0, util.get_byte, return_length = True)
+ data, comp_len = util.decomp(0x80000 | util.get_word(0xB88B), util.get_byte, return_length = True)
#print('%d: %d: %d' % (0x33, comp_len, len(data)))
add_asset_uint8('kGfx33', data)
@@ -150,8 +280,6 @@ def print_all(args):
r.append(util.get_bytes(p, pl))
add_asset_packed('kLayer3ImagePtrs', r)
- add_asset_uint8('kOverworldLayer2EventTilemap_Tiles', util.get_bytes(0xc8000, 3328))
-
add_asset_uint8('kSpcCreditsMusicBank', util.get_bytes(0x3e400, 6624))
add_asset_uint8('kSpcLevelMusicBank', util.get_bytes(0xEAED6, 16899))
add_asset_uint8('kSpcEngine', util.get_bytes(0xe8000, 6321) + b'\x00\x00')
@@ -160,14 +288,32 @@ def print_all(args):
add_asset_uint16('kMap16Data_OverworldLayer1', util.get_words(0x05d000, 772))
- add_asset_uint8('kkOverworldLayer2EventTilemap_Prop', util.get_bytes(0xc8d00, 1664))
-
add_asset_uint16('kMap16Data', util.get_words(0xd8000, (0xA100 - 0x8000) // 2))
add_asset_uint16('kMap16Data_Castle', util.get_words(0xdbc00, 712))
add_asset_uint16('kMap16Data_Rope', util.get_words(0xdc800, 712))
add_asset_uint16('kMap16Data_Underground', util.get_words(0xdd400, 712))
add_asset_uint16('kMap16Data_GhostHouse', util.get_words(0xde300, 712))
+ add_asset_uint16('kGlobalPalettes_Sky', util.get_words(0x00B0A0, 16))
+ add_asset_uint16('kGlobalPalettes_Background', util.get_words(0x00B0B0, 96))
+ add_asset_uint16('kGlobalPalettes_Layer3', util.get_words(0xB170, 16))
+ add_asset_uint16('kGlobalPalettes_Foreground', util.get_words(0x00B190, 96))
+ add_asset_uint16('kGlobalPalettes_Objects', util.get_words(0x00B250, 60))
+ add_asset_uint16('kPlayerPalettes', util.get_words(0x00B2C8, 40))
+ add_asset_uint16('kGlobalPalettes_Sprites', util.get_words(0x00B318, 84))
+ add_asset_uint16('kGlobalPalettes_YoshiBerry', util.get_words(0x00B674, 21))
+ add_asset_uint16('kGlobalPalettes_Flashing', util.get_words(0x00B60C, 16))
+
+ add_asset_uint16('kGlobalPalettes_OW_Objects', util.get_words(0xB528, 42))
+ add_asset_uint16('kGlobalPalettes_OW_Sprites', util.get_words(0xB57C, 56))
+ add_asset_uint16('kGlobalPalettes_B5EC', util.get_words(0xB5EC, 16))
+ add_asset_uint16('kGlobalPalettes_OW_Areas', util.get_words(0xB3D8, 168))
+ add_asset_uint16('kGlobalPalettes_OW_AreasPassed', util.get_words(0xB732, 168))
+ add_asset_uint16('kGlobalPalettes_Bowser', util.get_words(0xB69E, 56))
+ add_asset_uint16('kGlobalPalettes_Layer3Smasher', util.get_words(0xB66C, 4))
+ #add_asset_uint16('', util.get_words(0x, ))
+
+
add_asset_uint8('kGameMode1B_EndingCinema_Tilemaps', util.get_bytes(0xC95C7, 1873))
add_asset_uint16('kGameMode1B_EndingCinema_RowPointers', util.get_words(0xC9D18, 202))
@@ -175,10 +321,6 @@ def print_all(args):
add_asset_uint8('kLevelInfo_05F200', util.get_bytes(0x5f200, 0x200))
add_asset_uint8('kLevelInfo_05F400', util.get_bytes(0x5f400, 0x200))
add_asset_uint8('kLevelInfo_05F600', util.get_bytes(0x5f600, 0x200))
- add_asset_uint8('kLevelInfo_05F800', util.get_bytes(0x5f800, 0x200))
- add_asset_uint8('kLevelInfo_05FA00', util.get_bytes(0x5fa00, 0x200))
- add_asset_uint8('kLevelInfo_05FC00', util.get_bytes(0x5fc00, 0x200))
- add_asset_uint8('kLevelInfo_05FE00', util.get_bytes(0x5fe00, 0x200))
add_asset_uint8('kLoadLevel_DATA_05D608', util.get_bytes(0x5D608, 0x100))
@@ -188,21 +330,22 @@ def print_all(args):
add_asset_uint16('kLevelNames', util.get_words(0x4A0FC, 256))
- add_asset_uint8('kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap', util.get_bytes(0x4A533, 6904))
- add_asset_uint8('kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop', util.get_bytes(0x4C02B , 5709))
- add_asset_uint8('kLoadOverworldLayer1AndEvents_DATA_0CF7DF', util.get_bytes(0xCF7DF, 0x800))
-
add_asset_uint8('kLineGuideSpeedTableData', util.get_bytes(0x7F9DB, 536))
def add_packed_levels(name, addr, num, bank = None):
r = []
for i in range(num):
- if bank == None:
- ea = util.get_24(addr + i * 3)
- else:
- ea = util.get_word(addr + i * 2) | bank << 16
- ln = calc_level_len(ea)
- r.append(util.get_bytes(ea, ln))
+ try:
+ if bank == None:
+ ea = util.get_24(addr + i * 3)
+ else:
+ ea = util.get_word(addr + i * 2) | bank << 16
+ ln = calc_level_len(ea)
+ r.append(util.get_bytes(ea, ln))
+ except:
+ print('\n*** Crashed while decoding level 0x%x at 0x%x ***' % (i, ea), file = sys.stderr)
+ print('*** Try opening it in LM and then saving it ***', file = sys.stderr)
+
add_asset_packed(name, r)
add_packed_levels('kLevelData_Layer1', 0x5E000, 0x200)
@@ -224,7 +367,7 @@ def print_all(args):
else:
assert 0
- fl = 0
+ fl = util.get_byte(0xEF310 + i) if num == 0x200 and LUNAR_MAGIC else 0
if (ea & 0xff0000) == 0xff0000:
ea = (ea & 0xffff) | 0xc0000
fl = ((ea & 0xffff) >= 0xE8FE) << 4 | 2
@@ -243,7 +386,6 @@ def print_all(args):
add_packed_level_bg('kEntranceData_Layer2', 0x5d778, 6)
add_packed_level_bg('kChoclateIsland2_Layer2', 0x5DB2C, 9, mode = 'choc')
add_packed_level_bg('kRollCallData_Layer2', 0xCAD72, 13, mode = 'end')
-
add_packed_level_bg('kBufferCreditsBackgrounds_Layer2', 0xc93c1, 7, mode = 'choc')
def get_sprite_data_len(ea):
@@ -253,22 +395,34 @@ def print_all(args):
ea += 3
return ea + 1 - ea_org
+ def remove_trail_zero(s):
+ lx = len(s)
+ while lx and s[lx - 1] == 0:
+ lx -= 1
+ return s[:lx]
+
+ def remove_trail_empty(s):
+ lx = len(s)
+ while lx and len(s[lx - 1]) == 0:
+ lx -= 1
+ return s[:lx]
def add_sprites():
- r = []
-
+ spr_ranges = []
def touch(ea):
lx = get_sprite_data_len(ea)
- r.append(util.get_bytes(ea, lx))
+ spr_ranges.append((ea, ea + lx))
+ banks = util.get_bytes(0xef100, 512) if get_byte(0x05D8F5) == 0x22 else [7] * 512
for i in range(0x200):
- touch(util.get_word(0x5ec00 + i * 2) | 0x70000)
-
+ touch(util.get_word(0x5ec00 + i * 2) | (banks[i] << 16))
+
touch(0x7c3ee)
for i in range(9):
touch(util.get_word(0x5DB1A + i * 2) | 0x70000)
- add_asset_packed('kLoadLevelSpriteList', r)
+ add_asset_blob('kLvlSprBlob', spr_ranges)
+ add_asset_uint8('kLmSpritePtrBankByte', banks)
add_sprites()
@@ -276,16 +430,405 @@ def print_all(args):
add_asset_uint8('kFileSelectText_EraseFile', util.get_bytes(0x5B6FE, 203 + 204))
add_asset_uint8('kInitializeMode7TilemapsAndPalettes_TilemapData', util.get_bytes(0x3D9DE, 912))
- add_asset_uint16('kLayer2EventData_TileEntries', util.get_words(0x4DD8D, 742))
- add_asset_uint8('kUpdateLevelName_LevelNameStrings', util.get_bytes(0x49ac5, 460))
+ def do_u16(name, addr, org_addr, org_size, bank_addr = None):
+ p = get_24(addr) if bank_addr == None else util.get_word(addr) | get_byte(bank_addr) << 16
+ sz = get_rats_size(p) // 2 if p != org_addr else org_size
+ add_asset_uint16(name, util.get_words(p, sz))
+ assert p == org_addr or LUNAR_MAGIC
+ return p != org_addr
+
+ def do_u8(name, addr, org_addr, org_size, bank_addr = None):
+ p = get_24(addr) if bank_addr == None else util.get_word(addr) | get_byte(bank_addr) << 16
+ sz = get_rats_size(p) if p != org_addr else org_size
+ add_asset_uint8(name, util.get_bytes(p, sz))
+ assert p == org_addr or LUNAR_MAGIC
+ return p != org_addr
+
+ def add_event_tile_entries():
+ do_u16('kLayer2EventData_TileEntries', 0x4E49F, 0x4DD8D, 742)
+ do_u16('kChangingLayer1OverworldTiles_Layer1TileLocation', 0x4EC8C, 0x4D85D, 112)
+ do_u16('kOwEventProcess01_DestroyTileAnimation_DATA_04E587', 0x4EEC9, 0x4E587, 16)
+ if do_u16('kCheckIfDestroyTileEventIsActive_DATA_04E5B6', 0x4E69C, 0x4E5B6, 16):
+ lm_feat.flags |= kLmFeature_DestroyTileAnims
+ do_u16('kOwEventProcess01_DestroyTileAnimation_DATA_04D93D', 0x4EDB8, 0x4D93D, 112)
+
+ do_u8('kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles', 0x4E9F4, 0x4E8E4, 44)
+ do_u8('kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileLayer', 0x4EA27, 0x4E910, 44)
+
+ do_u16('kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileNum', 0x4EA31+1, 0x4E994, 44)
+ do_u16('kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TilemapLocation', 0x4EA37+1, 0x4E93C, 44)
+
+ add_asset_uint8('kOwDestruction_TileToIdx_04E5A7', get_bytes(0x4e5a7, 5))
+ add_asset_uint8('kOwDestruction_TopTile_04E5AC', get_bytes(0x4e5ac, 5))
+ add_asset_uint8('kOwDestruction_BottomTile_04E5B1', get_bytes(0x4e5b1, 5))
+ do_u8('kOwDestruction_TriggerEvent_04E5D6', 0x4E67C, 0x4e5d6, 16)
+
+ add_event_tile_entries()
+
+ def add_eventstuff():
+ def get_words_rats(p):
+ return get_words(p, get_rats_size(p) // 2)
+
+ def get_u8_rats(p):
+ return get_bytes(p, get_rats_size(p))
+
+ r1, r2, r3, r4 = [], [], [], [],
+ if get_byte(0x4E9F7) == 0x22:
+ lm_feat.flags |= kLmFeature_EventStuff
+ p = get_24(0x4E9F8)
+ r1 = get_words_rats(get_24(p - 0x8008 + 0x8014 + 1))
+ r2 = get_words_rats(get_24(p - 0x8008 + 0x8029 + 1))
+ r3 = get_words_rats(get_24(p - 0x8008 + 0x802F + 1))
+ r4 = get_u8_rats(get_24(p - 0x8008 + 0x803B + 1))
+ add_asset_uint16('kLmEventStuff1', r1)
+ add_asset_uint16('kLmEventStuff2', r2)
+ add_asset_uint16('kLmEventStuff3', r3)
+ add_asset_uint8('kLmEventStuff4', r4)
+
+
+ add_eventstuff()
+
+ do_u8('kOverworldLayer2EventTilemap_Tiles', 0x4EAF5, 0xc8000, 3328)
+
+ p = get_word(0x4DC72) | get_byte(0x4DC79) << 16
+ _, sz = unpack_rle_of_size(p, 0x2000)
+ add_asset_uint8('kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap', get_bytes(p, sz))
+
+ p = get_word(0x4DC8d) | get_byte(0x4DC79) << 16
+ _, sz = unpack_rle_of_size(p, 0x2000)
+ add_asset_uint8('kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop', get_bytes(p, sz))
+
+ do_u8('kOverworldLayer2EventTilemap_Prop',
+ addr = 0x4DD45, org_addr = 0xC8D00, org_size = 1642, bank_addr = 0x4DD4a)
+
+ add_asset_uint8('kLoadOverworldLayer1AndEvents_DATA_0CF7DF', util.get_bytes(0xCF7DF, 0x800))
+ add_asset_uint8('kRom', util.ROM.ROM if args.include_rom else b'')
+
+ add_asset_uint8('kUpdateLevelName_LevelNameStrings', util.get_bytes(0x49ac5, 460))
add_asset_uint8('kGameMode25_ShowEnemyRollcallScreen_TileData', util.get_bytes(0xCAF11, 1681))
- add_asset_uint8('kRom', util.ROM.ROM if args.include_rom else b'')
+ lm_pals = []
+ if LUNAR_MAGIC and get_24(0xef577) == 0xf58320:
+ for i in range(0x200):
+ pp = util.get_24(0xEF600 + i * 3)
+ lm_pals.append(util.get_bytes(pp, 0x202) if pp else b'')
+ add_asset_packed('kLmPalettes', lm_pals)
+
+ add_asset_uint8('kPlayerGFXRt_HeadTilePointerIndex', util.get_bytes(0xE00C, 192))
+ add_asset_uint8('kPlayerGFXRt_BodyTilePointerIndex', util.get_bytes(0xE0CC, 192))
+
+ add_asset_uint8('kLvlInitialFlags', util.get_bytes(0x5DDA0, 96))
+ add_asset_uint8('kLoadOverworldSprites_SpriteSlotData', util.get_bytes(0x4F625, 65))
+ add_asset_uint8('kChangingLayer1OverworldTiles_TilesThatChange', util.get_bytes(0x4DA1D, 22))
+ add_asset_uint8('kChangingLayer1OverworldTiles_TilesToBecome', util.get_bytes(0x4DA33, 22))
+
+ add_asset_uint8('kOverworldEventProcess01_DestroyTileAnimation_DATA_04EE7A', util.get_bytes(0x4EE7A, 48))
+
+ add_asset_uint16('kLevelTileAnimations_FrameData', util.get_words(0x5B999, 208))
+
+ add_asset_uint8('kSetPlayerPose_WalkingPoseCount', util.get_bytes(0xDC78, 4))
+
+ add_asset_uint8('kDrawLoadingLetters_TileData', util.get_bytes(0x90d1, 52))
+ add_asset_uint8('kDrawLoadingLetters_TileData_BottomTiles', util.get_bytes(0x9105, 52))
+ add_asset_uint8('kDrawLoadingLetters_TileData_TopProp', util.get_bytes(0x9139, 52))
+ add_asset_uint8('kDrawLoadingLetters_TileData_BottomProp', util.get_bytes(0x916A, 52))
+
+ add_asset_uint16('kOwTileAnimations_WaterTileNumbers', util.get_words(0x48000, 3))
+ add_asset_uint16('kOwTileAnimations_TileNumbers', util.get_words(0x48006, 64))
+
+ def add_star_pipe_warp():
+ if get_byte(0x48509) == 0x22:
+ p = get_24(0x4850a)
+ n = get_word(p + 0xe00f - 0xdfff) // 2
+ add_asset_uint16('kOwStarPipeWarp_SrcX_048431', get_words(get_24(p + 0xe016 - 0xdfff), n))
+ add_asset_uint16('kOwStarPipeWarp_SrcY_048467', get_words(get_24(p + 0xe026 - 0xdfff), n))
+ assert get_byte(0x48566) == 0x22
+ p = get_24(0x48567)
+ add_asset_uint16('kOwStarPipeWarp_DstX_04849D', get_words(get_24(p + 0xe04b - 0xe03f), n))
+ add_asset_uint16('kOwStarPipeWarp_DstY_0484D3', get_words(get_24(p + 0xe05d - 0xe03f), n))
+ else:
+ add_asset_uint16('kOwStarPipeWarp_SrcX_048431', get_words(0x48431, 27))
+ add_asset_uint16('kOwStarPipeWarp_SrcY_048467', get_words(0x48467, 27))
+ add_asset_uint16('kOwStarPipeWarp_DstX_04849D', get_words(0x4849d, 27))
+ add_asset_uint16('kOwStarPipeWarp_DstY_0484D3', get_words(0x484d3, 27))
+
+ add_star_pipe_warp()
+
+ add_asset_uint16('kOwLevelsForcedMusicChange_048D74', get_words(0x48d74, 11))
+ add_asset_uint8('kOwSubmapMusic_048D8A', get_bytes(0x48d8a, 7))
+ add_asset_uint16('kOw_KoopaKidTeleportXYPos_048E49', get_words(0x48e49, 6))
+ add_asset_uint8('kOwTriggerSaveTiles_048F7F', get_bytes(0x48f7f, 8))
+ add_asset_uint16('kOwNoAutoMoveLevels_04906C', get_words(0x4906c, 6))
+ add_asset_uint8('kOwHardcodedPathLevel_049078', get_bytes(0x49078, 10))
+ add_asset_uint16('kOwHardcodedPathChocolateIsland2_049082', get_words(0x49082, 2))
+ add_asset_uint8('kOwHardcodedPathTiles_049086', get_bytes(0x49086, 68))
+ add_asset_uint8('kOwHardcodedPathDirs_0490CA', get_bytes(0x490ca, 68))
+ add_asset_uint8('kOwHardcodedPathStartIndex_04910E', get_bytes(0x4910e, 10))
+ add_asset_uint8('kOwExitLevelTiles_049426', get_bytes(0x49426, 10))
+ add_asset_uint16('kUpdateLevelName_DATA_049C91', get_words(0x49c91, 31))
+ add_asset_uint16('kUpdateLevelName_DATA_049CCF', get_words(0x49ccf, 15))
+ add_asset_uint16('kUpdateLevelName_DATA_049CED', get_words(0x49ced, 13))
+ add_asset_uint8('kOwExitSource_049964', get_bytes(0x49964, 70))
+ add_asset_uint8('kOwExitDest_0499AA', get_bytes(0x499aa, 70))
+ add_asset_uint8('kOwExitExtra_0499F0', get_bytes(0x499f0, 28))
+ add_asset_uint16('kOwExitLayerPosition_049A0C', get_words(0x49a0c, 12))
+ add_asset_uint8('kOwUnknownTableA_From_04A03C', get_bytes(0x4a03c, 24))
+ add_asset_uint16('kOwUnknownTableA_Alpha_04A054', get_words(0x4a054, 24))
+ add_asset_uint16('kOwUnknownTableA_XY_04A084', get_words(0x4a084, 48))
+ add_asset_uint8('kOwUnknownTableA_Direction_04A0E4', get_bytes(0x4a0e4, 24))
+ add_asset_uint8('kOwDirectionAfterBeatingLevel_04D678', get_bytes(0x4d678, 113))
+ add_asset_uint8('kOwSubmapTileset_04DC02', get_bytes(0x4dc02, 7))
+ add_asset_uint16('kLayer2EventData_Ptrs_04E359', get_words(0x4e359, 121))
+
+ add_asset_uint8('kLmInitSaveData', get_bytes(0x05DDA0, 96) if get_byte(0x5dd80) != 0xff else b'')
+ add_asset_uint8('kInitializeSaveData_InitialOWPlayerPos', get_bytes(0x9EF0, 22))
+
+ add_asset_uint16('kOWSpr07_Smoke_DATA_04FC1E', get_words(0x4FC1E, 4))
+
+ add_asset_uint16('kLoadOverworldSprites_SubmapBooXPosOffset', get_words(0x4F666, 3))
+ add_asset_uint16('kLoadOverworldSprites_SubmapBooYPosOffset', get_words(0x4F66C, 3))
+
+ add_asset_uint8('kLoadLevelHeader_LevelMusicTable', get_bytes(0x584DB, 8))
+
+ # hack
+ add_asset_uint8('kLevelsThatTriggerCutscenes', get_bytes(0xC9A7, 8) + bytearray([get_byte(0xCA0C), get_byte(0xCA13)]))
#add_asset_uint16('', util.get_words(0x, ))
#add_asset_uint8('', util.get_bytes(0x, ))
+ def add_exgfx(name, addr, size):
+ r = []
+ if LUNAR_MAGIC and addr != 0xffffff:
+ for i in range(size):
+ p = util.get_24(addr + i * 3)
+ r.append(get_comp_data(p) if p not in (0, 0xffffff) else b'')
+ while len(r) and r[-1] == b'':
+ r.pop()
+ add_asset_packed(name, r)
+
+ add_exgfx('kLmExgfx', 0xFF600, 128)
+ add_exgfx('kLmSuperExgfx', get_24(0xFF937), 0x1000 - 0x100)
+ add_asset_uint8('kLmGraphicsRemapped', remove_trail_zero(util.get_bytes(0xFF200, 1024)) if LUNAR_MAGIC else b'')
+
+ def add_load_level_stuff():
+ lm_load_level = get_byte(0x5D9A1) == 0x22
+
+ p = get_24(0x6F624)
+ add_asset_uint16('kLmModifyMap16Ids', util.get_words(p, 4096) if lm_load_level and p != 0xffffff else b'')
+ add_asset_uint8('kLm5DE00', util.get_bytes(0x5DE00, 512) if lm_load_level else b'')
+ add_asset_uint8('kLm6FC00', util.get_bytes(0x6FC00, 512) if lm_load_level else b'')
+ add_asset_uint8('kLm6FE00', util.get_bytes(0x6FE00, 512) if lm_load_level else b'')
+
+ p = util.get_24(util.get_24(0x5D9A2) + 0x10BBDF - 0x10BB83) if lm_load_level else 0
+ add_asset_uint8('kLm10B8BC', util.get_bytes(p, 512) if p != 0 else b'')
+ add_asset_uint8('kLmLevelData3FE00', util.get_bytes(0x3FE00, 512) if lm_load_level else b'')
+
+ add_asset_uint8('kLmLevelData5DC85', util.get_bytes(get_24(0x5DC86), 512) if lm_load_level else b'')
+ add_asset_uint8('kLmLevelData5DC8A', util.get_bytes(get_24(0x5DC8B), 512) if lm_load_level else b'')
+ add_asset_uint8('kLm5FE00', util.get_bytes(get_24(0x5DC81), 512) if lm_load_level else b'')
+
+ add_asset_uint8('kLevelInfo_05F800', util.get_bytes(get_24(0xde191), 0x200) if lm_load_level else b'')
+ add_asset_uint8('kLevelInfo_05FA00', util.get_bytes(get_24(0xde198), 0x200) if lm_load_level else b'')
+ add_asset_uint8('kLevelInfo_05FC00', util.get_bytes(get_24(0xde19f), 0x200) if lm_load_level else b'')
+ lm_feat.flags |= kLmFeature_LoadLevel if lm_load_level else 0
+
+ add_load_level_stuff()
+
+ def add_lm_map16():
+ if LUNAR_MAGIC:
+ B = 0x06F500
+ half = (get_byte(0x6F54B) != 0xB0)
+ B -= 2 if half else 0
+ arr = [
+ get_byte(B + 0x57)<<16|(get_word(B + 0x53)+0x1000&0xFFFF),
+ get_byte(B + 0x60)<<16|(get_word(B + 0x5C)^0x8000),
+ get_byte(B + 0x6B)<<16|(get_word(B + 0x67)+1 & 0xFFFF),
+ get_byte(B + 0x74)<<16|(get_word(B + 0x70)+0x8001&0xFFFF),
+ ]
+ if not half:
+ arr += [
+ get_byte(B + 0x98)<<16|get_word(B + 0x94),
+ get_byte(B + 0xA1)<<16|(get_word(B + 0x9D)+0x8000&0xFFFF),
+ get_byte(B + 0xAC)<<16|(get_word(B + 0xA8)+1 & 0xFFFF),
+ get_byte(B + 0xB5)<<16|(get_word(B + 0xB1)+0x8001&0xFFFF),
+ ]
+ else:
+ print('Warning: Half map16', file=sys.stderr)
+ arr += [0, 0, 0, 0]
+ arr.append(get_byte(B + 0x8A)<<16|(get_word(B + 0x86)+0x1000&0xFFFF)), # TS
+ else:
+ arr = [0 for i in range(9)]
+
+ for i, p in enumerate(arr):
+ sz = get_rats_size(p)
+ add_asset_uint16('kMap16_%s' % ('TS' if i == 8 else i), get_words(p, sz // 2))
+
+ add_lm_map16()
+
+ #add_asset_uint16('kMap16Bank11', util.get_words(0x118000, 16384) if LUNAR_MAGIC else b'')
+ #add_asset_uint16('kMap16Bank12', util.get_words(0x128000, 12288) if LUNAR_MAGIC else b'')
+
+ def calc_one_exanim_end(p):
+ p_org = p
+ tp = util.get_byte(p)
+ trigger = util.get_byte(p + 1)
+ if tp >= 1 and tp <= 0x13:
+ limit = util.get_byte(p + 2)
+ p += 5 # type, trigger, limit, dest(w)
+ p += (limit + 1) * 2 * (1 if trigger==0 else 2)
+ return p
+ raise Exception('exanim type %x not supported' % tp)
+
+ def calc_exanim_size(p):
+ p_org = p
+ num = util.get_word(p)
+ trig = util.get_word(p + 6)
+ p += 8
+ for i in range(16):
+ if trig & (1 << i):
+ p += 2 # manual triggers
+ max_p = p
+ for i in range(num):
+ pd = util.get_word(p + i * 2)
+ max_p = max(max_p, calc_one_exanim_end(p + pd))
+ return max_p - p_org
+
+ # parse all level exanimation
+ lm_lvl_exanim = []
+ lm_exanim_ranges = []
+ if LUNAR_MAGIC and get_byte(0x0583AD) == 0x22: # call LmHook_InitExanimForLevel
+ LmHook_InitExanimForLevel = get_24(0x583AE)
+ if get_bytes(LmHook_InitExanimForLevel, 4) != b'\xe2\x30\x8b\xa2':
+ raise Exception('The Exanim file format is incorrect. ' + extra_lunar_magic_text())
+
+ exanim_ptr = get_24((0x10C24E - 0x10C164) + LmHook_InitExanimForLevel) # 0x10CD9C
+
+ for i in range(512):
+ p = util.get_24(exanim_ptr + i * 3)
+ lm_lvl_exanim.append(0 if (p & 0x8000) == 0 else p)
+ if (p & 0x8000) != 0:
+ sz = calc_exanim_size(p)
+ lm_exanim_ranges.append((p, p + sz))
+ lm_feat.flags |= kLmFeature_Exanim
+
+ add_asset_uint8('kLmLvlExAnim', b''.join(pack_24(a) for a in remove_trail_zero(lm_lvl_exanim)))
+ add_asset_blob('kLmExanimBlob', lm_exanim_ranges)
+
+ kSkipOwDecompressMap = {
+ b'\xea\xea\xea\xea' : kLmFeature_SkipOverworldDecompress,
+ b'\x22\x00\xFC\x0E' : 0, # lm
+ b'\x22\x28\xBA\x00' : 0, # orig
+ }
+
+ lm_feat.flags |= kLmFeature_LmEnabled if LUNAR_MAGIC else 0
+ lm_feat.flags |= kSkipOwDecompressMap[bytes(get_bytes(0xA149, 4))]
+ lm_feat.flags |= kLmFeature_OverworldTiles4bpp if get_byte(0x480D0) == 0x60 else 0
+ lm_feat.flags |= kLmFeature_Copy512colors if get_byte(0xA5E1) == 0xea else 0
+ lm_feat.flags |= kLmFeature_WeirdPalette if get_byte(0xAF71) == 0x22 else 0
+ lm_feat.flags |= kLmFeature_SkipLoadPaletteHook if get_byte(0xEF570) != 0xc2 else 0
+ lm_feat.flags |= kLmFeature_GfxUpload if get_bytes(0xAA6B, 4) != b'\x22\x28\xBA\x00' else 0
+ lm_feat.flags |= kLmFeature_4bppgfx if get_byte(0xAACE) == 0x10 else 0
+ lm_feat.flags |= kLmFeature_DontSetYposForIntroMarch if get_byte(0x05B15D) == 0xea else 0
+ lm_feat.flags |= kLmFeature_MusicRegTweak if get_byte(0x5855C) == 0x8d else 0
+ lm_feat.flags |= kLmFeature_TideWaterTweak if get_byte(0xa045) == 0x22 else 0
+ lm_feat.flags |= kLmFeature_EnemyCollTweak if get_byte(0x194B6) == 0x5c else 0
+ lm_feat.flags |= kLmFeature_Ow4bppGfx if get_bytes(0xA149, 4) != b'\x22\x28\xBA\x00' else 0
+
+ # Allows Mario to perform a wall kick by sliding along a wall and pressing the
+ # B button.
+ lm_feat.hacks |= kHack_Walljump if get_24(0xA2A2) != 0x586F1 else 0
+
+ def add_custom_ow_palette():
+ r = b''
+ if get_byte(0xAD32) == 0x22:
+ lm_feat.flags |= kLmFeature_OwPalette
+ p = get_24(0xAD33) - 0x10813F
+ r = get_rats_bytes(get_byte(p + 0x10815D) << 16 | get_word(p + 0x108151))
+ add_asset_uint8('kLmOverworldPal', r)
+ add_custom_ow_palette()
+
+ def add_custom_display_message():
+ flag = get_byte(0x5B1A3) == 0x22
+ lm_feat.flags |= kLmFeature_CustomDisplayMessage if flag else 0
+ add_asset_uint8('kLmDisplayMessage_Tab0', get_rats_bytes(get_24(0x3BC0B)) if flag else b'')
+ add_asset_uint16('kLmDisplayMessage_3BC7F', get_words(0x3BC7F, 8) if flag else b'')
+ add_asset_uint16('kLmDisplayMessage_3BE80', get_words(0x3BE80, 192) if flag else b'')
+ r = []
+ if flag:
+ for a in [0x3BB9A, 0x3BBA1, 0x3BBA6, 0x3BBAB, 0x3BBB0]:
+ assert get_byte(a) == 0xe0
+ r.append(get_byte(a+1))
+ add_asset_uint8('kLmDisplayMessage_Tab1', r)
+
+ add_custom_display_message()
+
+ def add_custom_title_screen():
+ lm_feat.flags |= kLmFeature_CustomTitleScreenDemo if get_byte(0x9c6f) == 0x22 else 0
+ r = b''
+ if lm_feat.flags & kLmFeature_CustomTitleScreenDemo:
+ p = get_24(get_24(0x9c70) + 0x10F6B0 - 0x10F68D) - 2
+ r = get_bytes(p, get_rats_size(p))
+ add_asset_uint8('kLmTitleScreenMoves', r)
+
+ add_custom_title_screen()
+
+ def add_level_names_patch():
+ lm_feat.flags |= kLmFeature_LevelNamesPatch if get_byte(0x48E81) == 0x22 else 0
+ r = b''
+ if lm_feat.flags & kLmFeature_LevelNamesPatch:
+ p = get_24(0x3BB57)
+ r = get_bytes(p, get_rats_size(p))
+ add_asset_uint8('kLmLevelNamesPatch', r)
+
+ add_level_names_patch()
+
+ # compressed layer1 and events
+ def add_overworld():
+ d = []
+ if get_byte(0x4d813) == 0x5c:
+ d = get_comp_data(get_byte(0x4d808) << 16 | get_word(0x4d803))
+ add_asset_uint8('kOwLayer1AndEvents', d)
+
+ d = []
+ if get_byte(0x4d832) == 0x5c:
+ d = get_comp_data(get_byte(0x4d827) << 16 | get_word(0x4d822))
+ add_asset_uint8('kOwLayer1AndEvents2', d)
+
+ add_overworld()
+
+ r = b''
+ if LUNAR_MAGIC and get_byte(0xA140) == 0x22:
+ lm_feat.kLmLvlInfo_addr_other = get_byte(0xFFAC2) << 16 | get_word(0xFFAB9)
+ lm_feat.kLmLvlInfo_addr = get_24(0xFF7FF)
+ r = util.get_words(lm_feat.kLmLvlInfo_addr, (512+8) * 16)
+ add_asset_uint16('kLmLvlInfo', r)
+ #add_lm_lvlinfo()
+
+
+
+ def add_custom_map16_bg():
+ r = []
+ if LUNAR_MAGIC:
+ for i in range(16):
+ p = util.get_24(0xEFD50 + i * 3)
+ if p:
+ r.append(util.get_bytes(p, 0x8000 - (p & 0x7fff)))
+ else:
+ r.append(b'')
+ add_asset_packed('kLmCustomMap16Bg', remove_trail_empty(r))
+ add_custom_map16_bg()
+
+ def add_sprite_extra_size():
+ r = b''
+ if LUNAR_MAGIC:
+ p = util.get_24(0xef30c)
+ if p != 0xffffff:
+ r = util.get_bytes(p, 1024)
+ add_asset_uint8('kLmSprExtraSize', r)
+ add_sprite_extra_size()
+
+ add_asset_uint8('kLmFeatures', lm_feat.serialize())
def write_assets_to_file(print_header = False):
@@ -293,7 +836,7 @@ def write_assets_to_file(print_header = False):
all_data = []
if print_header:
print('''#pragma once
-#include "types.h"
+#include "../src/types.h"
enum {
kNumberOfAssets = %d
@@ -301,14 +844,20 @@ enum {
extern const uint8 *g_asset_ptrs[kNumberOfAssets];
extern uint32 g_asset_sizes[kNumberOfAssets];
extern MemBlk FindInAssetArray(int asset, int idx);
+extern const uint8 *FindPtrInAsset(int asset, uint32 addr);
''' % len(assets))
for i, (k, (tp, data)) in enumerate(assets.items()):
if print_header:
if tp == 'packed':
print('#define %s(idx) FindInAssetArray(%d, idx)' % (k, i))
+ elif tp == 'blob':
+ print('#define %s(addr) FindPtrInAsset(%d, addr)' % (k, i))
else:
- print('#define %s ((%s*)g_asset_ptrs[%d])' % (k, tp, i))
+ if tp == 'uint8':
+ print('#define %s g_asset_ptrs[%d]' % (k, i))
+ else:
+ print('#define %s ((%s*)g_asset_ptrs[%d])' % (k, tp, i))
print('#define %s_SIZE (g_asset_sizes[%d])' % (k, i))
key_sig += k.encode('utf8') + b'\0'
all_data.append(data)
diff --git a/assets/restool.py b/assets/restool.py
index 2cdc52f..a90fc80 100644
--- a/assets/restool.py
+++ b/assets/restool.py
@@ -5,8 +5,7 @@ import sys
parser = argparse.ArgumentParser(description='Resource tool used to build smw_assets.dat', allow_abbrev=False)
parser.add_argument('-r', '--rom', nargs='?', metavar='ROM')
parser.add_argument('--extract-from-rom', '-e', action='store_true', help='Extract assets from the ROM')
-
-
+parser.add_argument('--no-hash-check', '-f', action='store_true', help='Bypass the hash check (needed for Lunar Magic roms)')
parser.add_argument('--no-include-rom', dest='include_rom', action='store_false', help='Don''t include the ROM in the assets file for verification')
optional = parser.add_argument_group('Debug things')
@@ -14,9 +13,9 @@ optional.add_argument('--print-assets-header', action='store_true')
args = parser.parse_args()
-ROM = util.load_rom(args.rom)
+ROM = util.load_rom(args.rom, disable_hash_check = args.no_hash_check)
+
-want_compile = True
import compile_resources
compile_resources.main(args)
diff --git a/assets/smw_assets.h b/assets/smw_assets.h
index b2d05ff..27c3c57 100644
--- a/assets/smw_assets.h
+++ b/assets/smw_assets.h
@@ -1,114 +1,350 @@
#pragma once
-#include "src/types.h"
+#include "../src/types.h"
enum {
- kNumberOfAssets = 58
+ kNumberOfAssets = 178
};
extern const uint8 *g_asset_ptrs[kNumberOfAssets];
extern uint32 g_asset_sizes[kNumberOfAssets];
extern MemBlk FindInAssetArray(int asset, int idx);
+extern const uint8 *FindPtrInAsset(int asset, uint32 addr);
#define kGraphicsPtrs(idx) FindInAssetArray(0, idx)
-#define kGfx32 ((uint8*)g_asset_ptrs[1])
+#define kGfx32 g_asset_ptrs[1]
#define kGfx32_SIZE (g_asset_sizes[1])
-#define kGfx33 ((uint8*)g_asset_ptrs[2])
+#define kGfx33 g_asset_ptrs[2]
#define kGfx33_SIZE (g_asset_sizes[2])
#define kLoadStripeImagePtrs(idx) FindInAssetArray(3, idx)
#define kLayer3ImagePtrs(idx) FindInAssetArray(4, idx)
-#define kOverworldLayer2EventTilemap_Tiles ((uint8*)g_asset_ptrs[5])
-#define kOverworldLayer2EventTilemap_Tiles_SIZE (g_asset_sizes[5])
-#define kSpcCreditsMusicBank ((uint8*)g_asset_ptrs[6])
-#define kSpcCreditsMusicBank_SIZE (g_asset_sizes[6])
-#define kSpcLevelMusicBank ((uint8*)g_asset_ptrs[7])
-#define kSpcLevelMusicBank_SIZE (g_asset_sizes[7])
-#define kSpcEngine ((uint8*)g_asset_ptrs[8])
-#define kSpcEngine_SIZE (g_asset_sizes[8])
-#define kSpcSamples ((uint8*)g_asset_ptrs[9])
-#define kSpcSamples_SIZE (g_asset_sizes[9])
-#define kSpcOverworldMusicBank ((uint8*)g_asset_ptrs[10])
-#define kSpcOverworldMusicBank_SIZE (g_asset_sizes[10])
-#define kMap16Data_OverworldLayer1 ((uint16*)g_asset_ptrs[11])
-#define kMap16Data_OverworldLayer1_SIZE (g_asset_sizes[11])
-#define kkOverworldLayer2EventTilemap_Prop ((uint8*)g_asset_ptrs[12])
-#define kkOverworldLayer2EventTilemap_Prop_SIZE (g_asset_sizes[12])
-#define kMap16Data ((uint16*)g_asset_ptrs[13])
-#define kMap16Data_SIZE (g_asset_sizes[13])
-#define kMap16Data_Castle ((uint16*)g_asset_ptrs[14])
-#define kMap16Data_Castle_SIZE (g_asset_sizes[14])
-#define kMap16Data_Rope ((uint16*)g_asset_ptrs[15])
-#define kMap16Data_Rope_SIZE (g_asset_sizes[15])
-#define kMap16Data_Underground ((uint16*)g_asset_ptrs[16])
-#define kMap16Data_Underground_SIZE (g_asset_sizes[16])
-#define kMap16Data_GhostHouse ((uint16*)g_asset_ptrs[17])
-#define kMap16Data_GhostHouse_SIZE (g_asset_sizes[17])
-#define kGameMode1B_EndingCinema_Tilemaps ((uint8*)g_asset_ptrs[18])
-#define kGameMode1B_EndingCinema_Tilemaps_SIZE (g_asset_sizes[18])
-#define kGameMode1B_EndingCinema_RowPointers ((uint16*)g_asset_ptrs[19])
-#define kGameMode1B_EndingCinema_RowPointers_SIZE (g_asset_sizes[19])
-#define kLevelInfo_05F000 ((uint8*)g_asset_ptrs[20])
-#define kLevelInfo_05F000_SIZE (g_asset_sizes[20])
-#define kLevelInfo_05F200 ((uint8*)g_asset_ptrs[21])
-#define kLevelInfo_05F200_SIZE (g_asset_sizes[21])
-#define kLevelInfo_05F400 ((uint8*)g_asset_ptrs[22])
-#define kLevelInfo_05F400_SIZE (g_asset_sizes[22])
-#define kLevelInfo_05F600 ((uint8*)g_asset_ptrs[23])
-#define kLevelInfo_05F600_SIZE (g_asset_sizes[23])
-#define kLevelInfo_05F800 ((uint8*)g_asset_ptrs[24])
-#define kLevelInfo_05F800_SIZE (g_asset_sizes[24])
-#define kLevelInfo_05FA00 ((uint8*)g_asset_ptrs[25])
-#define kLevelInfo_05FA00_SIZE (g_asset_sizes[25])
-#define kLevelInfo_05FC00 ((uint8*)g_asset_ptrs[26])
-#define kLevelInfo_05FC00_SIZE (g_asset_sizes[26])
-#define kLevelInfo_05FE00 ((uint8*)g_asset_ptrs[27])
-#define kLevelInfo_05FE00_SIZE (g_asset_sizes[27])
-#define kLoadLevel_DATA_05D608 ((uint8*)g_asset_ptrs[28])
-#define kLoadLevel_DATA_05D608_SIZE (g_asset_sizes[28])
-#define kDisplayMessage_DATA_05A5D9 ((uint8*)g_asset_ptrs[29])
-#define kDisplayMessage_DATA_05A5D9_SIZE (g_asset_sizes[29])
-#define kOverworldLightningAndRandomCloudSpawning ((uint8*)g_asset_ptrs[30])
-#define kOverworldLightningAndRandomCloudSpawning_SIZE (g_asset_sizes[30])
-#define kLevelNames ((uint16*)g_asset_ptrs[31])
-#define kLevelNames_SIZE (g_asset_sizes[31])
-#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap ((uint8*)g_asset_ptrs[32])
-#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_SIZE (g_asset_sizes[32])
-#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop ((uint8*)g_asset_ptrs[33])
-#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop_SIZE (g_asset_sizes[33])
-#define kLoadOverworldLayer1AndEvents_DATA_0CF7DF ((uint8*)g_asset_ptrs[34])
-#define kLoadOverworldLayer1AndEvents_DATA_0CF7DF_SIZE (g_asset_sizes[34])
-#define kLineGuideSpeedTableData ((uint8*)g_asset_ptrs[35])
-#define kLineGuideSpeedTableData_SIZE (g_asset_sizes[35])
-#define kLevelData_Layer1(idx) FindInAssetArray(36, idx)
-#define kEntranceData_Layer1(idx) FindInAssetArray(37, idx)
-#define kChoclateIsland2_Layer1(idx) FindInAssetArray(38, idx)
-#define kRollCallData_Layer1(idx) FindInAssetArray(39, idx)
-#define kLevelData_Layer2(idx) FindInAssetArray(40, idx)
-#define kLevelData_Layer2_IsBg ((uint8*)g_asset_ptrs[41])
-#define kLevelData_Layer2_IsBg_SIZE (g_asset_sizes[41])
-#define kEntranceData_Layer2(idx) FindInAssetArray(42, idx)
-#define kEntranceData_Layer2_IsBg ((uint8*)g_asset_ptrs[43])
-#define kEntranceData_Layer2_IsBg_SIZE (g_asset_sizes[43])
-#define kChoclateIsland2_Layer2(idx) FindInAssetArray(44, idx)
-#define kChoclateIsland2_Layer2_IsBg ((uint8*)g_asset_ptrs[45])
-#define kChoclateIsland2_Layer2_IsBg_SIZE (g_asset_sizes[45])
-#define kRollCallData_Layer2(idx) FindInAssetArray(46, idx)
-#define kRollCallData_Layer2_IsBg ((uint8*)g_asset_ptrs[47])
-#define kRollCallData_Layer2_IsBg_SIZE (g_asset_sizes[47])
-#define kBufferCreditsBackgrounds_Layer2(idx) FindInAssetArray(48, idx)
-#define kBufferCreditsBackgrounds_Layer2_IsBg ((uint8*)g_asset_ptrs[49])
-#define kBufferCreditsBackgrounds_Layer2_IsBg_SIZE (g_asset_sizes[49])
-#define kLoadLevelSpriteList(idx) FindInAssetArray(50, idx)
-#define kLoadLevel_SpriteDataPtrs ((uint16*)g_asset_ptrs[51])
-#define kLoadLevel_SpriteDataPtrs_SIZE (g_asset_sizes[51])
-#define kFileSelectText_EraseFile ((uint8*)g_asset_ptrs[52])
-#define kFileSelectText_EraseFile_SIZE (g_asset_sizes[52])
-#define kInitializeMode7TilemapsAndPalettes_TilemapData ((uint8*)g_asset_ptrs[53])
-#define kInitializeMode7TilemapsAndPalettes_TilemapData_SIZE (g_asset_sizes[53])
-#define kLayer2EventData_TileEntries ((uint16*)g_asset_ptrs[54])
-#define kLayer2EventData_TileEntries_SIZE (g_asset_sizes[54])
-#define kUpdateLevelName_LevelNameStrings ((uint8*)g_asset_ptrs[55])
-#define kUpdateLevelName_LevelNameStrings_SIZE (g_asset_sizes[55])
-#define kGameMode25_ShowEnemyRollcallScreen_TileData ((uint8*)g_asset_ptrs[56])
-#define kGameMode25_ShowEnemyRollcallScreen_TileData_SIZE (g_asset_sizes[56])
-#define kRom ((uint8*)g_asset_ptrs[57])
-#define kRom_SIZE (g_asset_sizes[57])
-#define kAssets_Sig 83, 109, 119, 95, 118, 48, 32, 32, 32, 32, 32, 32, 32, 32, 10, 0, 52, 78, 183, 252, 40, 131, 208, 13, 64, 107, 152, 161, 6, 99, 150, 130, 181, 105, 242, 158, 255, 50, 227, 158, 57, 108, 112, 255, 9, 165, 191, 187
+#define kSpcCreditsMusicBank g_asset_ptrs[5]
+#define kSpcCreditsMusicBank_SIZE (g_asset_sizes[5])
+#define kSpcLevelMusicBank g_asset_ptrs[6]
+#define kSpcLevelMusicBank_SIZE (g_asset_sizes[6])
+#define kSpcEngine g_asset_ptrs[7]
+#define kSpcEngine_SIZE (g_asset_sizes[7])
+#define kSpcSamples g_asset_ptrs[8]
+#define kSpcSamples_SIZE (g_asset_sizes[8])
+#define kSpcOverworldMusicBank g_asset_ptrs[9]
+#define kSpcOverworldMusicBank_SIZE (g_asset_sizes[9])
+#define kMap16Data_OverworldLayer1 ((uint16*)g_asset_ptrs[10])
+#define kMap16Data_OverworldLayer1_SIZE (g_asset_sizes[10])
+#define kMap16Data ((uint16*)g_asset_ptrs[11])
+#define kMap16Data_SIZE (g_asset_sizes[11])
+#define kMap16Data_Castle ((uint16*)g_asset_ptrs[12])
+#define kMap16Data_Castle_SIZE (g_asset_sizes[12])
+#define kMap16Data_Rope ((uint16*)g_asset_ptrs[13])
+#define kMap16Data_Rope_SIZE (g_asset_sizes[13])
+#define kMap16Data_Underground ((uint16*)g_asset_ptrs[14])
+#define kMap16Data_Underground_SIZE (g_asset_sizes[14])
+#define kMap16Data_GhostHouse ((uint16*)g_asset_ptrs[15])
+#define kMap16Data_GhostHouse_SIZE (g_asset_sizes[15])
+#define kGlobalPalettes_Sky ((uint16*)g_asset_ptrs[16])
+#define kGlobalPalettes_Sky_SIZE (g_asset_sizes[16])
+#define kGlobalPalettes_Background ((uint16*)g_asset_ptrs[17])
+#define kGlobalPalettes_Background_SIZE (g_asset_sizes[17])
+#define kGlobalPalettes_Layer3 ((uint16*)g_asset_ptrs[18])
+#define kGlobalPalettes_Layer3_SIZE (g_asset_sizes[18])
+#define kGlobalPalettes_Foreground ((uint16*)g_asset_ptrs[19])
+#define kGlobalPalettes_Foreground_SIZE (g_asset_sizes[19])
+#define kGlobalPalettes_Objects ((uint16*)g_asset_ptrs[20])
+#define kGlobalPalettes_Objects_SIZE (g_asset_sizes[20])
+#define kPlayerPalettes ((uint16*)g_asset_ptrs[21])
+#define kPlayerPalettes_SIZE (g_asset_sizes[21])
+#define kGlobalPalettes_Sprites ((uint16*)g_asset_ptrs[22])
+#define kGlobalPalettes_Sprites_SIZE (g_asset_sizes[22])
+#define kGlobalPalettes_YoshiBerry ((uint16*)g_asset_ptrs[23])
+#define kGlobalPalettes_YoshiBerry_SIZE (g_asset_sizes[23])
+#define kGlobalPalettes_Flashing ((uint16*)g_asset_ptrs[24])
+#define kGlobalPalettes_Flashing_SIZE (g_asset_sizes[24])
+#define kGlobalPalettes_OW_Objects ((uint16*)g_asset_ptrs[25])
+#define kGlobalPalettes_OW_Objects_SIZE (g_asset_sizes[25])
+#define kGlobalPalettes_OW_Sprites ((uint16*)g_asset_ptrs[26])
+#define kGlobalPalettes_OW_Sprites_SIZE (g_asset_sizes[26])
+#define kGlobalPalettes_B5EC ((uint16*)g_asset_ptrs[27])
+#define kGlobalPalettes_B5EC_SIZE (g_asset_sizes[27])
+#define kGlobalPalettes_OW_Areas ((uint16*)g_asset_ptrs[28])
+#define kGlobalPalettes_OW_Areas_SIZE (g_asset_sizes[28])
+#define kGlobalPalettes_OW_AreasPassed ((uint16*)g_asset_ptrs[29])
+#define kGlobalPalettes_OW_AreasPassed_SIZE (g_asset_sizes[29])
+#define kGlobalPalettes_Bowser ((uint16*)g_asset_ptrs[30])
+#define kGlobalPalettes_Bowser_SIZE (g_asset_sizes[30])
+#define kGlobalPalettes_Layer3Smasher ((uint16*)g_asset_ptrs[31])
+#define kGlobalPalettes_Layer3Smasher_SIZE (g_asset_sizes[31])
+#define kGameMode1B_EndingCinema_Tilemaps g_asset_ptrs[32]
+#define kGameMode1B_EndingCinema_Tilemaps_SIZE (g_asset_sizes[32])
+#define kGameMode1B_EndingCinema_RowPointers ((uint16*)g_asset_ptrs[33])
+#define kGameMode1B_EndingCinema_RowPointers_SIZE (g_asset_sizes[33])
+#define kLevelInfo_05F000 g_asset_ptrs[34]
+#define kLevelInfo_05F000_SIZE (g_asset_sizes[34])
+#define kLevelInfo_05F200 g_asset_ptrs[35]
+#define kLevelInfo_05F200_SIZE (g_asset_sizes[35])
+#define kLevelInfo_05F400 g_asset_ptrs[36]
+#define kLevelInfo_05F400_SIZE (g_asset_sizes[36])
+#define kLevelInfo_05F600 g_asset_ptrs[37]
+#define kLevelInfo_05F600_SIZE (g_asset_sizes[37])
+#define kLoadLevel_DATA_05D608 g_asset_ptrs[38]
+#define kLoadLevel_DATA_05D608_SIZE (g_asset_sizes[38])
+#define kDisplayMessage_DATA_05A5D9 g_asset_ptrs[39]
+#define kDisplayMessage_DATA_05A5D9_SIZE (g_asset_sizes[39])
+#define kOverworldLightningAndRandomCloudSpawning g_asset_ptrs[40]
+#define kOverworldLightningAndRandomCloudSpawning_SIZE (g_asset_sizes[40])
+#define kLevelNames ((uint16*)g_asset_ptrs[41])
+#define kLevelNames_SIZE (g_asset_sizes[41])
+#define kLineGuideSpeedTableData g_asset_ptrs[42]
+#define kLineGuideSpeedTableData_SIZE (g_asset_sizes[42])
+#define kLevelData_Layer1(idx) FindInAssetArray(43, idx)
+#define kEntranceData_Layer1(idx) FindInAssetArray(44, idx)
+#define kChoclateIsland2_Layer1(idx) FindInAssetArray(45, idx)
+#define kRollCallData_Layer1(idx) FindInAssetArray(46, idx)
+#define kLevelData_Layer2(idx) FindInAssetArray(47, idx)
+#define kLevelData_Layer2_IsBg g_asset_ptrs[48]
+#define kLevelData_Layer2_IsBg_SIZE (g_asset_sizes[48])
+#define kEntranceData_Layer2(idx) FindInAssetArray(49, idx)
+#define kEntranceData_Layer2_IsBg g_asset_ptrs[50]
+#define kEntranceData_Layer2_IsBg_SIZE (g_asset_sizes[50])
+#define kChoclateIsland2_Layer2(idx) FindInAssetArray(51, idx)
+#define kChoclateIsland2_Layer2_IsBg g_asset_ptrs[52]
+#define kChoclateIsland2_Layer2_IsBg_SIZE (g_asset_sizes[52])
+#define kRollCallData_Layer2(idx) FindInAssetArray(53, idx)
+#define kRollCallData_Layer2_IsBg g_asset_ptrs[54]
+#define kRollCallData_Layer2_IsBg_SIZE (g_asset_sizes[54])
+#define kBufferCreditsBackgrounds_Layer2(idx) FindInAssetArray(55, idx)
+#define kBufferCreditsBackgrounds_Layer2_IsBg g_asset_ptrs[56]
+#define kBufferCreditsBackgrounds_Layer2_IsBg_SIZE (g_asset_sizes[56])
+#define kLvlSprBlob(addr) FindPtrInAsset(57, addr)
+#define kLmSpritePtrBankByte g_asset_ptrs[58]
+#define kLmSpritePtrBankByte_SIZE (g_asset_sizes[58])
+#define kLoadLevel_SpriteDataPtrs ((uint16*)g_asset_ptrs[59])
+#define kLoadLevel_SpriteDataPtrs_SIZE (g_asset_sizes[59])
+#define kFileSelectText_EraseFile g_asset_ptrs[60]
+#define kFileSelectText_EraseFile_SIZE (g_asset_sizes[60])
+#define kInitializeMode7TilemapsAndPalettes_TilemapData g_asset_ptrs[61]
+#define kInitializeMode7TilemapsAndPalettes_TilemapData_SIZE (g_asset_sizes[61])
+#define kLayer2EventData_TileEntries ((uint16*)g_asset_ptrs[62])
+#define kLayer2EventData_TileEntries_SIZE (g_asset_sizes[62])
+#define kChangingLayer1OverworldTiles_Layer1TileLocation ((uint16*)g_asset_ptrs[63])
+#define kChangingLayer1OverworldTiles_Layer1TileLocation_SIZE (g_asset_sizes[63])
+#define kOwEventProcess01_DestroyTileAnimation_DATA_04E587 ((uint16*)g_asset_ptrs[64])
+#define kOwEventProcess01_DestroyTileAnimation_DATA_04E587_SIZE (g_asset_sizes[64])
+#define kCheckIfDestroyTileEventIsActive_DATA_04E5B6 ((uint16*)g_asset_ptrs[65])
+#define kCheckIfDestroyTileEventIsActive_DATA_04E5B6_SIZE (g_asset_sizes[65])
+#define kOwEventProcess01_DestroyTileAnimation_DATA_04D93D ((uint16*)g_asset_ptrs[66])
+#define kOwEventProcess01_DestroyTileAnimation_DATA_04D93D_SIZE (g_asset_sizes[66])
+#define kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles g_asset_ptrs[67]
+#define kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_SIZE (g_asset_sizes[67])
+#define kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileLayer g_asset_ptrs[68]
+#define kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileLayer_SIZE (g_asset_sizes[68])
+#define kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileNum ((uint16*)g_asset_ptrs[69])
+#define kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileNum_SIZE (g_asset_sizes[69])
+#define kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TilemapLocation ((uint16*)g_asset_ptrs[70])
+#define kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TilemapLocation_SIZE (g_asset_sizes[70])
+#define kOwDestruction_TileToIdx_04E5A7 g_asset_ptrs[71]
+#define kOwDestruction_TileToIdx_04E5A7_SIZE (g_asset_sizes[71])
+#define kOwDestruction_TopTile_04E5AC g_asset_ptrs[72]
+#define kOwDestruction_TopTile_04E5AC_SIZE (g_asset_sizes[72])
+#define kOwDestruction_BottomTile_04E5B1 g_asset_ptrs[73]
+#define kOwDestruction_BottomTile_04E5B1_SIZE (g_asset_sizes[73])
+#define kOwDestruction_TriggerEvent_04E5D6 g_asset_ptrs[74]
+#define kOwDestruction_TriggerEvent_04E5D6_SIZE (g_asset_sizes[74])
+#define kLmEventStuff1 ((uint16*)g_asset_ptrs[75])
+#define kLmEventStuff1_SIZE (g_asset_sizes[75])
+#define kLmEventStuff2 ((uint16*)g_asset_ptrs[76])
+#define kLmEventStuff2_SIZE (g_asset_sizes[76])
+#define kLmEventStuff3 ((uint16*)g_asset_ptrs[77])
+#define kLmEventStuff3_SIZE (g_asset_sizes[77])
+#define kLmEventStuff4 g_asset_ptrs[78]
+#define kLmEventStuff4_SIZE (g_asset_sizes[78])
+#define kOverworldLayer2EventTilemap_Tiles g_asset_ptrs[79]
+#define kOverworldLayer2EventTilemap_Tiles_SIZE (g_asset_sizes[79])
+#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap g_asset_ptrs[80]
+#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_SIZE (g_asset_sizes[80])
+#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop g_asset_ptrs[81]
+#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop_SIZE (g_asset_sizes[81])
+#define kOverworldLayer2EventTilemap_Prop g_asset_ptrs[82]
+#define kOverworldLayer2EventTilemap_Prop_SIZE (g_asset_sizes[82])
+#define kLoadOverworldLayer1AndEvents_DATA_0CF7DF g_asset_ptrs[83]
+#define kLoadOverworldLayer1AndEvents_DATA_0CF7DF_SIZE (g_asset_sizes[83])
+#define kRom g_asset_ptrs[84]
+#define kRom_SIZE (g_asset_sizes[84])
+#define kUpdateLevelName_LevelNameStrings g_asset_ptrs[85]
+#define kUpdateLevelName_LevelNameStrings_SIZE (g_asset_sizes[85])
+#define kGameMode25_ShowEnemyRollcallScreen_TileData g_asset_ptrs[86]
+#define kGameMode25_ShowEnemyRollcallScreen_TileData_SIZE (g_asset_sizes[86])
+#define kLmPalettes(idx) FindInAssetArray(87, idx)
+#define kPlayerGFXRt_HeadTilePointerIndex g_asset_ptrs[88]
+#define kPlayerGFXRt_HeadTilePointerIndex_SIZE (g_asset_sizes[88])
+#define kPlayerGFXRt_BodyTilePointerIndex g_asset_ptrs[89]
+#define kPlayerGFXRt_BodyTilePointerIndex_SIZE (g_asset_sizes[89])
+#define kLvlInitialFlags g_asset_ptrs[90]
+#define kLvlInitialFlags_SIZE (g_asset_sizes[90])
+#define kLoadOverworldSprites_SpriteSlotData g_asset_ptrs[91]
+#define kLoadOverworldSprites_SpriteSlotData_SIZE (g_asset_sizes[91])
+#define kChangingLayer1OverworldTiles_TilesThatChange g_asset_ptrs[92]
+#define kChangingLayer1OverworldTiles_TilesThatChange_SIZE (g_asset_sizes[92])
+#define kChangingLayer1OverworldTiles_TilesToBecome g_asset_ptrs[93]
+#define kChangingLayer1OverworldTiles_TilesToBecome_SIZE (g_asset_sizes[93])
+#define kOverworldEventProcess01_DestroyTileAnimation_DATA_04EE7A g_asset_ptrs[94]
+#define kOverworldEventProcess01_DestroyTileAnimation_DATA_04EE7A_SIZE (g_asset_sizes[94])
+#define kLevelTileAnimations_FrameData ((uint16*)g_asset_ptrs[95])
+#define kLevelTileAnimations_FrameData_SIZE (g_asset_sizes[95])
+#define kSetPlayerPose_WalkingPoseCount g_asset_ptrs[96]
+#define kSetPlayerPose_WalkingPoseCount_SIZE (g_asset_sizes[96])
+#define kDrawLoadingLetters_TileData g_asset_ptrs[97]
+#define kDrawLoadingLetters_TileData_SIZE (g_asset_sizes[97])
+#define kDrawLoadingLetters_TileData_BottomTiles g_asset_ptrs[98]
+#define kDrawLoadingLetters_TileData_BottomTiles_SIZE (g_asset_sizes[98])
+#define kDrawLoadingLetters_TileData_TopProp g_asset_ptrs[99]
+#define kDrawLoadingLetters_TileData_TopProp_SIZE (g_asset_sizes[99])
+#define kDrawLoadingLetters_TileData_BottomProp g_asset_ptrs[100]
+#define kDrawLoadingLetters_TileData_BottomProp_SIZE (g_asset_sizes[100])
+#define kOwTileAnimations_WaterTileNumbers ((uint16*)g_asset_ptrs[101])
+#define kOwTileAnimations_WaterTileNumbers_SIZE (g_asset_sizes[101])
+#define kOwTileAnimations_TileNumbers ((uint16*)g_asset_ptrs[102])
+#define kOwTileAnimations_TileNumbers_SIZE (g_asset_sizes[102])
+#define kOwStarPipeWarp_SrcX_048431 ((uint16*)g_asset_ptrs[103])
+#define kOwStarPipeWarp_SrcX_048431_SIZE (g_asset_sizes[103])
+#define kOwStarPipeWarp_SrcY_048467 ((uint16*)g_asset_ptrs[104])
+#define kOwStarPipeWarp_SrcY_048467_SIZE (g_asset_sizes[104])
+#define kOwStarPipeWarp_DstX_04849D ((uint16*)g_asset_ptrs[105])
+#define kOwStarPipeWarp_DstX_04849D_SIZE (g_asset_sizes[105])
+#define kOwStarPipeWarp_DstY_0484D3 ((uint16*)g_asset_ptrs[106])
+#define kOwStarPipeWarp_DstY_0484D3_SIZE (g_asset_sizes[106])
+#define kOwLevelsForcedMusicChange_048D74 ((uint16*)g_asset_ptrs[107])
+#define kOwLevelsForcedMusicChange_048D74_SIZE (g_asset_sizes[107])
+#define kOwSubmapMusic_048D8A g_asset_ptrs[108]
+#define kOwSubmapMusic_048D8A_SIZE (g_asset_sizes[108])
+#define kOw_KoopaKidTeleportXYPos_048E49 ((uint16*)g_asset_ptrs[109])
+#define kOw_KoopaKidTeleportXYPos_048E49_SIZE (g_asset_sizes[109])
+#define kOwTriggerSaveTiles_048F7F g_asset_ptrs[110]
+#define kOwTriggerSaveTiles_048F7F_SIZE (g_asset_sizes[110])
+#define kOwNoAutoMoveLevels_04906C ((uint16*)g_asset_ptrs[111])
+#define kOwNoAutoMoveLevels_04906C_SIZE (g_asset_sizes[111])
+#define kOwHardcodedPathLevel_049078 g_asset_ptrs[112]
+#define kOwHardcodedPathLevel_049078_SIZE (g_asset_sizes[112])
+#define kOwHardcodedPathChocolateIsland2_049082 ((uint16*)g_asset_ptrs[113])
+#define kOwHardcodedPathChocolateIsland2_049082_SIZE (g_asset_sizes[113])
+#define kOwHardcodedPathTiles_049086 g_asset_ptrs[114]
+#define kOwHardcodedPathTiles_049086_SIZE (g_asset_sizes[114])
+#define kOwHardcodedPathDirs_0490CA g_asset_ptrs[115]
+#define kOwHardcodedPathDirs_0490CA_SIZE (g_asset_sizes[115])
+#define kOwHardcodedPathStartIndex_04910E g_asset_ptrs[116]
+#define kOwHardcodedPathStartIndex_04910E_SIZE (g_asset_sizes[116])
+#define kOwExitLevelTiles_049426 g_asset_ptrs[117]
+#define kOwExitLevelTiles_049426_SIZE (g_asset_sizes[117])
+#define kUpdateLevelName_DATA_049C91 ((uint16*)g_asset_ptrs[118])
+#define kUpdateLevelName_DATA_049C91_SIZE (g_asset_sizes[118])
+#define kUpdateLevelName_DATA_049CCF ((uint16*)g_asset_ptrs[119])
+#define kUpdateLevelName_DATA_049CCF_SIZE (g_asset_sizes[119])
+#define kUpdateLevelName_DATA_049CED ((uint16*)g_asset_ptrs[120])
+#define kUpdateLevelName_DATA_049CED_SIZE (g_asset_sizes[120])
+#define kOwExitSource_049964 g_asset_ptrs[121]
+#define kOwExitSource_049964_SIZE (g_asset_sizes[121])
+#define kOwExitDest_0499AA g_asset_ptrs[122]
+#define kOwExitDest_0499AA_SIZE (g_asset_sizes[122])
+#define kOwExitExtra_0499F0 g_asset_ptrs[123]
+#define kOwExitExtra_0499F0_SIZE (g_asset_sizes[123])
+#define kOwExitLayerPosition_049A0C ((uint16*)g_asset_ptrs[124])
+#define kOwExitLayerPosition_049A0C_SIZE (g_asset_sizes[124])
+#define kOwUnknownTableA_From_04A03C g_asset_ptrs[125]
+#define kOwUnknownTableA_From_04A03C_SIZE (g_asset_sizes[125])
+#define kOwUnknownTableA_Alpha_04A054 ((uint16*)g_asset_ptrs[126])
+#define kOwUnknownTableA_Alpha_04A054_SIZE (g_asset_sizes[126])
+#define kOwUnknownTableA_XY_04A084 ((uint16*)g_asset_ptrs[127])
+#define kOwUnknownTableA_XY_04A084_SIZE (g_asset_sizes[127])
+#define kOwUnknownTableA_Direction_04A0E4 g_asset_ptrs[128]
+#define kOwUnknownTableA_Direction_04A0E4_SIZE (g_asset_sizes[128])
+#define kOwDirectionAfterBeatingLevel_04D678 g_asset_ptrs[129]
+#define kOwDirectionAfterBeatingLevel_04D678_SIZE (g_asset_sizes[129])
+#define kOwSubmapTileset_04DC02 g_asset_ptrs[130]
+#define kOwSubmapTileset_04DC02_SIZE (g_asset_sizes[130])
+#define kLayer2EventData_Ptrs_04E359 ((uint16*)g_asset_ptrs[131])
+#define kLayer2EventData_Ptrs_04E359_SIZE (g_asset_sizes[131])
+#define kLmInitSaveData g_asset_ptrs[132]
+#define kLmInitSaveData_SIZE (g_asset_sizes[132])
+#define kInitializeSaveData_InitialOWPlayerPos g_asset_ptrs[133]
+#define kInitializeSaveData_InitialOWPlayerPos_SIZE (g_asset_sizes[133])
+#define kOWSpr07_Smoke_DATA_04FC1E ((uint16*)g_asset_ptrs[134])
+#define kOWSpr07_Smoke_DATA_04FC1E_SIZE (g_asset_sizes[134])
+#define kLoadOverworldSprites_SubmapBooXPosOffset ((uint16*)g_asset_ptrs[135])
+#define kLoadOverworldSprites_SubmapBooXPosOffset_SIZE (g_asset_sizes[135])
+#define kLoadOverworldSprites_SubmapBooYPosOffset ((uint16*)g_asset_ptrs[136])
+#define kLoadOverworldSprites_SubmapBooYPosOffset_SIZE (g_asset_sizes[136])
+#define kLoadLevelHeader_LevelMusicTable g_asset_ptrs[137]
+#define kLoadLevelHeader_LevelMusicTable_SIZE (g_asset_sizes[137])
+#define kLevelsThatTriggerCutscenes g_asset_ptrs[138]
+#define kLevelsThatTriggerCutscenes_SIZE (g_asset_sizes[138])
+#define kLmExgfx(idx) FindInAssetArray(139, idx)
+#define kLmSuperExgfx(idx) FindInAssetArray(140, idx)
+#define kLmGraphicsRemapped g_asset_ptrs[141]
+#define kLmGraphicsRemapped_SIZE (g_asset_sizes[141])
+#define kLmModifyMap16Ids ((uint16*)g_asset_ptrs[142])
+#define kLmModifyMap16Ids_SIZE (g_asset_sizes[142])
+#define kLm5DE00 g_asset_ptrs[143]
+#define kLm5DE00_SIZE (g_asset_sizes[143])
+#define kLm6FC00 g_asset_ptrs[144]
+#define kLm6FC00_SIZE (g_asset_sizes[144])
+#define kLm6FE00 g_asset_ptrs[145]
+#define kLm6FE00_SIZE (g_asset_sizes[145])
+#define kLm10B8BC g_asset_ptrs[146]
+#define kLm10B8BC_SIZE (g_asset_sizes[146])
+#define kLmLevelData3FE00 g_asset_ptrs[147]
+#define kLmLevelData3FE00_SIZE (g_asset_sizes[147])
+#define kLmLevelData5DC85 g_asset_ptrs[148]
+#define kLmLevelData5DC85_SIZE (g_asset_sizes[148])
+#define kLmLevelData5DC8A g_asset_ptrs[149]
+#define kLmLevelData5DC8A_SIZE (g_asset_sizes[149])
+#define kLm5FE00 g_asset_ptrs[150]
+#define kLm5FE00_SIZE (g_asset_sizes[150])
+#define kLevelInfo_05F800 g_asset_ptrs[151]
+#define kLevelInfo_05F800_SIZE (g_asset_sizes[151])
+#define kLevelInfo_05FA00 g_asset_ptrs[152]
+#define kLevelInfo_05FA00_SIZE (g_asset_sizes[152])
+#define kLevelInfo_05FC00 g_asset_ptrs[153]
+#define kLevelInfo_05FC00_SIZE (g_asset_sizes[153])
+#define kMap16_0 ((uint16*)g_asset_ptrs[154])
+#define kMap16_0_SIZE (g_asset_sizes[154])
+#define kMap16_1 ((uint16*)g_asset_ptrs[155])
+#define kMap16_1_SIZE (g_asset_sizes[155])
+#define kMap16_2 ((uint16*)g_asset_ptrs[156])
+#define kMap16_2_SIZE (g_asset_sizes[156])
+#define kMap16_3 ((uint16*)g_asset_ptrs[157])
+#define kMap16_3_SIZE (g_asset_sizes[157])
+#define kMap16_4 ((uint16*)g_asset_ptrs[158])
+#define kMap16_4_SIZE (g_asset_sizes[158])
+#define kMap16_5 ((uint16*)g_asset_ptrs[159])
+#define kMap16_5_SIZE (g_asset_sizes[159])
+#define kMap16_6 ((uint16*)g_asset_ptrs[160])
+#define kMap16_6_SIZE (g_asset_sizes[160])
+#define kMap16_7 ((uint16*)g_asset_ptrs[161])
+#define kMap16_7_SIZE (g_asset_sizes[161])
+#define kMap16_TS ((uint16*)g_asset_ptrs[162])
+#define kMap16_TS_SIZE (g_asset_sizes[162])
+#define kLmLvlExAnim g_asset_ptrs[163]
+#define kLmLvlExAnim_SIZE (g_asset_sizes[163])
+#define kLmExanimBlob(addr) FindPtrInAsset(164, addr)
+#define kLmOverworldPal g_asset_ptrs[165]
+#define kLmOverworldPal_SIZE (g_asset_sizes[165])
+#define kLmDisplayMessage_Tab0 g_asset_ptrs[166]
+#define kLmDisplayMessage_Tab0_SIZE (g_asset_sizes[166])
+#define kLmDisplayMessage_3BC7F ((uint16*)g_asset_ptrs[167])
+#define kLmDisplayMessage_3BC7F_SIZE (g_asset_sizes[167])
+#define kLmDisplayMessage_3BE80 ((uint16*)g_asset_ptrs[168])
+#define kLmDisplayMessage_3BE80_SIZE (g_asset_sizes[168])
+#define kLmDisplayMessage_Tab1 g_asset_ptrs[169]
+#define kLmDisplayMessage_Tab1_SIZE (g_asset_sizes[169])
+#define kLmTitleScreenMoves g_asset_ptrs[170]
+#define kLmTitleScreenMoves_SIZE (g_asset_sizes[170])
+#define kLmLevelNamesPatch g_asset_ptrs[171]
+#define kLmLevelNamesPatch_SIZE (g_asset_sizes[171])
+#define kOwLayer1AndEvents g_asset_ptrs[172]
+#define kOwLayer1AndEvents_SIZE (g_asset_sizes[172])
+#define kOwLayer1AndEvents2 g_asset_ptrs[173]
+#define kOwLayer1AndEvents2_SIZE (g_asset_sizes[173])
+#define kLmLvlInfo ((uint16*)g_asset_ptrs[174])
+#define kLmLvlInfo_SIZE (g_asset_sizes[174])
+#define kLmCustomMap16Bg(idx) FindInAssetArray(175, idx)
+#define kLmSprExtraSize g_asset_ptrs[176]
+#define kLmSprExtraSize_SIZE (g_asset_sizes[176])
+#define kLmFeatures g_asset_ptrs[177]
+#define kLmFeatures_SIZE (g_asset_sizes[177])
+#define kAssets_Sig 83, 109, 119, 95, 118, 48, 32, 32, 32, 32, 32, 32, 32, 32, 10, 0, 85, 177, 205, 26, 249, 0, 56, 113, 186, 11, 242, 196, 157, 30, 113, 190, 86, 157, 53, 15, 96, 246, 11, 95, 59, 106, 128, 210, 127, 126, 117, 134
diff --git a/assets/util.py b/assets/util.py
index 6a6e4a7..b3304ca 100644
--- a/assets/util.py
+++ b/assets/util.py
@@ -16,9 +16,9 @@ SMW_SHA1 = {
SMW_SHA1_US : ('us', 'Super Mario World (USA)'),
}
-def load_rom(filename, support_multilanguage = False):
+def load_rom(filename, support_multilanguage = False, disable_hash_check = False):
global ROM
- ROM = LoadedRom(filename, support_multilanguage)
+ ROM = LoadedRom(filename, support_multilanguage, disable_hash_check)
return ROM
def get_byte(addr):
@@ -50,7 +50,7 @@ def get_word(addr):
class LoadedRom:
- def __init__(self, path = None, support_multilanguage = False):
+ def __init__(self, path = None, support_multilanguage = False, disable_hash_check = False):
rom_path = self.__get_rom_path(path)
self.ROM = open(rom_path, 'rb').read()
@@ -62,16 +62,8 @@ class LoadedRom:
entry = SMW_SHA1.get(hash)
self.language = entry[0] if entry != None else None
- if support_multilanguage:
- if self.language == None:
- msg = f"\n\nROM with hash {hash} not supported.\n\nYou need one of the following ROMs to extract the resources:\n"
- for k, v in SMW_SHA1.items():
- msg += '%5s: %s: %s\n' % (v[0], k, v[1])
- raise Exception(msg)
- print('Identified ROM as: %s - "%s"' % entry)
- else:
- if self.language != 'us':
- raise Exception(f"\n\nROM with hash {hash} not supported.\n\nExpected {SMW_SHA1_US}.\nPlease verify your ROM is \"Super Mario World\"");
+ if not disable_hash_check and self.language != 'us':
+ raise Exception(f"\n\nROM with hash {hash} not supported.\n\nExpected {SMW_SHA1_US}.\nPlease verify your ROM is \"Super Mario World\".\n\nIf you want to use a LunarMagic edited rom you can run restool with -f to bypass this check.");
def get_byte(self, ea):
assert (ea & 0x8000)
diff --git a/run_with_tcc.bat b/run_with_tcc.bat
index d9fa369..fb21296 100644
--- a/run_with_tcc.bat
+++ b/run_with_tcc.bat
@@ -33,7 +33,7 @@ IF ERRORLEVEL 1 goto GETOUT
copy %SDL2%\lib\x64\SDL2.dll .
echo Running...
-smw.exe smw.sfc
+smw.exe
:GETOUT
pause
diff --git a/src/common_cpu_infra.c b/src/common_cpu_infra.c
index e248fd8..7c0ebd8 100644
--- a/src/common_cpu_infra.c
+++ b/src/common_cpu_infra.c
@@ -106,6 +106,7 @@ int CpuOpcodeHook(uint32 addr) {
int i = RunPatchBugHook(addr);
if (i >= 0) return i;
}
+ printf("Bad hook at 0x%x!\n", addr);
assert(0);
return 0;
}
@@ -126,7 +127,7 @@ static void VerifySnapshotsEq(Snapshot *b, Snapshot *a, Snapshot *prev) {
int j = 0;
for (size_t i = 0; i < 0x20000; i++) {
if (a->ram[i] != b->ram[i]) {
- if (++j < 256) {
+ if (++j < 256*10) {
if (((i & 1) == 0 || i < 0x10000) && a->ram[i + 1] != b->ram[i + 1]) {
fprintf(stderr, "0x%.6X: %.4X != %.4X (%.4X)\n", (int)i,
WORD(b->ram[i]), WORD(a->ram[i]), WORD(prev->ram[i]));
@@ -253,7 +254,7 @@ Snes *SnesInit(const uint8 *data, int data_size) {
RtlSetupEmuCallbacks(NULL, &RtlRunFrameCompare, NULL);
- if (data_size != 0) {
+ if (data_size != 0 && g_runmode != RM_MINE) {
bool loaded = snes_loadRom(g_snes, data, data_size);
if (!loaded) {
return NULL;
@@ -277,6 +278,7 @@ Snes *SnesInit(const uint8 *data, int data_size) {
printf("0x%x double patched!\n", g_rtl_game_info->patch_carrys[i]);
}
}
+ g_rtl_game_info->initialize();
PatchBugs(1, 0);
} else {
g_runmode = RM_MINE;
@@ -291,7 +293,7 @@ Snes *SnesInit(const uint8 *data, int data_size) {
g_sram = g_snes->cart->ram;
g_sram_size = g_snes->cart->ramSize;
game_id = g_rtl_game_info->game_id;
- g_rtl_game_info->initialize();
+
return g_snes;
}
@@ -305,12 +307,15 @@ void SaveBugSnapshot() {
g_got_mismatch_count = 5 * 60;
}
+int g_dbg_ctr_mine, g_dbg_ctr_theirs;
+
void RunOneFrameOfGame_Both(void) {
g_ppu = g_snes->ppu;
MakeSnapshot(&g_snapshot_before);
// Run orig version then snapshot
again_theirs:
+ g_dbg_ctr_mine = g_dbg_ctr_theirs = 0;
g_snes->runningWhichVersion = 1;
g_rtl_game_info->run_frame_emulated();
MakeSnapshot(&g_snapshot_theirs);
diff --git a/src/common_rtl.c b/src/common_rtl.c
index bd292ab..05fbadc 100644
--- a/src/common_rtl.c
+++ b/src/common_rtl.c
@@ -24,6 +24,7 @@ uint8 game_id;
bool g_playback_mode;
Ppu *g_ppu, *g_my_ppu;
Dma *g_dma;
+bool g_custom_music;
static uint8 *g_rtl_memory_ptr;
static RunFrameFunc *g_rtl_runframe;
@@ -708,8 +709,10 @@ static void RtlResetApuQueue_Locked(void) {
void RtlApuUpload(const uint8 *p) {
RtlApuLock();
- g_spc_player->upload(g_spc_player, p);
- RtlResetApuQueue_Locked();
+ if (!g_custom_music) {
+ g_spc_player->upload(g_spc_player, p);
+ RtlResetApuQueue_Locked();
+ }
RtlApuUnlock();
}
@@ -823,6 +826,12 @@ void SmwCopyToVramLow(uint16 vram_addr, const uint8 *src, int n) {
g_ppu->vram[vram_addr + i] = (g_ppu->vram[vram_addr + i] & 0xff00) | src[i];
}
+void SmwCopyFromVram(uint16 vram_addr, uint8 *dst, int n) {
+ for (size_t i = 0; i < (n >> 1); i++)
+ WORD(dst[i * 2]) = g_ppu->vram[vram_addr + i];
+}
+
+
void RtlUpdatePalette(const uint16 *src, int dst, int n) {
for(int i = 0; i < n; i++)
g_ppu->cgram[dst + i] = src[i];
@@ -926,44 +935,3 @@ void SimpleHdma_DoLine(SimpleHdma *c) {
}
c->rep_count--;
}
-
-
-void LoadStripeImage_UploadToVRAM(const uint8 *pp) { // 00871e
- while (1) {
- if ((*pp & 0x80) != 0)
- break;
- uint16 vram_addr = pp[0] << 8 | pp[1];
- uint8 vmain = __CFSHL__(pp[2], 1);
- uint8 fixed_addr = (uint8)(pp[2] & 0x40) >> 3;
- uint16 num = (swap16(WORD(pp[2])) & 0x3FFF) + 1;
- uint16 *dst = g_ppu->vram + vram_addr;
- pp += 4;
-
- if (fixed_addr) {
- uint16 src_data = WORD(*pp);
- int ctr = (num + 1) >> 1;
- if (vmain) {
- for (int i = 0; i < ctr; i++)
- dst[i * 32] = src_data;
- } else {
- // uhm...?
- uint8 *dst_b = (uint8 *)dst;
- for (int i = 0; i < num; i++)
- dst_b[i + ((i & 1) << 1)] = src_data;
- for (int i = 0; i < num; i += 2)
- dst_b[i + 1] = src_data >> 8;
- }
- pp += 2;
- } else {
- uint16 *src = (uint16 *)pp;
- if (vmain) {
- for (int i = 0; i < (num >> 1); i++)
- dst[i * 32] = src[i];
- } else {
- for (int i = 0; i < (num >> 1); i++)
- dst[i] = src[i];
- }
- pp += num;
- }
- }
-}
diff --git a/src/common_rtl.h b/src/common_rtl.h
index 79e2cc1..a8ec55f 100644
--- a/src/common_rtl.h
+++ b/src/common_rtl.h
@@ -87,6 +87,8 @@ static inline const uint8 *RomPtr_0C(uint16_t addr) { return RomPtr(0x0c0000 | a
static inline const uint8 *RomPtr_0D(uint16_t addr) { return RomPtr(0x0d0000 | addr); }
static inline const uint8 *RomPtr_0E(uint16_t addr) { return RomPtr(0x0e0000 | addr); }
static inline const uint8 *RomPtr_0F(uint16_t addr) { return RomPtr(0x0f0000 | addr); }
+static inline const uint8 *RomPtr_11(uint16_t addr) { return RomPtr(0x110000 | addr); }
+static inline const uint8 *RomPtr_12(uint16_t addr) { return RomPtr(0x120000 | addr); }
static inline const uint8 *RomPtrWithBank(uint8 bank, uint16_t addr) { return RomPtr((bank << 16) | addr); }
uint16 Mult8x8(uint8 a, uint8 b);
diff --git a/src/consts.h b/src/consts.h
index 9ec2d0a..cf6d514 100644
--- a/src/consts.h
+++ b/src/consts.h
@@ -1,14 +1,8 @@
#include "types.h"
-extern const uint16 kLevelTileAnimations_FrameData[208];
extern const uint8 kSlopeDataTables_SlopeType[33];
extern const uint8 kSlopeDataTables_ShapeOfSlope[512];
-extern const uint8 kLevelDataLayoutTables_EightBitLo_Horizontal[32];
-extern const uint8 kLevelDataLayoutTables_EightBitLo_Vertical[28];
-extern const uint8 kLevelDataLayoutTables_EightBitHi_Horizontal[32];
-extern const uint8 kLevelDataLayoutTables_EightBitHi_Vertical[28];
-
extern const uint16 kGlobalPalettes_Bowser[56];
extern const uint16 kGlobalPalettes_Background[];
@@ -16,7 +10,6 @@ extern const uint8 kGameModeXX_FadeInOrOut_DATA_009F2F[2];
extern const uint8 kGameModeXX_FadeInOrOut_DATA_009F31[2];
extern const uint8 kGameModeXX_FadeInOrOut_DATA_009F33[2];
-extern const uint16 kGlobalPalettes_Sky[8];
extern const uint8 kGameMode19_Cutscene_SkyColorSetting[8];
extern const uint8 kGenericSpriteToSpawnTable[19];
@@ -30,4 +23,7 @@ extern const uint8 kBitTable_Bank05[8];
extern const uint8 kInitializeNormalSpriteRAMTables_Sprite190FVals[201];
extern const uint16 kCircleCoordinates[256];
+extern const uint16 kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[4];
+extern const uint16 kDisplayMessage_SwitchBlockTileAndProperties[32];
+extern const uint8 kDisplayMessage_SwitchBlockXAndYDisp[16];
diff --git a/src/funcs.h b/src/funcs.h
index d7e96c4..43e72a4 100644
--- a/src/funcs.h
+++ b/src/funcs.h
@@ -1,3 +1,6 @@
+#ifndef SMW_FUNCS_H_
+#define SMW_FUNCS_H_
+
#include "smw_rtl.h"
typedef struct CollInfo {
@@ -29,6 +32,7 @@ typedef struct CheckPlatformCollRet {
const uint16 *GetLayerLayoutPtr(int layer, int top);
const uint16 *GetPlayerPalette();
const uint16 *GetMap16RomAddr(uint8 bank, uint16_t addr);
+const uint16 *Lm_GetMap16RomAddr(uint16 addr);
// Bank 0
PairU16 BufferFileSelectText_009DB5(uint8 k);
@@ -148,9 +152,9 @@ void GenericPage01Tile_00C0FB(GenTileArgs *gta, uint16 j);
void GenericPage01Tile(GenTileArgs *gta);
void GenericPage01Tile_Return00C1AB(void);
void GenericPage01Tile_SetItemMemory(GenTileArgs *gta);
-void GraphicsDecompressTo(const uint8 *src, uint8 *pdst);
+int DecompressTo(const uint8 *src, uint8 *pdst);
void GraphicsDecompressionRoutines_DecompressGFX32And33(void);
-const uint8 *GraphicsDecompress(uint8 j);
+uint8 *GraphicsDecompress(uint8 j);
void HandleMenuCursor_009E82(uint8 j);
void HandleMenuCursor_009ED4(uint8 k);
void HandlePaletteFades_00AF35(bool run_code_at_end);
@@ -326,7 +330,7 @@ void UploadBigLayer3LettersToVRAM(void);
void ConvertGFX27IntoNormallFormat(uint16 *dst);
void UploadGraphicsFiles_Layer3(void);
void UploadGraphicsFiles(void);
-void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j);
+void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j, uint8 index);
void UploadLevelExAnimationData(void);
void UploadLevelAnimations_RedFlash(uint8 a, uint8 r0);
void UploadLevelAnimations_YellowFlash(uint8 a);
@@ -685,7 +689,7 @@ void Spr0A5_Sparky(uint8 k);
void Spr0A7_IggyBall(uint8 k);
void Spr0A9_Reznor_Init(uint8 k);
void Spr0AA_Fishbone_Init(uint8 k);
-void Spr0A0_ActivateBowserBattle(uint8 k);
+void HandleExtraSprites(uint8 k);
void Spr0AC_DownFirstWoodenSpike_Init(uint8 k);
void Spr0AD_UpDownFirstWoodenSpike_Init(uint8 k);
void Spr0B1_CreateEatBlock_Init(uint8 k);
@@ -980,7 +984,8 @@ void MExtSpr0A_BooStream(uint8 k);
void MExtSpr0B_UnusedYoshiSmoke(uint8 k);
void MExtSpr_Delete(uint8 k);
void ParseLevelSpriteList_Entry2(void);
-void ParseLevelSpriteList_LoadSpriteLoopStrt(uint8 k, uint8 j, uint16 r0w);
+bool LoadOneSprite(const uint8 *p, uint8 k, PointU16 pt);
+void ParseLevelSpriteList_LoadSpriteLoopStrt(uint8 k, uint8 j, PointU16 pt);
void ParseLevelSpriteList(void);
void ProcessBounceAndSmokeSprites_BounceSprites(uint8 k);
void ProcessBounceAndSmokeSprites(void);
@@ -1163,15 +1168,15 @@ void Spr09F_BanzaiBill_Draw(uint8 k);
void Spr09F_BanzaiBill_Sub(uint8 k);
PointU8 Spr0A3_GreyChainedPlatform_02D813(uint8 k);
PointU8 Spr0A3_GreyChainedPlatform_02D848(uint8 k);
-void Spr0DE_Load5Eeries(uint8 k, uint16 r0w, uint8 r2, const uint8 *edata);
-void Spr0E0_Load3Platforms(uint16 r0w, uint8 r2, const uint8 *edata);
-void Spr0E1_LoadBooCeiling(uint8 k, uint8 a, uint16 r0w, uint8 r2, const uint8 *edata);
+void Spr0DE_Load5Eeries(uint8 k, PointU16 pt, uint8 r2, const uint8 *edata);
+void Spr0E0_Load3Platforms(PointU16 pt, uint8 r2, const uint8 *edata);
+void Spr0E1_LoadBooCeiling(uint8 k, uint8 a, PointU16 pt, uint8 r2, const uint8 *edata);
void SprXXX_Dolphins(uint8 k);
void SprXXX_Dolphins_Draw(uint8 k);
void SprXXX_JumpingPiranhaPlant_02E17F(uint8 k);
void SprXXX_JumpingPiranhaPlant_02E1C0(uint8 k, uint8 a);
void Spr04F_JumpingPiranhaPlant(uint8 k);
-void SprXXX_LoadShooter(uint8 k, uint8 a, uint16 r0w, const uint8 *edata);
+void SprXXX_LoadShooter(uint8 k, uint8 a, PointU16 pt, const uint8 *edata);
void SprXXX_SuperKoopas_02EB3D(uint8 k, uint8 j);
void SprXXX_SuperKoopas_02EBB5(uint8 k, uint8 r0);
void SprXXX_SuperKoopas_02EBCA(uint8 k);
@@ -1278,7 +1283,7 @@ void Spr07C_PrincessPeach_StandByBro(uint8 k);
void Spr07C_PrincessPeach_WaitAfterFall(uint8 k);
void Spr07C_PrincessPeach_WalkTowardsBro(uint8 k);
void Spr0A0_ActivateBowserBattle_Init(uint8 k);
-void Spr0A0_ActivateBowserBattle(uint8 k);
+void HandleExtraSprites(uint8 k);
void Spr0A0_ActivateBowserBattle_03A4D2(uint8 k);
void Spr0A0_ActivateBowserBattle_03A4ED(uint8 k);
void Spr0A0_ActivateBowserBattle_03A4FD(uint8 k);
@@ -1486,7 +1491,7 @@ void OWSpr0A_Boo_04FDD2(uint8 k, uint8 a, uint8 r0);
void OWSpr0A_Boo(uint8 k);
void OwEventProcess00_CheckIfEventShouldRun(void);
void OwEventProcess01_DestroyTileAnimation_04ED83(void);
-void OwEventProcess01_DestroyTileAnimation_04EDE6(uint16 k, uint16 j, uint16 r0w, const uint8 *p);
+void OwEventProcess01_DestroyTileAnimation_04EDE6(uint16 k, uint16 r0w, const uint8 *p);
void OwEventProcess01_DestroyTileAnimation_04EEAA(void);
void OwEventProcess02_SetEventTileIndexes(void);
void OwEventProcess03_GetLayer2Tile_04EA62(void);
@@ -1496,7 +1501,7 @@ void OwEventProcess04_FadeInLayer2Tile_04EE30(void);
void OwEventProcess04_FadeInLayer2Tile(void);
void OwEventProcess05_GetLayer1Tile(void);
void OwEventProcess06_FadeInLayer1Tile(void);
-void OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(uint8 a);
+void OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(uint8 a, bool from_where);
void OwEventProcess07_SilentEventsAndEndOfEvent(void);
void OverworldLightningAndRandomCloudSpawning(void);
void OverworldLightningAndRandomCloudSpawning_Return04F828(uint8 k);
@@ -1615,7 +1620,7 @@ void ScrollSecondInteractiveLayer(void);
void ShowCourseClearText(void);
void LoadLevel_05DBAC(void);
void LoadLevel_HandleChocolateIsland2Gimmick(void);
-void LoadLevel(void);
+bool LoadLevel(void);
void Spr0E7_SpecialAutoScroll_Layer2(void);
void Spr0E7_SpecialAutoScroll(void);
void Spr0E9_Layer2Smash(void);
@@ -1956,4 +1961,177 @@ void UndergroundObj3C_VerySteepSlope_VerySteepLeftSlope(void);
void UndergroundObj3C_VerySteepSlope_VerySteepRightSlope(void);
void UndergroundObj3D_CeilingLedge(uint8 k);
void UndergroundObj3E_CeilingEdges(uint8 k);
-void UndergroundObj3F_SolidDirt(uint8 k);
\ No newline at end of file
+void UndergroundObj3F_SolidDirt(uint8 k);
+
+void LmStdObj22_DirectMap16(uint8 k);
+void LmStdObj23(uint8 k);
+void LmStdObj24(uint8 k);
+void LmStdObj25(uint8 k);
+void LmStdObj26_MusicBypass(uint8 k);
+void LmStdObj27(uint8 k);
+void LmStdObj28(uint8 k);
+void LmStdObj29(uint8 k);
+
+void LmHook_InitExanimForLevel(void);
+void LmHook_UploadLevelAnimations(void);
+void LmHook_BeginLoadingLevelDataB(void);
+void LmHook_PrepareLevel(void);
+void LmFunc1_CustomPalettes(int a);
+void LmHook_UploadGraphicsFiles(void);
+uint8 LmFunc15_DecompressSlot(uint8 a);
+void LmGraphicsDecompress(uint16 a);
+
+const uint8 *LmHook_UploadGFXFile(uint8 a, uint8 index);
+
+uint8 LmFunc18_GetFF200(uint8 a, uint8 k);
+
+uint8 LmHook_ModifyMap16IDForSpecialBlocks(uint8 a);
+uint8 LmFunc20_ModifyMap16IDForSpecialBlocks(uint8 a);
+
+uint8 *LmHook_GraphicsDecompress(uint8 a);
+void LmHandleDirectMapObjs(uint8 a);
+
+void LmHook_LoadSpritesOnLevelLoad(void);
+void LmHook_LoadLevelInfo(void);
+void LmHook_BufferCreditsBackgrounds(void);
+void LmHook_LoadLevel(uint16 j);
+void LmHook_LoadLevelB(const uint8 *ptr_layer1_data, uint8 R2, uint16 level_number);
+uint16 LmFunc_InitScreenTables(int k, int a);
+void LmHook_HandleStandardLevelCameraScroll(void);
+bool LmHook_GameMode11_LoadSublevel(void);
+
+void LmHook_UploadLevelLayer1And2Tilemaps(void);
+
+void LmHook_BE8A(uint16 xbase);
+
+void LmHook_PreserveLevelDataPointerInObjects(void);
+void LmHook_RestoreLevelDataPointerInObjects(void);
+uint8 LmHook_HandleHorizontalSubScreenCrossingForCurrentObject_Entry2(void);
+uint8 LmHook_HandleVerticalSubScreenCrossingForCurrentObject(void);
+void LmFunc_DF1C3(uint8 k, uint8 a);
+
+void LmHook_InitializeLevelLayer1And2Tilemaps(void);
+void LmHook_CheckIfLevelTilemapsNeedScrollUpdate(void);
+
+void LmHook_BufferTilemap_L1(void);
+void LmHook_BufferTilemap_L2(void);
+void LmHook_UploadLevelLayer1And2Tilemaps(void);
+
+void Lm_BufferTilemap_L1_0(void);
+void Lm_BufferTilemap_L1_1(void);
+void LmHook_BufferScrollingTiles_L2_Background(void);
+void LmHook_BufferScrollingTiles_L2_1(void);
+void LmHook_BufferScrollingTiles_L2_7(void);
+void LmHook_BufferScrollingTiles_L2_7(void);
+void LmFunc_UpdateTilemapA_0(void);
+void LmFunc_UpdateTilemapB_0(void);
+void LmFunc_UpdateTilemapB_7(void);
+void LmFunc_UpdateTilemapC_0(void);
+void LmFunc_UpdateTilemapD_0(void);
+void LmFunc_UpdateTilemapD_1(void);
+void LmFunc_UpdateTilemapD_2(void);
+
+void Lm_CopyTilesToL1UploadBuffer(const uint8 *plo, const uint8 *phi, uint16 j, uint16 r6);
+void Lm_SetupLmVramDma_0(void);
+void Lm_SetupLmVramDma_6(void);
+void Lm_SetupLmVramDma_12(void);
+void Lm_SetupLmVramDma_16(void);
+void Lm_SetupPipeTiles(uint16 a);
+const uint16 *Lm_GetMap16RomAddr(uint16 a);
+
+uint16 *LmHook_CustomBgMap16(void);
+void Lm_CopyToVramBufD_6(const uint8 *plo, const uint8 *phi, uint16 j, const uint16 *ptile);
+void Lm_SetupLmVramDma_6(void);
+
+void LmHook_LevelTileAnimations(void);
+
+typedef struct ParseTileAnimCtx {
+ const uint8 *p, *porg;
+ uint8 *r8;
+ uint8 r10;
+ LongPtr ptr;
+} ParseTileAnimCtx;
+
+void LmFunc_10C713(LongPtr p, uint16 r8, uint8 r10, uint16 k);
+
+void LmHook_SetStandardPPUSettings(void);
+void LmHook_HandleStandardLevelCameraScrollB(void);
+void LmHook_HandleStandardLevelCameraScrollC(void);
+uint16 LmHook_HandleStandardLevelCameraScrollD(void);
+uint16 LmHook_HandleStandardLevelCameraScrollG(uint16 r2, uint16 r4);
+uint16 LmHook_LoadStripeImage(uint16 r3);
+
+void LmHook_GameMode0C_LoadOverworld(uint16 k);
+
+const uint16 *LmHook_TileGen(uint16 j);
+bool LmHook_WantEraseSprite(uint16 k, uint16 y);
+void LmHook_OwGraphicsDecompress(void);
+
+uint16 LmHook_LoadLevelInfo_A(uint16 a, uint16 k);
+uint16 LmHook_LoadLevelInfo_C(uint16 a);
+
+void LmHook_ExpandLvlHdr(uint16 lvl);
+
+bool LmHook_CustomTitleScreenDemo(void);
+void LmHook_InitializeSaveData(void);
+void LmHook_DisplayMessage(void);
+void LmHook_OverworldPalette(void);
+void LmHook_LevelNamesPatch(uint16 a);
+int LmHook_LoadLevelInfo_E(uint16 k, uint16 lvl, uint8 r0, uint8 r1);
+
+uint16 LmHook_DestroyTileAnimation2(uint16 a);
+const uint8* LmHook_DestroyTileAnimation3(uint16 k);
+uint16 LmHook_RemapDestroyTile(uint16 a);
+
+void LmHook_EventStuff(uint8 a, bool from_where);
+
+void LmFunc_UploadGraphics_StepA(void);
+void LmFunc_UpdateBG12NBA(void);
+void LmHook_InitializeLevelLayer3_GenerateInteractiveTideWater(void);
+
+uint16 GetLevelLayoutPtr_Vertical(int i);
+uint16 GetLevelLayoutPtr_Horizontal(int i);
+
+enum {
+ kLmFeature_LmEnabled = 1 << 0,
+ kLmFeature_Exanim = 1 << 1,
+ kLmFeature_SkipOverworldDecompress = 1 << 2,
+ kLmFeature_OverworldTiles4bpp = 1 << 3,
+ kLmFeature_Copy512colors = 1 << 4,
+ kLmFeature_WeirdPalette = 1 << 5,
+ kLmFeature_SkipLoadPaletteHook = 1 << 6,
+ kLmFeature_GfxUpload = 1 << 7,
+ kLmFeature_LoadLevel = 1 << 8,
+ kLmFeature_4bppgfx = 1 << 9,
+ kLmFeature_CustomTitleScreenDemo = 1 << 10,
+ kLmFeature_CustomDisplayMessage = 1 << 11,
+ kLmFeature_DontSetYposForIntroMarch = 1 << 12,
+ kLmFeature_OwPalette = 1 << 13,
+ kLmFeature_LevelNamesPatch = 1 << 14,
+ kLmFeature_DestroyTileAnims = 1 << 15,
+ kLmFeature_EventStuff = 1 << 16,
+ kLmFeature_MusicRegTweak = 1 << 17,
+ kLmFeature_TideWaterTweak = 1 << 18,
+ kLmFeature_EnemyCollTweak = 1 << 19,
+ kLmFeature_Ow4bppGfx = 1 << 20,
+};
+
+// Non lunar magic hacks
+enum {
+ kHack_Walljump = 1 << 0,
+};
+
+typedef struct LmFeatures {
+ uint32 flags;
+ uint32 kLmLvlInfo_addr;
+ uint32 kLmLvlInfo_addr_other;
+ uint32 hacks;
+} LmFeatures;
+
+#define LM_FEATURES ((LmFeatures *)kLmFeatures)
+#define HAS_LM_FEATURE(i) ((LM_FEATURES->flags & (i)) != 0)
+#define HAS_HACK(i) ((LM_FEATURES->hacks & (i)) != 0)
+
+void HackHandleWalljump();
+
+#endif // SMW_FUNCS_H_
\ No newline at end of file
diff --git a/src/lm.c b/src/lm.c
new file mode 100644
index 0000000..8329cfb
--- /dev/null
+++ b/src/lm.c
@@ -0,0 +1,2513 @@
+#include "consts.h"
+#include "funcs.h"
+#include "smw_rtl.h"
+#include "variables.h"
+#include "assets/smw_assets.h"
+#include "snes/ppu.h"
+
+void LmHook_InitExanimForLevel(void) {
+ if (!HAS_LM_FEATURE(kLmFeature_Exanim))
+ return;
+
+ lm_var19 = 0xff;
+ lm_varA = 0;
+ lm_one_shot_triggers = 0;
+ ex_anim_info_0.hdr_size = 0;
+ ex_anim_info_1.hdr_size = 0;
+ ex_anim_info_2.hdr_size = 0;
+ ex_anim_info_3.hdr_size = 0;
+ ex_anim_info_4.hdr_size = 0;
+ ex_anim_info_5.hdr_size = 0;
+ ex_anim_info_6.hdr_size = 0;
+ ex_anim_info_7.hdr_size = 0;
+
+ WORD(lm_var3) = 0xffff;
+ for (int i = 0; i < 32; i++)
+ lm_exanim_frame_ctr[i] = 0xffff;
+
+ if (lunar_magic_FE) {
+ lm_varA |= kLmLevelData3FE00[lunar_magic_FE - 1];
+ } else {
+ lm_varA |= 0x10;
+ }
+
+ lm_ptr16.addr = 0;
+ lm_ptr16.bank = 0;
+ lm_varE = 0;
+ lm_varA |= 0x10;
+
+ LongPtr pp;
+
+ if (lunar_magic_FE && lunar_magic_FE * 3 <= (int)kLmLvlExAnim_SIZE &&
+ (pp = *(LongPtr *)(kLmLvlExAnim + (lunar_magic_FE - 1) * 3)).addr != 0) {
+
+ lm_ptr0.bank = pp.bank;
+ const uint8 *p = kLmExanimBlob(Load24(pp)), *p_org = p;
+
+ lm_custom_triggers = lm_custom_triggers & WORD(p[2]) | WORD(p[4]);
+ uint16 m = WORD(p[6]);
+ p += 8;
+
+ for (int i = 0; i < 16; i++, m >>= 1) {
+ if (m & 1)
+ lm_exanim_manual_triggers[i] = *p++;
+ }
+ lm_ptr0.addr = pp.addr + (p - p_org);
+ if (!p_org[0])
+ goto else_2;
+
+ lm_varC = p_org[0] * 2;
+ lm_ptr10.addr = 0;
+ } else {
+else_2:
+ lm_ptr0.addr = 0;
+ lm_ptr0.bank = 0;
+ lm_varC = 0;
+ lm_varA |= 0x20;
+ }
+ graphics_tile_anim_vramaddress1 = 0;
+ graphics_tile_anim_vramaddress2 = 0;
+ graphics_tile_anim_vramaddress3 = 0;
+}
+
+void LmHook_BeginLoadingLevelDataB(void) {
+ if (!kLmLvlInfo_SIZE)
+ return;
+ if (lunar_magic_FE) {
+ uint16 t = kLmLvlInfo[(lunar_magic_FE - 1) * 16];
+ uint32 addr = LM_FEATURES->kLmLvlInfo_addr;
+ lm_level_info.addr = addr + (lunar_magic_FE - 1) * 32;
+ lm_level_info.bank = addr >> 16;
+ lm_var9 = 0x41 + (t >> 15);
+ if (lm_varB & 0x1)
+ LmFunc15_DecompressSlot(1);
+ } else {
+ lm_var9 = 0xff;
+ }
+}
+
+void LmHook_PrepareLevel(void) {
+ if (lunar_magic_FE && !HAS_LM_FEATURE(kLmFeature_SkipLoadPaletteHook)) {
+ LmFunc1_CustomPalettes(lunar_magic_FE - 1);
+ lunar_magic_FE = 0;
+ }
+}
+
+void LmFunc1_CustomPalettes(int a) {
+ MemBlk pal = kLmPalettes(a);
+ if (pal.size) {
+ const uint16 *pp = (const uint16*)pal.ptr;
+ palettes_background_color = pp[0];
+ memcpy(palettes_palette_mirror, pp + 1, 512);
+ }
+}
+
+void LmHook_UploadGraphicsFiles(void) {
+ LmFunc_UploadGraphics_StepA();
+ LmFunc_UpdateBG12NBA();
+
+ // more things here
+ if (lm_var9 == 0x42) {
+ LmFunc15_DecompressSlot(0);
+ } else {
+ if (lunar_magic_FB)
+ LmGraphicsDecompress(lunar_magic_FB - 1);
+ }
+ lunar_magic_FB = 0;
+ lm_var9 = 0;
+}
+
+static uint16 *GetLvlInfo() {
+ return &kLmLvlInfo[(lm_level_info.addr - (uint16)LM_FEATURES->kLmLvlInfo_addr) >> 1];
+}
+
+uint8 LmFunc15_DecompressSlotB(uint8 a) {
+ LmGraphicsDecompress(GetLvlInfo()[a] & 0xfff);
+ return 1;
+}
+
+uint8 LmFunc15_DecompressSlot(uint8 a) {
+ if (lm_var9 != 0x42)
+ return 0;
+ return LmFunc15_DecompressSlotB(a);
+}
+
+void LmHook_OwGraphicsDecompress() {
+ if (HAS_LM_FEATURE(kLmFeature_SkipOverworldDecompress))
+ return;
+ if (HAS_LM_FEATURE(kLmFeature_Ow4bppGfx))
+ LmHook_GraphicsDecompress(0x14);
+ else
+ GraphicsDecompress(0x14);
+}
+
+void LmGraphicsDecompress(uint16 a) {
+ if (a == 0x7f)
+ return; // skip
+ if (a < 0x80) {
+ GraphicsDecompress(a);
+ } else if (a < 0x100) {
+ // exgfx
+ MemBlk blk = kLmExgfx(a - 0x80);
+ assert(blk.size != 0);
+ DecompressTo(blk.ptr, g_ram + 0xad00);
+ } else {
+ MemBlk blk = kLmSuperExgfx(a - 0x100);
+ assert(blk.size != 0);
+ DecompressTo(blk.ptr, g_ram + 0xad00);
+ }
+}
+
+const uint8 *LmHook_UploadGFXFile(uint8 a, uint8 index) {
+ uint8 t;
+
+ if (index < 2) {
+ LmGraphicsDecompress(a);
+ } else if (index < 8) {
+ // bg
+ if (lm_var9 == 0x42) {
+ LmFunc15_DecompressSlot(index);
+ lunar_magic_FC = 0;
+ } else if (!(t = lunar_magic_FC)) {
+ LmGraphicsDecompress(a);
+ } else {
+ if (index == 4)
+ lunar_magic_FC = 0;
+ LmGraphicsDecompress(LmFunc18_GetFF200(t, index - 4));
+ }
+ } else {
+ // sprite
+ assert(index < 12);
+ if (lm_var9 == 0x42) {
+ LmFunc15_DecompressSlot(index);
+ lunar_magic_FD = 0;
+ } else if (!(t = lunar_magic_FD)) {
+ LmGraphicsDecompress(a);
+ } else {
+ if (index == 8)
+ lunar_magic_FD = 0;
+ LmGraphicsDecompress(LmFunc18_GetFF200(t, index - 4));
+ }
+ }
+ return g_ram + 0xad00;
+}
+
+uint8 LmFunc18_GetFF200(uint8 a, uint8 k) {
+ uint32 i = (a - 1) * 4 + k;
+ return (i < kLmGraphicsRemapped_SIZE) ? kLmGraphicsRemapped[i] : 0;
+}
+
+uint8 LmHook_ModifyMap16IDForSpecialBlocks(uint8 a) {
+ if (g_lunar_magic)
+ a = LmFunc20_ModifyMap16IDForSpecialBlocks(a);
+ return ModifyMap16IDForSpecialBlocks(a);
+}
+
+uint8 LmFunc20_ModifyMap16IDForSpecialBlocks(uint8 a) {
+ if (misc_level_mode_setting == 9 || misc_level_mode_setting == 11 || misc_level_mode_setting == 16)
+ return a; // lm returns twice...
+
+ uint16 t = blocks_currently_processed_map16_tile_lo | a << 8;
+ do {
+ t = kLmModifyMap16Ids[t];
+ } while (t >= 0x200);
+ blocks_currently_processed_map16_tile_lo = t;
+ return t >> 8;
+}
+
+uint8 *LmHook_GraphicsDecompress(uint8 a) {
+ uint8 *p = GraphicsDecompress(a);
+ if (HAS_LM_FEATURE(kLmFeature_4bppgfx)) {
+ uint8 *dst = p, *src = p;
+ int i = 0;
+ do {
+ memcpy(dst, src, 16);
+ dst += 16, src += 16;
+ for (int j = 0; j < 8; j++) {
+ dst[0] = src[0];
+ dst += 1, src += 2;
+ }
+ i += 0x20;
+ } while (i != 0x1000);
+ }
+ return p;
+}
+
+static const uint16 kMinOffsFromScreenToSpawn[] = {-192, -48, -128, -16383};
+static const uint16 kMaxOffsFromScreenToSpawn[] = {432, 288, 352, 16383};
+
+void LmHook_LoadSpritesOnLevelLoad(void) {
+ min_y_offset_from_screen_to_spawn = kMinOffsFromScreenToSpawn[extra_flags_for_sprites & 3] - 0x10;
+ max_y_offset_from_screen_to_spawn = kMaxOffsFromScreenToSpawn[extra_flags_for_sprites & 3] + 0x10;
+ WORD(smart_spawn_horiz_collision) = 0xffff;
+
+ lm_ptrs_to_sprites_per_screen[0] = ptr_sprite_list_data.addr;
+ uint16 r4 = ptr_sprite_list_data.addr - 2;
+ uint16 r8 = 0;
+ uint8 r6 = 0;
+ int r0 = 0;
+
+ lm_screen_sprite_data[0] = 0;
+ const uint8 *p_org = kLvlSprBlob(Load24(ptr_sprite_list_data));
+ const uint8 *p = p_org + 1;
+outer_loop:;
+ const uint8 *r10 = p;
+ uint8 a;
+ uint8 r7 = r8;
+read_next:
+ for (;;) {
+ if ((a = p[0]) != 0xff)
+ break;
+ if (!(extra_flags_and_horiz_level_mode & 0x20))
+ goto found_end;
+ p++;
+ if ((a = p[0]) == 0xff)
+ break;
+ if (a == 0xfe)
+ goto found_end;
+ r6 = a * 2;
+ p++;
+ }
+
+ uint8 r2_screen = ((a & 2) << 3 | (p[1] & 0xf));
+ p += 2;
+
+ if (kLmSprExtraSize_SIZE) {
+ p += kLmSprExtraSize[(a & 0xc) << 6 | p[0]] - 2;
+ }
+ p += 1;
+ r8++;
+ if (r2_screen == r0)
+ goto read_next;
+
+ uint16 t0 = lm_ptrs_to_sprites_per_screen[r0];
+ uint16 t1 = lm_screen_sprite_data[r0];
+ do {
+ r0++;
+ lm_ptrs_to_sprites_per_screen[r0] = t0;
+ lm_screen_sprite_data[r0] = t1;
+ } while (r0 < r2_screen);
+
+ lm_ptrs_to_sprites_per_screen[r0] = (r10 - p_org) + r4 + 1;
+ lm_screen_sprite_data[r0] = r6 | r7 << 8;
+
+ goto outer_loop;
+
+found_end:
+ t0 = lm_ptrs_to_sprites_per_screen[r0];
+ t1 = lm_screen_sprite_data[r0];
+ while (r0 < 0x1f) {
+ r0++;
+ lm_ptrs_to_sprites_per_screen[r0] = t0;
+ lm_screen_sprite_data[r0] = t1;
+ }
+}
+
+void Lm_ParseLevelSpriteList(uint8 k, const uint8 *p, PointU16 pt) { // 02a82e
+ uint16 xx;
+
+ while (1) {
+ if (*p == 0xFF) {
+ if (!(extra_flags_and_horiz_level_mode & 0x20))
+ return;
+ p++;
+ if (p[0] < 0x80) {
+ pt.y = pt.y & ~0x1ff | p[0] * 2;
+ continue;
+ }
+ if (p[0] != 0xff)
+ return;
+ }
+
+ lm_var_0054 = p[0];
+ uint8 r0 = p[1];
+
+ uint8 screen = (8 * p[0]) & 0x10 | p[1] & 0xF;
+
+ if (sign8(screen - HIBYTE(lm_var_0050))) {
+ r0 &= ~0xf;
+ } else if ((uint8)(screen - HIBYTE(lm_var_0050)) != 0) {
+ if (lm_var_0045 & 0x80 || screen > HIBYTE(lm_var_004E))
+ return;
+ if (lm_var_0045 & 0x20)
+ return;
+ r0 &= ~0xf;
+ goto label2;
+ } else {
+ r0 &= 0xf0;
+ if (r0 != BYTE(lm_var_0050))
+ goto label1;
+ xx = r0 | screen << 8;
+ if (lm_var_0045 & 0x80)
+ goto found_sprite;
+ if (lm_var_0045 & 0x40)
+ goto label1;
+ uint16 t0 = (lm_var_0054 & 1 | HIBYTE(pt.y)) << 8 | lm_var_0054 & 0xf0;
+ if (sign16(t0 - lm_var_0052) || !sign16(t0 - lm_var_0046))
+ goto read_next_sprite;
+ goto found_sprite;
+ }
+ label1:
+ if (lm_var_0045 & 0x82)
+ goto read_next_sprite;
+ label2:
+
+ if (HIBYTE(pt.y) == HIBYTE(lm_var_0048)) {
+ if ((lm_var_0054 & 0xf1) != LOBYTE(lm_var_0048) && (
+ (lm_var_0054 & 0xf1) != LOBYTE(lm_var_004A) || HIBYTE(pt.y) != HIBYTE(lm_var_004A)))
+ goto read_next_sprite;
+ } else {
+ // else_2
+ if (HIBYTE(pt.y) != HIBYTE(lm_var_004A))
+ goto read_next_sprite;
+ if ((lm_var_0054 & 0xf1) != LOBYTE(lm_var_004A))
+ goto read_next_sprite;
+ }
+
+ xx = r0 | screen << 8;
+ if (sign16(xx - lm_var_004C) || !sign16(xx - lm_var_004E))
+ goto read_next_sprite;
+
+found_sprite:
+ if (!sprites_load_status[k] && LoadOneSprite(p, k, (PointU16) { .x = xx, .y = pt.y }))
+ return;
+ read_next_sprite:
+ p += 3;
+ k++;
+ }
+}
+
+
+void LmHook_BE8A(uint16 x_base) {
+ int k = extra_flags_for_sprites & 3;
+
+ lm_var_0050 = x_base;
+ lm_var_0046 = mirror_current_layer1_ypos & ~0xf;
+ lm_var_0052 = lm_var_0046 + kMinOffsFromScreenToSpawn[k];
+ lm_var_0048 = lm_var_0052;
+ lm_var_0046 += kMaxOffsFromScreenToSpawn[k];
+ lm_var_004A = lm_var_0046 - 0x10;
+ lm_var_004C = (mirror_current_layer1_xpos & ~0xf) - 0x30;
+ lm_var_004E = lm_var_004C + 0x150;
+
+ uint8 a = HIBYTE(lm_var_0048) & 1;
+ HIBYTE(lm_var_0048) &= ~a;
+ LOBYTE(lm_var_0048) |= a;
+
+ a = HIBYTE(lm_var_004A) & 1;
+ HIBYTE(lm_var_004A) &= ~a;
+ LOBYTE(lm_var_004A) |= a;
+
+ k = misc_level_layout_flags & 1;
+
+ lm_var_0045 = 0xa0;
+ (&lm_var_0045)[k * 2] = 0;
+
+ uint8 t;
+ if (extra_flags_for_sprites & 0x80) {
+ t = smart_spawn_horiz_collision;
+ smart_spawn_horiz_collision = BYTE(lm_var_0050);
+ if (BYTE(lm_var_0050) == t)
+ lm_var_0045 |= 0x40;
+
+ t = smart_spawn_vert_collision;
+ smart_spawn_vert_collision = BYTE(lm_var_0048);
+ if (BYTE(lm_var_0048) == t)
+ lm_var_0045 |= 0x20;
+
+ t = lm_var_0045 & 0x60;
+ if (t == 0x60)
+ return;
+ if (t != 0x20)
+ goto else_1;
+
+ t = HIBYTE(lm_var_0050);
+ if (t & 0x80) {
+ t = 0;
+ } else {
+ if (t >= 0x20)
+ t = 0x1f;
+ }
+ } else {
+else_1:
+ t = ((k ? HIBYTE(mirror_current_layer1_ypos) : HIBYTE(mirror_current_layer1_xpos)) - 1) & 0x7f;
+ if (t & 0x40)
+ t = 0;
+ }
+
+ LongPtr backup = ptr_sprite_list_data;
+
+ ptr_sprite_list_data.addr = lm_ptrs_to_sprites_per_screen[t];
+
+ // The low byte is used to modify the sprite's Y position,
+ // while the high byte indicates the number of the sprite within the level.
+ uint16 tt = lm_screen_sprite_data[t];
+
+ Lm_ParseLevelSpriteList(tt >> 8, kLvlSprBlob(Load24(ptr_sprite_list_data)) + 1, (PointU16){.x = 0, .y = tt << 8});
+
+ ptr_sprite_list_data = backup;
+}
+
+uint16 LmFunc_InitScreenTables(int k, int a) {
+ do {
+ L1_Screen_Lo[k / 3].addr = a;
+ L1_Screen_Hi[k / 3].addr = a;
+ k += 3;
+ a += lm_level_height;
+ } while (a < 0x10000 && k < 0x60);
+ return k;
+}
+
+void LmHook_LoadLevelInfo(void) {
+ if (!HAS_LM_FEATURE(kLmFeature_LoadLevel))
+ return;
+ HIBYTE(mirror_current_layer1_ypos) = 0;
+ HIBYTE(mirror_current_layer2_ypos) = 0;
+ extra_flags_and_horiz_level_mode = 0;
+
+ lm_level_height = 0x1b0;
+ lm_level_height_minus_16 = lm_level_height - 0x10;
+
+ LmFunc_InitScreenTables(0, 0xc800);
+}
+
+void LmHook_BufferCreditsBackgrounds(void) {
+ if (!HAS_LM_FEATURE(kLmFeature_LoadLevel))
+ return;
+
+ lm_level_height = 0x1b0;
+ lm_level_height_minus_16 = lm_level_height - 0x10;
+ LmFunc_InitScreenTables(0, 0xc800);
+ extra_flags_and_horiz_level_mode = 0;
+}
+
+static const uint16 kLmLevelHeights[32] = {
+ 0x1B0, 0x1C0, 0x1D0, 0x200, 0x220, 0x250, 0x260, 0x280, 0x2A0, 0x2C0, 0x2F0, 0x310, 0x340, 0x380, 0x3B0, 0x400,
+ 0x440, 0x4A0, 0x510, 0x590, 0x630, 0x700, 0x800, 0x950, 0xB30, 0xE00,0x12A0,0x1C00,0x3800, 0x100, 0xF0, 0xE0,
+};
+
+void LmHook_LoadLevel(uint16 j) {
+ if (!HAS_LM_FEATURE(kLmFeature_LoadLevel))
+ return;
+
+ extra_flags_and_horiz_level_mode = *GetSpriteListPtr() & 0x20;
+
+ for (int i = 0; i < 0x20; i++) {
+ L1_Screen_Lo[i].bank = 0x7e;
+ L1_Screen_Hi[i].bank = 0x7f;
+ }
+
+ if (misc_level_layout_flags & 1) {
+ lm_level_height = 0x1b0;
+ lm_level_height_minus_16 = lm_level_height - 0x10;
+ LmFunc_InitScreenTables(0, 0xc800);
+ lm_level_height = 0x100;
+ return;
+ }
+
+ uint8 a = kLm5DE00[j] & 7;
+ if (a & 4)
+ a ^= 0x84;
+ extra_flags_for_sprites = a;
+ extra_flags_and_horiz_level_mode |= kLm10B8BC[j];
+ lm_level_height = kLmLevelHeights[extra_flags_and_horiz_level_mode & 0x1f];
+ lm_level_height_minus_16 = lm_level_height - 0x10;
+ uint16 k = LmFunc_InitScreenTables(0, 0xc800);
+
+ // ??
+ if (extra_flags_and_horiz_level_mode & 0x80 && k < 0x60)
+ LmFunc_InitScreenTables(0x30, WORD(((uint8*)L1_Screen_Lo)[(k & 1 ? k - 3 : k) >> 1]));
+
+ for (int i = 0; i < 0x20; i++) {
+ L1_Screen_8bit_Lo[i] = L1_Screen_Lo[i].addr;
+ L1_Screen_8bit_Hi[i] = L1_Screen_Lo[i].addr >> 8;
+ }
+}
+
+void LmHook_LoadLevelB(const uint8 *ptr_layer1_data, uint8 R2, uint16 level_number) {
+ if (!HAS_LM_FEATURE(kLmFeature_LoadLevel))
+ return;
+
+ uint8 r4 = kLm6FC00[level_number];
+
+ uint16 r6;
+ if (!(misc_level_layout_flags & 1)) {
+ r6 = lm_level_height - 0xf0 + (extra_flags_and_horiz_level_mode & 0x40 ? 15 : 0);
+ } else {
+ r6 = (uint8)(camera_last_screen_vert - 1) << 8;
+ }
+ mirror_current_layer2_xpos = 0;
+
+ uint8 k = lm_var13CD;
+ if (!sign8(k))
+ return;
+
+ flag_layer1_vert_scroll_level_setting = 0;
+ BYTE(mirror_current_layer1_ypos) = 0;
+ if (player_riding_yoshi_flag && (ptr_layer1_data[4] & 0x30) != 0x30) {
+ BYTE(mirror_current_layer1_ypos) = ptr_layer1_data[4] & 0x30;
+ }
+
+ uint16 t = (R2 & 0xf) << 4;
+ if (r4 & 0x40 && (t |= 0xff00) != 0xff90) {
+ mirror_current_layer1_ypos = 0;
+ }
+ if (extra_flags_and_horiz_level_mode & 0x40)
+ t--;
+ t += player_ypos;
+ if (sign16(t) || BYTE(mirror_current_layer1_ypos) && !(BYTE(mirror_current_layer1_ypos) == 0x20 && t == r6) && sign16(t -= 8))
+ t = 0;
+ mirror_current_layer1_ypos = t;
+
+ uint16 kk = flag_layer2_vert_scroll_level_setting;
+
+ uint8 carry = misc_level_layout_flags & 1;
+ static const uint8 kShifts[] = { 0, 1, 5, 2, 3, 4, 6 };
+ uint16 a;
+
+ if (!(r4 & 0x80)) {
+ k &= 0x1f;
+ if (!carry) {
+ k -= 0xe;
+ if (extra_flags_and_horiz_level_mode & 0x40)
+ k += 1;
+ if (kk) {
+ mirror_current_layer2_ypos = k << kShifts[kk - 1];
+ a = (lm_level_height >> 4);
+ if (!(extra_flags_and_horiz_level_mode & 0x40))
+ a--;
+ endif_8:
+ a -= 0xe;
+ if (a < mirror_current_layer2_ypos) {
+ camera_layer2_ypos_relative_to_layer1 = ((uint16)((mirror_current_layer2_ypos - a) * 16) >> kShifts[kk - 1]);
+ } else {
+ camera_layer2_ypos_relative_to_layer1 = -(((uint16)((a - mirror_current_layer2_ypos) * 16) >> kShifts[kk - 1]));
+ }
+ mirror_current_layer2_ypos = (mirror_current_layer1_ypos >> kShifts[kk - 1]) + camera_layer2_ypos_relative_to_layer1;
+ } else {
+ mirror_current_layer2_ypos = k * 16;
+ }
+ } else {
+ k -= 0xe;
+ if (kk) {
+ mirror_current_layer2_ypos = k << kShifts[kk - 1];
+ a = camera_last_screen_vert * 16 - 2;
+ goto endif_8;
+ } else {
+ mirror_current_layer2_ypos = k * 16;
+ }
+ }
+ } else {
+ k *= 16;
+ if (k & 0x100) {
+ k |= 0xff00;
+ if (k == 0xff00)
+ k = 0;
+ else
+ k += mirror_current_layer1_ypos;
+ } else {
+ k = (k & 0xf0) + mirror_current_layer1_ypos;
+ }
+ mirror_current_layer2_ypos = k;
+ camera_layer2_ypos_relative_to_layer1 = -(mirror_current_layer1_ypos >> kShifts[kk - 1]) + mirror_current_layer2_ypos;
+ }
+}
+
+
+void LmFunc_UploadOneLevelAnimation(ExAnimationInfo *anim) {
+ if (anim->hdr_size) {
+ const uint8 *src = (anim->src.bank == 0x7e) ? g_ram + anim->src.addr : kLmExanimBlob(Load24(anim->src));
+ if (!(anim->hdr_size & 0x8000)) {
+ SmwCopyToVram(anim->dst & 0x7fff, src, anim->hdr_size);
+ if (anim->dst & 0x8000)
+ SmwCopyToVram((anim->dst & 0x7fff) + 0x100, src + anim->hdr_size, anim->hdr_size);
+ } else {
+ RtlUpdatePalette((uint16 *)src, (uint8)anim->dst, (uint8)anim->hdr_size);
+ }
+ }
+}
+
+void LmHook_UploadLevelAnimations(void) {
+ LmFunc_UploadOneLevelAnimation(&ex_anim_info_4);
+ LmFunc_UploadOneLevelAnimation(&ex_anim_info_5);
+ LmFunc_UploadOneLevelAnimation(&ex_anim_info_6);
+ LmFunc_UploadOneLevelAnimation(&ex_anim_info_7);
+ LmFunc_UploadOneLevelAnimation(&ex_anim_info_0);
+ LmFunc_UploadOneLevelAnimation(&ex_anim_info_1);
+ LmFunc_UploadOneLevelAnimation(&ex_anim_info_2);
+ LmFunc_UploadOneLevelAnimation(&ex_anim_info_3);
+ if (!sign8(lm_varA)) {
+ RtlUpdatePalette(&kGlobalPalettes_Flashing[(counter_local_frames & 0x1c) >> 2], 0x64, 1);
+ }
+ lm_var4 = lm_var19 >> 3;
+}
+
+bool LmHook_GameMode11_LoadSublevel(void) {
+ camera_last_screen_horiz = (ptr_layer1_data[0] & 0x1f) + 1;
+ uint8 a = lm_var13CD;
+ lm_var13CD = 0;
+ if (a & 0x40) {
+ player_facing_direction = 0;
+ }
+ lunar_magic_F9 = (a & 0x40) ? 0xc0 : 0x40;
+ if (a & 0x80) {
+ player_relative_position_needed_to_scroll_screen = 0x80;
+ return true;
+ }
+ return false;
+}
+
+uint8 blocks_screen_to_place_next_object_bak;
+
+void LmHook_PreserveLevelDataPointerInObjects(void) {
+ ptr_lo_map16_data_bak = ptr_lo_map16_data;
+ blocks_screen_to_place_next_object_bak = blocks_screen_to_place_next_object;
+}
+
+void LmHook_RestoreLevelDataPointerInObjects(void) {
+ ptr_lo_map16_data = ptr_lo_map16_data_bak;
+ blocks_screen_to_place_next_object = blocks_screen_to_place_next_object_bak;
+}
+
+uint8 LmHook_HandleHorizontalSubScreenCrossingForCurrentObject_Entry2(void) {
+ if (misc_level_layout_flags & 1) {
+ ptr_lo_map16_data += 256;
+ } else {
+ ptr_lo_map16_data += lm_level_height;
+ blocks_screen_to_place_next_object++;
+ }
+ return blocks_sub_scr_pos & 0xF0;
+}
+
+uint8 LmHook_HandleVerticalSubScreenCrossingForCurrentObject(void) {
+ int j = blocks_sub_scr_pos + 16;
+ blocks_sub_scr_pos = j;
+ if (j >= 256) {
+ if (misc_level_layout_flags & 1) {
+ ptr_lo_map16_data += 512;
+ blocks_screen_to_place_next_object++;
+ } else {
+ ptr_lo_map16_data += 256;
+ }
+ LmHook_PreserveLevelDataPointerInObjects();
+ }
+ return j;
+}
+
+void LmHook_UploadLevelLayer1And2Tilemaps(void) {
+ if (misc_game_mode == 1) {
+ lm_vram_upload_enable_0 = 0;
+ lm_vram_upload_enable_6 = 0;
+ lm_vram_upload_enable_12 = 0;
+ lm_vram_upload_enable_16 = 0;
+ return;
+ }
+
+ if (misc_game_mode >= 0x20) {
+ UploadLevelLayer1And2Tilemaps();
+ return;
+ }
+
+ if (lm_vram_upload_enable_0) {
+ SmwCopyToVram(lm_vram_dma_dst0, g_ram + lm_vram_dma_src0, lm_vram_dma_size0);
+ SmwCopyToVram(lm_vram_dma_dst1, g_ram + lm_vram_dma_src1, lm_vram_dma_size1);
+ SmwCopyToVram(lm_vram_dma_dst2, g_ram + lm_vram_dma_src2, lm_vram_dma_size2);
+ SmwCopyToVram(lm_vram_dma_dst3, g_ram + lm_vram_dma_src3, lm_vram_dma_size3);
+ if (lm_vram_dma_size0 != 0x40) {
+ SmwCopyToVram(lm_vram_dma_dst4, g_ram + lm_vram_dma_src4, lm_vram_dma_size4);
+ SmwCopyToVram(lm_vram_dma_dst5, g_ram + lm_vram_dma_src5, lm_vram_dma_size5);
+ }
+ lm_vram_upload_enable_0 = 0;
+ }
+
+ if (lm_vram_upload_enable_6) {
+ SmwCopyToVram(lm_vram_dma_dst6, g_ram + lm_vram_dma_src6, lm_vram_dma_size6);
+ SmwCopyToVram(lm_vram_dma_dst7, g_ram + lm_vram_dma_src7, lm_vram_dma_size7);
+ SmwCopyToVram(lm_vram_dma_dst8, g_ram + lm_vram_dma_src8, lm_vram_dma_size8);
+ SmwCopyToVram(lm_vram_dma_dst9, g_ram + lm_vram_dma_src9, lm_vram_dma_size9);
+ if (lm_vram_dma_size6 != 0x40) {
+ SmwCopyToVram(lm_vram_dma_dst10, g_ram + lm_vram_dma_src10, lm_vram_dma_size10);
+ SmwCopyToVram(lm_vram_dma_dst11, g_ram + lm_vram_dma_src11, lm_vram_dma_size11);
+ }
+ lm_vram_upload_enable_6 = 0;
+ }
+
+ if (lm_vram_upload_enable_12) {
+ SmwCopyToVramPitch32(lm_vram_dma_dst12, g_ram + 0x10000 + lm_vram_dma_src12, lm_vram_dma_size12);
+ SmwCopyToVramPitch32(lm_vram_dma_dst13, g_ram + 0x10000 + lm_vram_dma_src13, lm_vram_dma_size13);
+ if (lm_vram_dma_size12 != 0x40) {
+ SmwCopyToVramPitch32(lm_vram_dma_dst14, g_ram + 0x10000 + lm_vram_dma_src14, lm_vram_dma_size14);
+ SmwCopyToVramPitch32(lm_vram_dma_dst15, g_ram + 0x10000 + lm_vram_dma_src15, lm_vram_dma_size15);
+ }
+ lm_vram_upload_enable_12 = 0;
+ }
+
+ if (lm_vram_upload_enable_16) {
+ SmwCopyToVramPitch32(lm_vram_dma_dst16, g_ram + 0x10000 + lm_vram_dma_src16, lm_vram_dma_size16);
+ SmwCopyToVramPitch32(lm_vram_dma_dst17, g_ram + 0x10000 + lm_vram_dma_src17, lm_vram_dma_size17);
+ if (lm_vram_dma_size16 != 0x40) {
+ SmwCopyToVramPitch32(lm_vram_dma_dst18, g_ram + 0x10000 + lm_vram_dma_src18, lm_vram_dma_size18);
+ SmwCopyToVramPitch32(lm_vram_dma_dst19, g_ram + 0x10000 + lm_vram_dma_src19, lm_vram_dma_size19);
+ }
+ lm_vram_upload_enable_16 = 0;
+ }
+}
+
+void LmHook_InitializeLevelLayer1And2Tilemaps(void) {
+ for (int i = 0; i < 8; i++)
+ lm_arr1830b[i] = -1;
+ for (int i = 0; i < 4; i++)
+ lm_arr1831b[i] = 2;
+}
+
+void EmptyFunc(void) {}
+
+void Lm_SetupPipeTiles(uint16 a) {
+ uint16 t = kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[a & 3];
+ for (int i = 0; i < 8; i++)
+ pointer_map16_tiles[307 + i] = t + i * 8;
+}
+
+const uint16 *GetMap16RomAddr(uint8 bank, uint16 addr) {
+ if (bank == 13) {
+ if (addr >= 0xe300)
+ return (uint16 *)((const uint8 *)kMap16Data_GhostHouse + addr - 0xe300);
+ else if (addr >= 0xd400)
+ return (uint16 *)((const uint8 *)kMap16Data_Underground + addr - 0xd400);
+ else if (addr >= 0xc800)
+ return (uint16 *)((const uint8 *)kMap16Data_Rope + addr - 0xc800);
+ else if (addr >= 0xbc00)
+ return (uint16 *)((const uint8 *)kMap16Data_Castle + addr - 0xbc00);
+ else
+ return (uint16 *)((const uint8 *)kMap16Data + addr - 0x8000);
+ }
+ assert(addr >= 0xd000 && addr < 0xd608);
+ return (uint16 *)((const uint8 *)kMap16Data_OverworldLayer1 + addr - 0xd000);
+}
+
+const uint16 *Lm_GetMap16RomAddr(uint16 addr) {
+ assert(addr < 0x8000);
+
+ if (addr < 0x200)
+ return GetMap16RomAddr(misc_level_tileset_setting < 16 ? 13 : 5, pointer_map16_tiles[addr]);
+ if (addr < 0x300 && kMap16_TS_SIZE != 0) {
+ // tileset specific map16
+ int v2 = (4 * addr) & 0x3ff | ((misc_level_tileset_setting & 0xf) << 10);
+ return kMap16_TS + v2;
+ }
+ int part = (4 * addr) & 0x3fff;
+ switch (addr >> 12) {
+ case 0: return kMap16_0 + part - 0x800;
+ case 1: return kMap16_1 + part;
+ case 2: return kMap16_2 + part;
+ case 3: return kMap16_3 + part;
+ case 4: return kMap16_4 + part;
+ case 5: return kMap16_5 + part;
+ case 6: return kMap16_6 + part;
+ case 7: return kMap16_7 + part;
+ default: assert(0); return NULL;
+ }
+}
+
+void Lm_CopyTilesToL1UploadBuffer(const uint8 *plo, const uint8 *phi, uint16 j, uint16 r6) {
+ uint16 *dp = &blocks_layer1_tiles_to_upload_buffer[0];
+ for (int i = 0; i < 20; i++, dp += 2) {
+ const uint16 *tp = Lm_GetMap16RomAddr((plo[j] | phi[j] << 8));
+ dp[0] = tp[0];
+ dp[64] = tp[1];
+ dp[1] = tp[2];
+ dp[65] = tp[3];
+ if ((++j & 0xF) == 0) {
+ Lm_SetupPipeTiles(++r6);
+ j += lm_level_height_minus_16;
+ }
+ }
+}
+
+void Lm_CopyToVramBufD_6(const uint8 *plo, const uint8 *phi, uint16 j, const uint16 *ptile) {
+ uint16 *dp = &blocks_layer2_tiles_to_upload_buffer[0];
+ for (int i = 0; i < 32; i++, dp += 2) {
+ const uint16 *tp = ptile + 4 * (plo[j] | phi[j] << 8);
+ dp[0] = tp[0];
+ dp[64] = tp[1];
+ dp[1] = tp[2];
+ dp[65] = tp[3];
+ j++;
+ if (i == 15)
+ j += lm_var18327 - 0x10;
+ }
+}
+
+void LmFunc_CopyTilemapA_12(const uint8 *plo, const uint8 *phi, uint16 j) {
+ uint16 *dp = &lm_L2_colbuf[0];
+ for (int i = 0; i < 16; i++, dp += 2) {
+ const uint16 *tp = Lm_GetMap16RomAddr((plo[j] | phi[j] << 8));
+ dp[0] = tp[0];
+ dp[1] = tp[1];
+ dp[32] = tp[2];
+ dp[33] = tp[3];
+ j = (j + 16) & 0x3fff;
+ }
+}
+
+void LmFunc_108CB0(const uint8 *plo, const uint8 *phi, uint16 j, uint16 r6, uint16 r3) {
+ uint16 *dp = &blocks_layer2_tiles_to_upload_buffer[0];
+ for (int i = 0; i < 20; i++, dp += 2) {
+ const uint16 *tp = Lm_GetMap16RomAddr((plo[j] | phi[j] << 8));
+ dp[0] = r3 | tp[0];
+ dp[64] = r3 | tp[1];
+ dp[1] = r3 | tp[2];
+ dp[65] = r3 | tp[3];
+ if ((++j & 0xF) == 0) {
+ Lm_SetupPipeTiles(++r6);
+ j += lm_level_height_minus_16;
+ }
+ }
+}
+
+void LmFunc_CopyTilemapC_12(const uint8 *plo, const uint8 *phi, uint16 j, uint16 r3) {
+ uint16 *dp = &lm_tilebuf3[0];
+ for (int i = 0; i < 16; i++, dp += 2) {
+ const uint16 *tp = Lm_GetMap16RomAddr((plo[j] | phi[j] << 8));
+ dp[0] = r3 | tp[0];
+ dp[1] = r3 | tp[1];
+ dp[32] = r3 | tp[2];
+ dp[33] = r3 | tp[3];
+ j = (j + 16) & 0x3fff;
+ }
+}
+
+void LmFunc_109662(const uint8 *plo, const uint8 *phi, uint16 j) {
+ uint16 *dp = &blocks_layer1_tiles_to_upload_buffer[0];
+ for (int i = 0; i < 32; i++, dp += 2) {
+ const uint16 *tp = Lm_GetMap16RomAddr((plo[j] | phi[j] << 8));
+ dp[0] = tp[0];
+ dp[64] = tp[1];
+ dp[1] = tp[2];
+ dp[65] = tp[3];
+ j++;
+ if (i == 15)
+ j += 256 - 16;
+ }
+}
+
+void LmFunc_109C29(const uint8 *plo, const uint8 *phi, uint16 j, uint16 r3) {
+ uint16 *dp = &blocks_layer2_tiles_to_upload_buffer[0];
+ for (int i = 0; i < 32; i++, dp += 2) {
+ const uint16 *tp = Lm_GetMap16RomAddr((plo[j] | phi[j] << 8));
+ dp[0] = r3 | tp[0];
+ dp[64] = r3 | tp[1];
+ dp[1] = r3 | tp[2];
+ dp[65] = r3 | tp[3];
+ j++;
+ if (i == 15)
+ j += 256 - 16;
+ }
+}
+
+
+void Lm_BufferTilemap_L1_0(void) {
+ if (blocks_screen_to_place_current_object & 0x10)
+ return;
+
+ const uint16 *r10 = GetLayerLayoutPtr(0, misc_level_mode_setting);
+
+ uint16 t0 = (mirror_current_layer1_ypos >> 4) - 1 + (blocks_screen_to_place_current_object & 0xf);
+ if (sign16(t0))
+ return; // lm fix
+
+ lm_vram_upload_enable_0 = (t0 << 6) & 0x3ff | 0x3000;
+
+ uint16 t1;
+ if (!sign16(mirror_current_layer1_xpos)) {
+ t1 = (mirror_current_layer1_xpos >> 4) - 2;
+ t1 = sign16(t1) ? 0 : t1;
+ } else {
+ t1 = 0;
+ }
+
+ Lm_SetupPipeTiles(t1 >> 4);
+
+ const uint8 *plo = g_ram + r10[t1 >> 4];
+ const uint8 *phi = g_ram + r10[t1 >> 4] + 0x10000;
+
+ uint16 r8 = t1 & 0xf;
+ lm_vram_upload_enable_0 |= (t1 & 0xf) * 2 | (t1 & 0x10 ? 0x400 : 0);
+
+ Lm_CopyTilesToL1UploadBuffer(plo, phi, t0 * 16 | r8, t1 >> 4);
+ Lm_SetupLmVramDma_0();
+}
+
+void Lm_BufferTilemap_L1_1(void) {
+ if (blocks_screen_to_place_current_object & 0x10)
+ return;
+
+ const uint16 *r10 = GetLayerLayoutPtr(0, misc_level_mode_setting);
+ uint16 t0 = (mirror_current_layer1_ypos >> 4) - 1 + (blocks_screen_to_place_current_object & 0xf);
+ if (sign16(t0)) // lm fix
+ return;
+
+ lm_vram_upload_enable_0 = (t0 << 6) & 0x3ff | 0x3000;
+ Lm_SetupPipeTiles(t0 >> 4);
+
+ const uint8 *plo = g_ram + r10[(t0 & 0x1f0) >> 4];
+ const uint8 *phi = g_ram + r10[(t0 & 0x1f0) >> 4] + 0x10000;
+
+ LmFunc_109662(plo, phi, (t0 & 0xf) * 16);
+ Lm_SetupLmVramDma_0();
+}
+
+uint16 *LmHook_CustomBgMap16(void) {
+ uint16 v0 = (lm_varB & 4) != 0 ? (lm_varB & 0xF0) >> 4 : 0;
+ return (uint16*)kLmCustomMap16Bg(v0).ptr;
+}
+
+void LmHook_BufferScrollingTiles_L2_Background(void) {
+ if (blocks_screen_to_place_current_object & 0x10)
+ return;
+ const uint8 *phi = blocks_layer2_tiles_hi, *plo = blocks_layer2_tiles_lo;
+ const uint16 *r10 = LmHook_CustomBgMap16();
+ lm_var18327 = (lm_varB & 4) != 0 ? 0x200 : 0x1b0;
+ int v0 = 32;
+ uint16 v1 = (blocks_screen_to_place_current_object & 0xF) << 6;
+ do {
+ lm_arr_7FBC00[v1 >> 1] = WORD(blocks_layer2_tiles_lo[v1]);
+ lm_arr_7FC300[v1 >> 1] = WORD(blocks_layer2_tiles_hi[v1]);
+ v1 += 2;
+ } while (--v0);
+ uint16 r8 = (mirror_current_layer2_ypos - 16 + 16 * (blocks_screen_to_place_current_object & 0xF)) & 0x1F0;
+ lm_vram_upload_enable_6 = (4 * r8) & 0x3FF | 0x3800;
+ Lm_CopyToVramBufD_6(plo, phi, r8, r10);
+ Lm_SetupLmVramDma_6();
+}
+
+void LmHook_BufferScrollingTiles_L2_1(void) {
+ if (blocks_screen_to_place_current_object & 0x10)
+ return;
+
+ const uint16 *r10 = GetLayerLayoutPtr(1, misc_level_mode_setting);
+
+ uint16 r3 = (misc_level_tileset_setting == 3 ? 0x1000 : 0);
+
+ uint16 t0 = (mirror_current_layer2_ypos >> 4) - 1 + (blocks_screen_to_place_current_object & 0xf);
+ if (sign16(t0))
+ return; // lm fix
+
+ lm_vram_upload_enable_6 = (t0 << 6) & 0x3ff | 0x3800;
+
+ uint16 t1;
+ if ((mirror_current_layer2_xpos & 0x8000u) != 0 || (t1 = (mirror_current_layer2_xpos >> 4) - 2, (t1 & 0x8000u) != 0))
+ t1 = 0;
+
+ Lm_SetupPipeTiles(t1 >> 4);
+
+ const uint8 *plo = g_ram + r10[t1 >> 4];
+ const uint8 *phi = g_ram + r10[t1 >> 4] + 0x10000;
+
+ uint16 r8 = t1 & 0xf;
+ lm_vram_upload_enable_6 |= (t1 & 0xf) * 2 | (t1 & 0x10 ? 0xC00 : 0x800);
+
+ LmFunc_108CB0(plo, phi, t0 * 16 | r8, t1 >> 4, r3);
+ Lm_SetupLmVramDma_6();
+}
+
+void LmHook_BufferScrollingTiles_L2_7(void) {
+ if (blocks_screen_to_place_current_object & 0x10)
+ return;
+
+ const uint16 *r10 = GetLayerLayoutPtr(1, misc_level_mode_setting);
+ uint16 r3 = (misc_level_tileset_setting == 3 ? 0x1000 : 0);
+
+ uint16 t0 = (mirror_current_layer2_ypos >> 4) - 1 + (blocks_screen_to_place_current_object & 0xf);
+ lm_vram_upload_enable_6 = (t0 << 6) & 0x3ff | 0x3800;
+
+ const uint8 *plo = g_ram + r10[(t0 & 0x1f0) >> 4];
+ const uint8 *phi = g_ram + r10[(t0 & 0x1f0) >> 4] + 0x10000;
+
+ LmFunc_109C29(plo, phi, (t0 & 0xf) * 16, r3);
+ Lm_SetupLmVramDma_6();
+}
+
+static const uint16 kLm10B483[2] = {0, 14};
+static const uint16 kLm10B487[2] = {0xFFFF, 0x11};
+
+void LmFunc_UpdateTilemapA_0(void) {
+ const uint16 *r10 = GetLayerLayoutPtr(0, misc_level_mode_setting);
+
+ uint16 v2 = kLm10B487[lm_arr1831b[0] >> 1] + (mirror_current_layer1_xpos >> 4);
+ lm_vram_upload_enable_12 = (2 * v2) & 0x1F | 0x3000 | (v2 & 0x10 ? 0x400 : 0);
+ Lm_SetupPipeTiles(v2 >> 4);
+ uint16 t1 = (v2 >> 4) & 0x1F;
+
+ const uint8 *plo = g_ram + r10[t1];
+ const uint8 *phi = g_ram + r10[t1] + 0x10000;
+
+ uint16 r8 = mirror_current_layer1_ypos & 0x3FF0;
+ lm_vram_upload_enable_12 |= (4 * r8) & 0x3C0;
+ LmFunc_CopyTilemapA_12(plo, phi, r8 | v2 & 0xF);
+ Lm_SetupLmVramDma_12();
+}
+
+void LmFunc_UpdateTilemapB_0(void) {
+ const uint16 *r10 = GetLayerLayoutPtr(0, misc_level_mode_setting);
+ uint16 v0;
+ uint16 v4 = kLm10B483[lm_arr1831b[1] >> 1] + (mirror_current_layer1_ypos >> 4);
+ lm_vram_upload_enable_0 = (v4 << 6) & 0x3FF | 0x3000;
+ if ( (mirror_current_layer1_xpos & 0x8000) != 0 || (v0 = (mirror_current_layer1_xpos >> 4) - 2, (int16)v0 < 0) )
+ v0 = 0;
+ Lm_SetupPipeTiles(v0 >> 4);
+ uint16 t1 = v0 >> 4;
+
+ const uint8 *plo = g_ram + r10[t1];
+ const uint8 *phi = g_ram + r10[t1] + 0x10000;
+
+ lm_vram_upload_enable_0 |= 2 * (v0 & 0xF) | ((v0 & 0x10) == 0 ? 0 : 0x400);
+ Lm_CopyTilesToL1UploadBuffer(plo, phi, v0 & 0xF | 16 * v4, v0 >> 4);
+ Lm_SetupLmVramDma_0();
+}
+
+void LmFunc_UpdateTilemapB_7(void) {
+ const uint16 *r10 = GetLayerLayoutPtr(0, misc_level_mode_setting);
+ uint16 v0 = kLm10B483[lm_arr1831b[1] >> 1] + (mirror_current_layer1_ypos >> 4);
+ lm_vram_upload_enable_0 = (v0 << 6) & 0x3FF | 0x3000;
+ Lm_SetupPipeTiles(v0 >> 4);
+ uint16 t1 = (v0 & 0x1f0) >> 4;
+ const uint8 *plo = g_ram + r10[t1];
+ const uint8 *phi = g_ram + r10[t1] + 0x10000;
+ LmFunc_109662(plo, phi, (v0 & 0xF) * 16);
+ Lm_SetupLmVramDma_0();
+}
+
+void LmFunc_UpdateTilemapC_0(void) {
+ const uint16 *r10 = GetLayerLayoutPtr(1, misc_level_mode_setting);
+ uint16 r3 = (misc_level_tileset_setting == 3 ? 0x1000 : 0);
+ uint16 v2 = kLm10B487[lm_arr1831b[2] >> 1] + (mirror_current_layer2_xpos >> 4);
+ lm_vram_upload_enable_16 = (2 * v2) & 0x1F | 0x3800 | (v2 & 0x10 ? 0x400 : 0);
+ Lm_SetupPipeTiles(v2 >> 4);
+ uint16 t1 = (v2 >> 4) & 0xF; // lm bugfix, L2 doesn't have 32 screens
+
+ const uint8 *plo = g_ram + r10[t1];
+ const uint8 *phi = g_ram + r10[t1] + 0x10000;
+
+ uint16 r8 = mirror_current_layer2_ypos & 0x3FF0;
+ lm_vram_upload_enable_16 |= (4 * r8) & 0x3C0;
+ LmFunc_CopyTilemapC_12(plo, phi, r8 | v2 & 0xF, r3);
+ Lm_SetupLmVramDma_16();
+}
+
+void LmFunc_UpdateTilemapD_0(void) {
+ const uint8 *phi = g_ram + 0x1c300, *plo = g_ram + 0x1bc00;
+ const uint16 *r10 = LmHook_CustomBgMap16();
+ uint16 r8 = ((mirror_current_layer2_ypos & 0xFFF0) + 16 * kLm10B483[lm_arr1831b[3] >> 1]) & 0x1F0;
+ lm_vram_upload_enable_6 = (4 * r8) & 0x3FF | 0x3800;
+ Lm_CopyToVramBufD_6(plo, phi, r8, r10);
+ Lm_SetupLmVramDma_6();
+}
+
+void LmFunc_UpdateTilemapD_1(void) {
+ const uint16 *r10 = GetLayerLayoutPtr(1, misc_level_mode_setting);
+
+ uint16 r3 = (misc_level_tileset_setting == 3 ? 0x1000 : 0);
+
+ uint16 t0 = kLm10B483[lm_arr1831b[3] >> 1] + ((int16)mirror_current_layer2_ypos >> 4);
+ if (sign16(t0))
+ return; // lm fix
+
+ lm_vram_upload_enable_6 = (t0 << 6) & 0x3ff | 0x3800;
+
+ uint16 t1;
+ if ((mirror_current_layer2_xpos & 0x8000u) != 0 || (t1 = (mirror_current_layer2_xpos >> 4) - 2, (t1 & 0x8000u) != 0))
+ t1 = 0;
+ Lm_SetupPipeTiles(t1 >> 4);
+ const uint8 *plo = g_ram + r10[t1 >> 4];
+ const uint8 *phi = g_ram + r10[t1 >> 4] + 0x10000;
+
+ lm_vram_upload_enable_6 |= (t1 & 0xf) * 2 | (t1 & 0x10 ? 0xC00 : 0x800);
+ LmFunc_108CB0(plo, phi, t0 * 16 | t1 & 0xf, t1 >> 4, r3);
+ Lm_SetupLmVramDma_6();
+}
+
+void LmFunc_UpdateTilemapD_2(void) {
+ const uint16 *r10 = GetLayerLayoutPtr(1, misc_level_mode_setting);
+ uint16 r3 = (misc_level_tileset_setting == 3 ? 0x1000 : 0);
+ uint16 t0 = kLm10B483[lm_arr1831b[3] >> 1] + (mirror_current_layer2_ypos >> 4);
+ lm_vram_upload_enable_6 = (t0 << 6) & 0x3ff | 0x3800;
+ const uint8 *plo = g_ram + r10[(t0 & 0x1f0) >> 4];
+ const uint8 *phi = g_ram + r10[(t0 & 0x1f0) >> 4] + 0x10000;
+ LmFunc_109C29(plo, phi, (t0 & 0xf) * 16, r3);
+ Lm_SetupLmVramDma_6();
+}
+
+
+static FuncV *const kLmHook_BufferTilemap_L1[32] = {
+ &Lm_BufferTilemap_L1_0,
+ &Lm_BufferTilemap_L1_0,
+ &Lm_BufferTilemap_L1_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &Lm_BufferTilemap_L1_1,
+ &Lm_BufferTilemap_L1_1,
+ &EmptyFunc,
+ &Lm_BufferTilemap_L1_1,
+ &EmptyFunc,
+ &Lm_BufferTilemap_L1_0,
+ &Lm_BufferTilemap_L1_1,
+ &Lm_BufferTilemap_L1_0,
+ &Lm_BufferTilemap_L1_0,
+ &EmptyFunc,
+ &Lm_BufferTilemap_L1_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &Lm_BufferTilemap_L1_0,
+ &Lm_BufferTilemap_L1_0,
+};
+
+static FuncV *const kLmHook_BufferTilemap_L2[32] = {
+ &LmHook_BufferScrollingTiles_L2_Background,
+ &LmHook_BufferScrollingTiles_L2_1,
+ &LmHook_BufferScrollingTiles_L2_1,
+ &BufferScrollingTiles_Layer2,
+ &BufferScrollingTiles_Layer2,
+ &BufferScrollingTiles_Layer2_VerticalLevel,
+ &BufferScrollingTiles_Layer2_VerticalLevel,
+ &LmHook_BufferScrollingTiles_L2_7,
+ &LmHook_BufferScrollingTiles_L2_7,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &LmHook_BufferScrollingTiles_L2_Background,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &LmHook_BufferScrollingTiles_L2_Background,
+ &LmHook_BufferScrollingTiles_L2_Background,
+ &LmHook_BufferScrollingTiles_L2_Background,
+ &LmHook_BufferScrollingTiles_L2_1,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &LmHook_BufferScrollingTiles_L2_Background,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &BufferScrollingTiles_Layer2_NoScroll,
+ &LmHook_BufferScrollingTiles_L2_Background,
+ &LmHook_BufferScrollingTiles_L2_1,
+};
+static FuncV *const kLmFunc_UpdateTilemapA[32] = {
+ &LmFunc_UpdateTilemapA_0,
+ &LmFunc_UpdateTilemapA_0,
+ &LmFunc_UpdateTilemapA_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapA_0,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapA_0,
+ &LmFunc_UpdateTilemapA_0,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapA_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapA_0,
+ &LmFunc_UpdateTilemapA_0,
+};
+static FuncV *const kLmFunc_UpdateTilemapB[32] = {
+ &LmFunc_UpdateTilemapB_0,
+ &LmFunc_UpdateTilemapB_0,
+ &LmFunc_UpdateTilemapB_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapB_7,
+ &LmFunc_UpdateTilemapB_7,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapB_7,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapB_0,
+ &LmFunc_UpdateTilemapB_7,
+ &LmFunc_UpdateTilemapB_0,
+ &LmFunc_UpdateTilemapB_0,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapB_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapB_0,
+ &LmFunc_UpdateTilemapB_0,
+};
+static FuncV *const kLmFunc_UpdateTilemapC[32] = {
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapC_0,
+ &LmFunc_UpdateTilemapC_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapC_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapC_0,
+};
+static FuncV *const kLmFunc_UpdateTilemapD[32] = {
+ &LmFunc_UpdateTilemapD_0,
+ &LmFunc_UpdateTilemapD_1,
+ &LmFunc_UpdateTilemapD_1,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapD_2,
+ &LmFunc_UpdateTilemapD_2,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapD_0,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapD_0,
+ &LmFunc_UpdateTilemapD_0,
+ &LmFunc_UpdateTilemapD_0,
+ &LmFunc_UpdateTilemapD_1,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapD_0,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &EmptyFunc,
+ &LmFunc_UpdateTilemapD_0,
+ &LmFunc_UpdateTilemapD_1,
+};
+
+void LmHook_BufferTilemap_L1(void) {
+ if (misc_game_mode >= 0x20)
+ BufferScrollingTiles_Layer1_Init();
+ else
+ kLmHook_BufferTilemap_L1[misc_level_mode_setting]();
+}
+
+void LmHook_BufferTilemap_L2(void) {
+ if (misc_game_mode >= 0x20)
+ BufferScrollingTiles_Layer2_Init();
+ else
+ kLmHook_BufferTilemap_L2[misc_level_mode_setting]();
+}
+
+void LmFunc_UpdateTilemapA() {
+ kLmFunc_UpdateTilemapA[misc_level_mode_setting]();
+}
+
+void LmFunc_UpdateTilemapB() {
+ kLmFunc_UpdateTilemapB[misc_level_mode_setting]();
+}
+
+void LmFunc_UpdateTilemapC() {
+ kLmFunc_UpdateTilemapC[misc_level_mode_setting]();
+}
+
+void LmFunc_UpdateTilemapD() {
+ kLmFunc_UpdateTilemapD[misc_level_mode_setting]();
+}
+
+
+void LmHook_CheckIfLevelTilemapsNeedScrollUpdate(void) {
+ uint8 t = lm_arr1831b[0] >> 1;
+ if ((mirror_current_layer1_xpos & 0xFFF0) != lm_arr1830b[t]) {
+ lm_arr1830b[t] = mirror_current_layer1_xpos & 0xFFF0;
+ lm_arr1830b[t ^ 1] = -1;
+ LmFunc_UpdateTilemapA();
+ }
+ t = lm_arr1831b[1] >> 1;
+ if ((mirror_current_layer1_ypos & 0xFFF0) != lm_arr1830b[t + 2]) {
+ lm_arr1830b[t + 2] = mirror_current_layer1_ypos & 0xFFF0;
+ lm_arr1830b[(t ^ 1) + 2] = -1;
+ LmFunc_UpdateTilemapB();
+ }
+ t = lm_arr1831b[2] >> 1;
+ if ((mirror_current_layer2_xpos & 0xFFF0) != lm_arr1830b[t + 4]) {
+ lm_arr1830b[t + 4] = mirror_current_layer2_xpos & 0xFFF0;
+ lm_arr1830b[(t ^ 1) + 4] = -1;
+ LmFunc_UpdateTilemapC();
+ }
+ t = lm_arr1831b[3] >> 1;
+ if ((mirror_current_layer2_ypos & 0xFFF0) != lm_arr1830b[t + 6]) {
+ lm_arr1830b[t + 6] = mirror_current_layer2_ypos & 0xFFF0;
+ lm_arr1830b[(t ^ 1) + 6] = -1;
+ LmFunc_UpdateTilemapD();
+ }
+}
+
+void Lm_SetupLmVramDma_0(void) {
+ lm_vram_dma_dst0 = lm_vram_upload_enable_0;
+ uint16 r0 = 4 * (((lm_vram_upload_enable_0 >> 1) & 0xF ^ 0xF) + 1);
+ lm_vram_dma_src0 = 7142;
+ lm_vram_dma_size0 = r0;
+ lm_vram_dma_dst1 = (lm_vram_upload_enable_0 ^ 0x400) & 0xFFC0;
+ lm_vram_dma_src1 = r0 + 0x1be6;
+ lm_vram_dma_size1 = 64;
+ lm_vram_dma_dst2 = lm_vram_upload_enable_0 | 0x20;
+ lm_vram_dma_src2 = 7270;
+ lm_vram_dma_size2 = lm_vram_dma_size0;
+ lm_vram_dma_dst3 = (lm_vram_upload_enable_0 ^ 0x400) & 0xFFC0 | 0x20;
+ lm_vram_dma_src3 = r0 + 0x1c66;
+ lm_vram_dma_size3 = 64;
+ if (lm_vram_dma_size0 != 64) {
+ lm_vram_dma_dst4 = lm_vram_upload_enable_0 & 0xFFC0;
+ lm_vram_dma_src4 = r0 + 0x1be6 + 0x40;
+ lm_vram_dma_size4 = 64 - r0;
+ lm_vram_dma_dst5 = lm_vram_upload_enable_0 & 0xFFC0 | 0x20;
+ lm_vram_dma_src5 = r0 + 0x1c66 + 0x40;
+ lm_vram_dma_size5 = 64 - r0;
+ }
+}
+
+void Lm_SetupLmVramDma_6(void) {
+ lm_vram_dma_dst6 = lm_vram_upload_enable_6;
+ uint16 r0 = 4 * (((lm_vram_upload_enable_6 >> 1) & 0xF ^ 0xF) + 1);
+ lm_vram_dma_src6 = 0x1CE8;
+ lm_vram_dma_size6 = r0;
+ lm_vram_dma_dst7 = (lm_vram_upload_enable_6 ^ 0x400) & 0xFFC0;
+ lm_vram_dma_src7 = r0 + 0x1CE8;
+ lm_vram_dma_size7 = 64;
+ lm_vram_dma_dst8 = lm_vram_upload_enable_6 | 0x20;
+ lm_vram_dma_src8 = 7528;
+ lm_vram_dma_size8 = lm_vram_dma_size6;
+ lm_vram_dma_dst9 = (lm_vram_upload_enable_6 ^ 0x400) & 0xFFC0 | 0x20;
+ lm_vram_dma_src9 = r0 + 0x1D68;
+ lm_vram_dma_size9 = 64;
+ if (lm_vram_dma_size6 != 64) {
+ lm_vram_dma_dst10 = lm_vram_upload_enable_6 & 0xFFC0;
+ lm_vram_dma_src10 = r0 + 0x1D28;
+ lm_vram_dma_size10 = 64 - r0;
+ lm_vram_dma_dst11 = lm_vram_upload_enable_6 & 0xFFC0 | 0x20;
+ lm_vram_dma_src11 = r0 + 0x1DA8;
+ lm_vram_dma_size11 = 64 - r0;
+ }
+}
+
+void Lm_SetupLmVramDma_12(void) {
+ lm_vram_dma_dst12 = lm_vram_upload_enable_12;
+ uint16 r0 = 4 * (((lm_vram_upload_enable_12 >> 6) & 0xF ^ 0xF) + 1);
+ lm_vram_dma_src12 = 0x820B;
+ lm_vram_dma_size12 = 4 * (((lm_vram_upload_enable_12 >> 6) & 0xF ^ 0xF) + 1);
+ lm_vram_dma_dst13 = lm_vram_upload_enable_12 + 1;
+ lm_vram_dma_src13 = 0x824B;
+ lm_vram_dma_size13 = lm_vram_dma_size12;
+ if (lm_vram_dma_size12 != 64) {
+ lm_vram_dma_dst14 = lm_vram_upload_enable_12 & 0xFC1F;
+ lm_vram_dma_src14 = r0 + 0x820B;
+ lm_vram_dma_size14 = 64 - r0;
+ lm_vram_dma_dst15 = (lm_vram_upload_enable_12 & 0xFC1F) + 1;
+ lm_vram_dma_src15 = r0 + 0x824B;
+ lm_vram_dma_size15 = 64 - r0;
+ }
+}
+
+void Lm_SetupLmVramDma_16(void) {
+ lm_vram_dma_dst16 = lm_vram_upload_enable_16;
+ uint16 r0 = 4 * (((lm_vram_upload_enable_16 >> 6) & 0xF ^ 0xF) + 1);
+ lm_vram_dma_src16 = 0x828B;
+ lm_vram_dma_size16 = 4 * (((lm_vram_upload_enable_16 >> 6) & 0xF ^ 0xF) + 1);
+ lm_vram_dma_dst17 = lm_vram_upload_enable_16 + 1;
+ lm_vram_dma_src17 = 0x82CB;
+ lm_vram_dma_size17 = lm_vram_dma_size16;
+ if (lm_vram_dma_size16 != 64) {
+ lm_vram_dma_dst18 = lm_vram_upload_enable_16 & 0xFC1F;
+ lm_vram_dma_src18 = r0 + 0x828B;
+ lm_vram_dma_size18 = 64 - r0;
+ lm_vram_dma_dst19 = (lm_vram_upload_enable_16 & 0xFC1F) + 1;
+ lm_vram_dma_src19 = r0 + 0x82CB;
+ lm_vram_dma_size19 = 64 - r0;
+ }
+}
+
+
+void LmHook_LevelTileAnimations(void) {
+ if (!HAS_LM_FEATURE(kLmFeature_Exanim)) {
+ HandleLevelTileAnimations();
+ return;
+ }
+ if (counter_local_frames == lm_var3) {
+ ex_anim_info_0.hdr_size = 0;
+ ex_anim_info_1.hdr_size = 0;
+ ex_anim_info_2.hdr_size = 0;
+ ex_anim_info_3.hdr_size = 0;
+ ex_anim_info_4.hdr_size = 0;
+ ex_anim_info_5.hdr_size = 0;
+ ex_anim_info_6.hdr_size = 0;
+ ex_anim_info_7.hdr_size = 0;
+ graphics_tile_anim_vramaddress3 = 0;
+ graphics_tile_anim_vramaddress2 = 0;
+ graphics_tile_anim_vramaddress1 = 0;
+ return;
+ }
+
+ lm_var3 = counter_local_frames;
+ uint8 v1 = lm_varA;
+ if ((lm_varA & 0x40) == 0) {
+ HandleLevelTileAnimations();
+ v1 = lm_varA;
+ }
+ if ((lm_varA & 0x30) != 48) {
+ ++lm_var19;
+ ex_anim_info_0.hdr_size = 0;
+ ex_anim_info_1.hdr_size = 0;
+ ex_anim_info_2.hdr_size = 0;
+ ex_anim_info_3.hdr_size = 0;
+ ex_anim_info_4.hdr_size = 0;
+ ex_anim_info_5.hdr_size = 0;
+ ex_anim_info_6.hdr_size = 0;
+ ex_anim_info_7.hdr_size = 0;
+ if ((lm_varA & 0x10) == 0) {
+ uint16 v3 = 2 * (counter_local_frames & 7);
+ if (v3 < lm_varE) {
+ LongPtr r0 = lm_ptr16;
+ uint16 v0 = 4;
+ do {
+ uint16 v5 = *(uint16 *)(kLmExanimBlob(Load24(r0)) + v3);
+ if (v5) {
+ uint16 r8 = (v3 >> 1) + 0xC0A0;
+ LmFunc_10C713((LongPtr){.bank = r0.bank, .addr = r0.addr + v3 + v5}, r8, 1, v0);
+ }
+ v3 += 16;
+ ++v0;
+ } while (v3 < lm_varE);
+ }
+ }
+ if ((lm_varA & 0x20) == 0) {
+ uint16 v6 = 2 * (counter_local_frames & 7);
+ if (v6 < lm_varC) {
+ LongPtr r0 = lm_ptr0;
+ uint16 v0 = 0;
+ uint16 r10 = 0;
+ do {
+ uint16 v8 = *(uint16 *)(kLmExanimBlob(Load24(r0)) + v6);
+ if (v8) {
+ uint16 r8 = (v6 >> 1) + 0xC080;
+ LmFunc_10C713((LongPtr){.bank = r0.bank, .addr = r0.addr + v8}, r8, 0, v0);
+ }
+ v6 += 16;
+ ++v0;
+ } while (v6 < lm_varC);
+ }
+ }
+ }
+}
+
+typedef void ParseTileAnimFunc(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a);
+
+void ParseTileAnimFunc_Null(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ // empty
+}
+
+static const uint16 kParseTileAnimFunc_1_Tab[] = {0, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0x100, 0x180,
+ 0x200, 0x280, 0x300, 0x380, 0x400, 0x10, 0x20, 0x40, 0x80};
+
+int CheckExanimTrigger(ParseTileAnimCtx *ctx, uint8 a) {
+ uint8 t;
+ switch (a) {
+ case 0: return 0;
+ case 1: return timer_blue_pswitch;
+ case 2: return timer_silver_pswitch;
+ case 3: return flag_on_off_switch;
+ case 4: return timer_star_power;
+ case 5: return counter_timer_hundreds == 0;
+ case 6: return (counter_timer_hundreds || *ctx->r8 == 0xff) ? -1 : (*ctx->r8 < *ctx->p) ? 0 : 1;
+ case 7: return counter_yoshi_coins_collected >= 5;
+ case 8: return (counter_yoshi_coins_collected < 5 || *ctx->r8 == 0xff) ? -1 : (*ctx->r8 < *ctx->p) ? 0 : 1;
+ case 0xf: assert(0); return 1;
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ t = lm_exanim_manual_triggers[a - 0x10];
+ if (t == *ctx->r8)
+ return -1;
+ *ctx->r8 = t - 1;
+ return 1;
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+ return (lm_custom_triggers >> (a - 0x20)) & 1;
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+ case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
+ if (!(lm_one_shot_triggers & 1 << (a - 0x30)))
+ return -1;
+ if (*ctx->r8 < *ctx->p || *ctx->r8 == 0xff)
+ return 0;
+ *ctx->r8 = 0xff;
+ lm_one_shot_triggers |= 1 << (a - 0x30);
+ return -1;
+ default: return 0;
+ }
+}
+
+void ParseTileAnimFunc_1(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ int trigger = CheckExanimTrigger(ctx, a);
+ if (trigger < 0)
+ return;
+ uint8 limit = *ctx->p;
+ a = *ctx->r8;
+ a = (a >= limit) ? 0xff : a;
+ *ctx->r8 = ++a;
+ a += trigger ? limit + 1 : 0;
+
+ exinfo->hdr_size = kParseTileAnimFunc_1_Tab[cmd];
+ uint16 dest = WORD(*++ctx->p);
+ if (!sign16(dest)) {
+ exinfo->dst = dest;
+ exinfo->src.bank = 0x7e;
+ exinfo->src.addr = WORD(ctx->p[(a + 1) * 2]);
+ } else {
+ exinfo->dst = dest & 0x7fff;
+ exinfo->src = (&lm_ptr10)[ctx->r10];
+ exinfo->src.addr += WORD(ctx->p[(a + 1) * 2]);
+ }
+}
+
+void ParseTileAnimFunc_10(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ ParseTileAnimFunc_1(ctx, cmd, exinfo, a);
+ exinfo->dst |= 0x8000;
+}
+
+void ParseTileAnimFunc_13(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ int trigger = CheckExanimTrigger(ctx, a);
+ if (trigger < 0)
+ return;
+ uint8 limit = *ctx->p;
+ a = *ctx->r8;
+ a = (a >= limit) ? 0xff : a;
+ *ctx->r8 = ++a;
+ a += trigger ? limit + 1 : 0;
+
+ uint16 x = WORD(*++ctx->p);
+ exinfo->dst = x;
+ int t = (a + 1) * 2;
+
+ if (!(x & 0x7f00)) {
+ exinfo->hdr_size = 0x8001;
+ exinfo->src = ctx->ptr;
+ exinfo->src.addr += t + (ctx->p - ctx->porg);
+ } else {
+ exinfo->hdr_size = (((x & 0x7f00) >> 8) + 1) | 0x8000;
+ if (!sign16(x)) {
+ exinfo->src.bank = 0x7e;
+ exinfo->src.addr = WORD(ctx->p[t]);
+ } else {
+ exinfo->src = (&lm_ptr10)[ctx->r10];
+ exinfo->src.addr += WORD(ctx->p[t]);
+ }
+ }
+}
+
+void ParseTileAnimFunc_14(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ assert(0);
+}
+
+void ParseTileAnimFunc_15(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ assert(0);
+}
+
+void ParseTileAnimFunc_16(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ assert(0);
+}
+
+void ParseTileAnimFunc_17(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ assert(0);
+}
+
+void ParseTileAnimFunc_18(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ assert(0);
+}
+
+void ParseTileAnimFunc_19(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ assert(0);
+}
+
+void ParseTileAnimFunc_1A(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ assert(0);
+}
+
+void ParseTileAnimFunc_1B(ParseTileAnimCtx *ctx, uint8 cmd, ExAnimationInfo *exinfo, uint8 a) {
+ assert(0);
+}
+
+static ParseTileAnimFunc *const kkParseTileAnimsFuncs[28] = {
+ &ParseTileAnimFunc_Null,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_1,
+ &ParseTileAnimFunc_10,
+ &ParseTileAnimFunc_10,
+ &ParseTileAnimFunc_10,
+ &ParseTileAnimFunc_13,
+ &ParseTileAnimFunc_14,
+ &ParseTileAnimFunc_15,
+ &ParseTileAnimFunc_16,
+ &ParseTileAnimFunc_17,
+ &ParseTileAnimFunc_18,
+ &ParseTileAnimFunc_19,
+ &ParseTileAnimFunc_1A,
+ &ParseTileAnimFunc_1B,
+};
+
+void LmFunc_10C713(LongPtr p, uint16 r8, uint8 r10, uint16 k) {
+ const uint8 *pp = kLmExanimBlob(Load24(p));
+ ParseTileAnimCtx ctx = {.p = pp, .porg = pp, .ptr = p, .r8 = g_ram + 0x10000 + r8, .r10 = r10};
+
+ uint8 cmd = ctx.p[0];
+ uint8 arg = ctx.p[1];
+ ctx.p += 2;
+ kkParseTileAnimsFuncs[cmd](&ctx, cmd, &ex_anim_info_0 + k, arg);
+}
+
+void LmHook_SetStandardPPUSettings(void) {
+ WriteReg(SETINI, 0);
+ WriteReg(MOSAIC, 0);
+ WriteReg(BG1SC, 0x31u);
+ WriteReg(BG2SC, 0x39u);
+ WriteReg(BG3SC, 0x53u);
+ WriteReg(BG12NBA, 0);
+ WriteReg(BG34NBA, 4u);
+ mirror_bg1_and2_window_mask_settings = 0;
+ mirror_bg3_and4_window_mask_settings = 0;
+ mirror_object_and_color_window_settings = 0;
+ WriteReg(WBGLOG, 0);
+ WriteReg(WOBJLOG, 0);
+ WriteReg(TMW, 0);
+ WriteReg(TSW, 0);
+ mirror_color_math_initial_settings = 2;
+ WriteReg(M7SEL, 0x80u);
+}
+
+void LmHook_HandleStandardLevelCameraScroll() {
+ lm_var8325 = mirror_current_layer2_ypos;
+ lm_var8323 = mirror_current_layer2_xpos;
+ lm_var8321 = mirror_current_layer1_ypos;
+ lm_var831f = mirror_current_layer1_xpos;
+}
+
+void LmHook_HandleStandardLevelCameraScrollB(void) {
+ uint8 kShifts[] = { 0, 1, 5, 2, 3, 4, 6 };
+ uint16 x = mirror_current_layer1_xpos;
+ if (flag_layer2_horiz_scroll_level_setting != 0)
+ mirror_current_layer2_xpos = mirror_current_layer1_xpos >> kShifts[flag_layer2_horiz_scroll_level_setting - 1];
+ if (flag_layer2_vert_scroll_level_setting != 0)
+ mirror_current_layer2_ypos = (mirror_current_layer1_ypos >> kShifts[flag_layer2_vert_scroll_level_setting - 1]) + camera_layer2_ypos_relative_to_layer1;
+}
+
+void LmHook_HandleStandardLevelCameraScrollC(void) {
+ for (int i = 3; i >= 0; --i ) {
+ uint16 v2 = (&mirror_current_layer1_xpos)[i];
+ get_PointU16(misc_layer1_pos, i * 2)->x = v2;
+ if ( v2 != lm_arr1831f[i] ) {
+ lm_arr1831b[i] = (int16)(v2 - lm_arr1831f[i]) < 0 ? 0 : 2;
+ }
+ }
+}
+
+uint16 LmHook_HandleStandardLevelCameraScrollD(void) {
+ uint16 a = lm_level_height + (extra_flags_and_horiz_level_mode & 0x40 ? 15 : 0) - 0xf0;
+ if (sign16(a))
+ a = 0;
+ return a;
+}
+
+uint16 LmHook_HandleStandardLevelCameraScrollG(uint16 r2, uint16 r4) {
+ if (!sign16((r2 + 6) ^ -6))
+ r2 = -6;
+ r2 += mirror_current_layer1_ypos;
+ if (sign16(r2 - r4))
+ r2 = r4;
+ return r2;
+}
+
+uint16 LmHook_LoadStripeImage(uint16 r3) {
+ uint16 r9, r11;
+
+ if (misc_game_mode != 20 && misc_game_mode != 7 && misc_game_mode != 19 && misc_game_mode != 5)
+ return r3; // Org code
+
+ if ((r3 & 0x7000) != 0x2000) {
+ if ((r3 & 0x7000) != 0x3000)
+ return r3;
+ r11 = (r3 >> 5) & 0x1F | 4 * ((r3 & 0x800) >> 8);
+ r9 = ((mirror_current_layer2_ypos >> 3) - 2) & 0x3F;
+ if ( ((r9 + 32) & 0x40) != 0 ) {
+ if ( r11 < r9 && (uint8)((r9 + 32) & 0x3F) < r11 )
+ goto LABEL_23;
+ } else if ( r11 < r9 || (uint8)(r9 + 32) < r11 ) {
+ goto LABEL_23;
+ }
+ return r3 & 0x7FF | 0x3800;
+ } else {
+ r11 = (r3 >> 5) & 0x1F | 4 * ((r3 & 0x800) >> 8);
+ r9 = ((mirror_current_layer1_ypos >> 3) - 2) & 0x3F;
+ if (((r9 + 32) & 0x40) == 0 ) {
+ if ( r11 < r9 || (uint8)(r9 + 32) < r11 )
+ goto LABEL_23;
+ return r3 & 0x7FF | 0x3000;
+ }
+ if ( r11 >= r9 || ((r9 + 32) & 0x3F) >= r11 )
+ return r3 & 0x7FF | 0x3000;
+ }
+LABEL_23:
+ return 0xffff; // skip this
+}
+
+void LmHook_GameMode0C_LoadOverworld(uint16 k) {
+ uint32 addr = LM_FEATURES->kLmLvlInfo_addr_other;
+ if (addr == 0)
+ return;
+ lm_level_info.addr = addr + k * 32;
+ lm_level_info.bank = addr >> 16;
+ lm_var9 = 0x42;
+ lm_varB = 0;
+}
+
+bool LmHook_WantEraseSprite(uint16 k, uint16 y) {
+ if (!sign16(y - lm_level_height))
+ return true;
+ y -= mirror_current_layer1_ypos;
+ if (sign16(y - max_y_offset_from_screen_to_spawn) && !sign16(y - min_y_offset_from_screen_to_spawn))
+ return false;
+ if (spr_property_bits167a[k] & 4 || misc_nmito_use_flag == 0x80)
+ return false;
+ return true;
+}
+
+uint16 LmHook_LoadLevelInfo_C(uint16 a) {
+ if (misc_intro_level_flag)
+ return a;
+
+ a = ow_level_number_lo;
+ if (a >= 0x25)
+ a += 0x100 - 0x24;
+ return a;
+}
+
+uint16 LmHook_LoadLevelInfo_A(uint16 a, uint16 k) {
+ if (!g_lunar_magic)
+ return a;
+
+ uint8 f = misc_subscreen_exit_properties[k];
+ if (!(f & 4)) {
+ misc_level_header_entrance_settings = 0;
+ return (a & 0xff) | (ow_level_number_lo >= 0x25) << 8;
+ }
+ flag_use_secondary_entrance = (f >> 1) & 1;
+ misc_level_header_entrance_settings = (f & 8) << 3;
+ return ((f & 1) | (f >> 4) << 1) << 8 | (a & 0xff);
+}
+
+void LmHook_ExpandLvlHdr(uint16 j) {
+ if (!HAS_LM_FEATURE(kLmFeature_LoadLevel))
+ return;
+
+ uint8 R4_ = kLm6FC00[j];
+ lm_var13CD = kLm6FE00[j];
+ uint8 v2 = kLm5DE00[j];
+ misc_level_header_entrance_settings |= v2 & 0xC0;
+ if ((v2 & 0x20) != 0) {
+ uint8 v3 = 8 * (v2 & 0x18);
+ LOBYTE(player_xpos) = 2 * v3;
+ HIBYTE(player_xpos) = 4 * v3;
+ LOBYTE(player_xpos) = (16 * kLevelInfo_05F200[j]) & 0x70 | (2 * v3);
+ LOBYTE(player_ypos) = 16 * kLevelInfo_05F000[j];
+ HIBYTE(player_ypos) = R4_ & 0x3F;
+ }
+}
+
+
+void LmStdObj22_DirectMap16(uint8 k) {
+ LmHandleDirectMapObjs(0);
+}
+
+void LmStdObj23(uint8 k) {
+ LmHandleDirectMapObjs(1);
+}
+
+void LmHandleDirectMapObjsInner(uint8 r0, uint8 r1, uint8 r2, uint8 r3) {
+ LmHook_PreserveLevelDataPointerInObjects();
+
+ uint8 j = blocks_sub_scr_pos;
+ do {
+ uint8 r2cur = r2;
+ do {
+ uint8 *p = ptr_lo_map16_data + j;
+ p[0x0] = r0;
+ p[0x10000] = r1;
+
+ if ((++j & 0xf) == 0)
+ j = LmHook_HandleHorizontalSubScreenCrossingForCurrentObject_Entry2();
+ } while ((int8)--r2cur >= 0);
+ LmHook_RestoreLevelDataPointerInObjects();
+ j = LmHook_HandleVerticalSubScreenCrossingForCurrentObject();
+ } while ((int8)--r3 >= 0);
+}
+
+void LmHandleDirectMapObjs(uint8 a) {
+ uint8 r1 = a;
+ uint8 r0 = *ptr_layer1_data++;
+ uint8 r2 = blocks_size_or_type & 0xf;
+ uint8 r3 = blocks_size_or_type >> 4;
+ LmHandleDirectMapObjsInner(r0, r1, r2, r3);
+}
+
+void LmStdObj24(uint8 k) {
+ lunar_magic_FD = blocks_sub_scr_pos;
+ lunar_magic_FC = blocks_size_or_type;
+}
+
+void LmStdObj25(uint8 k) {
+ lunar_magic_FA = blocks_sub_scr_pos;
+ lunar_magic_FB = blocks_size_or_type;
+}
+
+void LmStdObj26_MusicBypass(uint8 k) {
+ if (blocks_sub_scr_pos)
+ misc_music_register_backup = blocks_sub_scr_pos - 1;
+ if (blocks_size_or_type)
+ misc_music_register_backup = blocks_size_or_type - 1;
+}
+
+void LmStdObj27(uint8 k) {
+ uint8 a = *ptr_layer1_data++;
+ if ((a & 0xc0) == 0) {
+ LmHandleDirectMapObjs(a);
+ } else {
+ LmFunc_DF1C3(a, a & 0x3f);
+ }
+}
+
+void LmFunc_DF1C3(uint8 k, uint8 a) {
+ uint16 r0 = a << 8 | *ptr_layer1_data++;
+ uint16 r4 = r0;
+ uint16 r6 = r0;
+ uint8 v5, v6;
+
+ uint8 r2 = blocks_size_or_type & 0xF;
+ uint8 r3 = blocks_size_or_type >> 4;
+ if ((k & 0x80u) == 0) {
+ v5 = blocks_size_or_type;
+ v6 = blocks_size_or_type;
+ } else {
+ v5 = *ptr_layer1_data++;
+ v6 = v5;
+ if (k & 0x40) {
+ r3 = *ptr_layer1_data++;
+ r2 = blocks_size_or_type & 0x7F;
+ if ((blocks_size_or_type & 0x80u) != 0) {
+ uint8 f = *ptr_layer1_data++;
+
+ if (lm_state_array[f >> 3 & 0xf] & (1 << (f & 7))) {
+ if (f & 0x80) {
+ r0 += 0x100;
+ r4 += 0x100;
+ r6 += 0x100;
+ }
+ } else {
+ if (!(f & 0x80))
+ return;
+ }
+ }
+ v5 = v6;
+ if (!v6) {
+ LmHandleDirectMapObjsInner(r0, r0 >> 8, r2, r3);
+ return;
+ }
+ }
+ }
+ uint8 r8 = v5 & 0xF;
+ uint8 r10 = v5 & 0xF;
+ uint8 r9 = v6 >> 4;
+ blocks_object_number = v6 >> 4;
+ LmHook_PreserveLevelDataPointerInObjects();
+ uint8 v9 = r2;
+ uint8 v10 = blocks_sub_scr_pos;
+
+ do {
+ while (1) {
+ ptr_lo_map16_data[v10 + 0x10000] = r4 >> 8;
+ ptr_lo_map16_data[v10] = r4;
+ uint8 v11 = r4;
+ if ((--v9 & 0x80u) != 0)
+ break;
+ uint8 v12 = v11 + 1;
+ if ((--r10 & 0x80u) != 0) {
+ r10 = r8;
+ v12 = r6;
+ }
+ r4 = (r4 & 0xff00) | v12;
+ if ((++v10 & 0xF) == 0)
+ v10 = LmHook_HandleHorizontalSubScreenCrossingForCurrentObject_Entry2();
+ }
+ r10 = r8;
+ uint16 v13;
+ if ((--blocks_object_number & 0x80u) != 0) {
+ blocks_object_number = r9;
+ v13 = r0;
+ } else {
+ v13 = r6 + 16;
+ }
+ r4 = v13;
+ r6 = v13;
+ LmHook_RestoreLevelDataPointerInObjects();
+ v10 = LmHook_HandleVerticalSubScreenCrossingForCurrentObject();
+ v9 = r2;
+ } while ((int8)--r3 >= 0);
+}
+
+void LmStdObj28(uint8 k) {
+ if ((blocks_size_or_type & 0x80) != 0 || !counter_sublevels_entered) {
+ counter_timer_ones = blocks_sub_scr_pos & 0xF;
+ counter_timer_tens = blocks_sub_scr_pos >> 4;
+ counter_timer_hundreds = blocks_size_or_type & 0xF;
+ }
+}
+
+void LmStdObj29(uint8 k) {
+ uint8 t = *ptr_layer1_data++;
+ if ((t & 0xc0) == 0)
+ LmHandleDirectMapObjs(t | 0x40);
+ else
+ LmFunc_DF1C3(t, t & 0x3f | 0x40);
+}
+
+bool LmHook_CustomTitleScreenDemo(void) {
+ uint16 v0;
+ uint8 v1;
+ uint8 v2;
+
+ if ( !misc_title_screen_movement_data_index ) {
+ lm_title_screen_var = 0;
+ misc_title_screen_movement_data_index = 1;
+ }
+ v0 = lm_title_screen_var;
+ if ( !--timer_title_screen_input_timer ) {
+ timer_title_screen_input_timer = kLmTitleScreenMoves[lm_title_screen_var + 2];
+ v0 = lm_title_screen_var + 3;
+ lm_title_screen_var += 3;
+ }
+ v1 = kLmTitleScreenMoves[v0 - 3];
+ if ( v1 != 255 ) {
+ io_controller_hold1 = v1;
+ io_controller_press1 = v1 & 0x3F;
+ v2 = kLmTitleScreenMoves[v0 - 2];
+ io_controller_press1 |= (16 * v2) & 0xC0;
+ io_controller_hold2 = v2 & 0xB0;
+ io_controller_press2 = (2 * v2) & 0x80;
+ return true;
+ }
+ return false;
+}
+
+void LmHook_InitializeSaveData(void) {
+ if (kLmInitSaveData_SIZE)
+ memcpy(ow_save_buffer, kLmInitSaveData, 96);
+}
+
+void LmFunc13_SwitchBlock(uint8 j) {
+ uint8 v1; // si
+ char i; // di
+ OamEnt *oam; // rbx
+
+ misc_color_of_palace_switch_pressed1 = j + 1;
+ v1 = 16 * j;
+ uint16 r0 = 0;
+ for ( i = 28; i >= 0; i -= 4 ) {
+ oam = get_OamEnt(oam_buf, i);
+ WORD(oam->charnum) = kDisplayMessage_SwitchBlockTileAndProperties[v1 >> 1];
+ WORD(oam->xpos) = WORD(kDisplayMessage_SwitchBlockXAndYDisp[r0]);
+ v1 += 2;
+ r0 += 2;
+ }
+ WORD(*oam_buf_ext) = 0;
+}
+
+void LmHook_DisplayMessage(void) {
+ uint16 v0; // di
+ uint16 v1; // si
+ uint16 v2; // di
+ uint16 v3; // si
+ uint16 v4; // si
+ uint8 v5; // al
+ uint16 v6; // [rsp+45h] [rbp-3h]
+ uint8 r3 = 0; // wtf
+
+ if ( misc_display_message == 3 ) {
+ v1 = 0;
+ v0 = 1;
+ } else {
+ v1 = ow_level_number_lo;
+ if ( ow_level_number_lo == kLmDisplayMessage_Tab1[0]) {
+ v0 = player_riding_yoshi_flag != 0;
+ } else {
+ v0 = misc_display_message - 1;
+ if ( misc_display_message == 1 ) {
+ if ( ow_level_number_lo == kLmDisplayMessage_Tab1[1]
+ || (v0 = 1, ow_level_number_lo == kLmDisplayMessage_Tab1[2])
+ || (v0 = 2, ow_level_number_lo == kLmDisplayMessage_Tab1[3])
+ || (v0 = 3, ow_level_number_lo == kLmDisplayMessage_Tab1[4]) ) {
+ LmFunc13_SwitchBlock(v0);
+ }
+ v0 = 0;
+ }
+ }
+ }
+ uint16 r0 = kLmDisplayMessage_3BE80[(2 * v1 + v0)];
+ v2 = stripe_image_upload;
+ v3 = 14;
+ uint16 r2 = 0;
+ do {
+ WORD(stripe_image_upload_data[v2]) = kLmDisplayMessage_3BC7F[v3 >> 1];
+ WORD(stripe_image_upload_data[v2 + 2]) = 8960;
+ v6 = v3;
+ r2 = 18;
+ v4 = r0;
+ do {
+ v5 = 31;
+ if ( (r3 & 0x80u) == 0 ) {
+ v5 = kLmDisplayMessage_Tab0[v4++];
+ if ( v5 == 0xFE ) {
+ r3 = -2;
+ v5 = 31;
+ }
+ }
+ stripe_image_upload_data[v2 + 4] = v5;
+ stripe_image_upload_data[v2 + 5] = 57;
+ v2 += 2;
+ } while ( --r2 );
+ r0 = v4;
+ v2 += 4;
+ v3 = v6 - 2;
+ } while ( (int16)v3 >= 0 );
+ WORD(stripe_image_upload_data[v2]) = 255;
+ stripe_image_upload = v2;
+ mirror_layer3_xpos = 0;
+ mirror_layer3_ypos = 0;
+ flag_disable_layer3_scroll = 1;
+}
+
+void LmHook_OverworldPalette(void) {
+ uint16 v2 = (misc_level_tileset_setting & 0xF) - 1;
+ if ( ow_level_tile_settings[73] & 0x80 )
+ v2 += 7;
+ MemCpy(palettes_palette_mirror, kLmOverworldPal + v2 * 0x200, 0x200u);
+}
+
+void LmHook_LevelNamesPatch(uint16 a) {
+ uint16 v1; // si
+ uint16 v2; // di
+
+ uint16 r0 = 16 * a;
+ v1 = 16 * a + 3 * a;
+ v2 = stripe_image_upload;
+ uint16 r2 = stripe_image_upload + 38;
+ stripe_image_upload += 42;
+ WORD(stripe_image_upload_data[v2 + 2]) = 0x2500;
+ WORD(stripe_image_upload_data[v2]) = 0x8B50;
+ do
+ {
+ stripe_image_upload_data[v2 + 4] = kLmLevelNamesPatch[v1];
+ stripe_image_upload_data[v2 + 5] = 57;
+ v2 += 2;
+ ++v1;
+ } while ( v2 < r2);
+ stripe_image_upload_data[v2 + 4] = -1;
+}
+
+int LmHook_LoadLevelInfo_E(uint16 k, uint16 lvl, uint8 r0, uint8 r1) {
+ uint8 f = kLm5FE00[k];
+ misc_level_header_entrance_settings |= f & 0x87;
+ uint8 r15 = (f & 8) >> 3;
+ uint8 r2 = kLmLevelData5DC85[k];
+ uint8 r4 = r2 & 0x7F;
+ uint8 g = kLmLevelData5DC8A[k];
+ lm_var13CD = g & 0xC0;
+ misc_level_header_entrance_settings |= 2 * (g & 0x20);
+ r4 |= kLm6FC00[lvl] & 0x80;
+ lm_var13CD = kLm6FE00[lvl] & 0x3F | g & 0xC0;
+ if ((f & 0x40) != 0) {
+ player_xpos = 8 * (f & 0x30) | (r1 >> 1) & 0x70;
+ LOBYTE(player_ypos) = 16 * r0;
+ HIBYTE(player_ypos) = r2 & 0x3F;
+ }
+ if ((r2 & 0x80) != 0) {
+ misc_game_mode = 12;
+ mirror_screen_display_register = 0;
+ misc_mosaic_direction = 0;
+ mirror_mosaic_size_and_bgenable = 0;
+ if ((f & 0x10) != 0) {
+ ow_star_pipe_index = r0;
+ ++ow_warping_on_pipe_or_star_flag;
+ }
+ if ((f & 0x20) != 0) {
+ ow_current_event_number = r1;
+ }
+ uint8 v3 = f & 7;
+ if (v3 == 7)
+ v3 = 0x80;
+ misc_exit_level_action = v3;
+ if (2 * v3) {
+ ++flag_got_midpoint;
+ ++counter_enemy_rollcall_screen;
+ }
+ return -1;
+ } else {
+ return r0 >> 4;
+ }
+}
+
+uint16 LmHook_DestroyTileAnimation2(uint16 a) {
+ return a + (((a & 0x3E0) == 0x3E0) ? 0x420 : 0x20);
+}
+
+const uint8* LmHook_DestroyTileAnimation3(uint16 k) {
+ return (uint8*)Lm_GetMap16RomAddr(blocks_map16_table_hi[k] << 8 | blocks_map16_table_lo[k]);
+}
+
+uint16 LmHook_RemapDestroyTile(uint16 a) {
+ a += 0x10;
+ if ((uint8)a < 0x10)
+ a += 0x100;
+ return a;
+}
+
+void LmHook_EventStuff(uint8 a, bool from_where) {
+
+ uint16 r6 = kLmEventStuff1[a];
+ uint16 r4 = kLmEventStuff1[a + 1];
+
+ uint16 j = r4 - r6;
+ if (j == 0)
+ return;
+ uint16 k = r6;
+
+ do {
+ uint16 r0 = kLmEventStuff2[k >> 1];
+ uint16 r4 = kLmEventStuff3[k >> 1];
+ uint8 a = kLmEventStuff4[k >> 1];
+ if (a & 1) {
+ if (from_where)
+ BufferEventTileToLayer2Tilemap_Entry2(k, r0, r4);
+ } else {
+ blocks_map16_table_lo[r4] = r0;
+ blocks_map16_table_hi[r4] = r0 >> 8;
+ }
+ } while (k += 2, j -= 2);
+}
+
+
+#define wallkick_flags g_ram[0x61]
+#define wallkick_no_back_timer g_ram[0x62]
+#define wallkick_temp_y_spd g_ram[0x63]
+
+void HackHandleWalljump() {
+ uint8 v0;
+ uint8 v1;
+ bool v2;
+ uint8 v3;
+ uint8 v4;
+
+ if ((player_blocked_flags & 4) != 0) {
+ wallkick_flags = 0;
+ return;
+ }
+ if ((wallkick_flags & 3) == 0) {
+ if (wallkick_no_back_timer) {
+ --wallkick_no_back_timer;
+ io_controller_hold1 &= ~(wallkick_flags >> 2);
+ io_controller_press1 &= ~(wallkick_flags >> 2);
+ }
+ if ((player_yspeed & 0x80u) == 0 &&
+ !(player_riding_yoshi_flag |
+ (uint8)(timer_end_level | player_carrying_something_flag1 | player_spin_jump_flag | player_cape_flying_phase |
+ player_swimming_flag | player_climbing_flag | player_ducking_flag | player_current_state)) &&
+ (uint8)player_on_screen_pos_x >= 9u && (uint8)player_on_screen_pos_x < 0xE8u &&
+ (player_blocked_flags & (wallkick_flags >> 2)) == 0 && (io_controller_hold1 & 3) != 3 &&
+ (player_blocked_flags & io_controller_hold1) != 0) {
+ wallkick_flags = player_blocked_flags & io_controller_hold1;
+ wallkick_temp_y_spd = player_yspeed;
+ }
+ return;
+ }
+ if (player_riding_yoshi_flag | (uint8)(player_carrying_something_flag1 | player_swimming_flag | player_current_state) ||
+ (uint8)(player_xspeed + 7) >= 0xFu || (io_controller_hold1 & 3) == 3 || (wallkick_flags & io_controller_hold1) == 0) {
+ wallkick_flags = 0;
+ return;
+ }
+ io_controller_hold1 &= ~0x40u;
+ io_controller_press1 &= ~0x40u;
+ player_facing_direction = wallkick_flags - 1;
+ if ((io_controller_press1 & 0x80u) != 0) {
+ io_sound_ch2 = 1;
+ } else {
+ if ((io_controller_press2 & 0x80u) == 0) {
+ if ((counter_local_frames & 7) == 0) {
+ v0 = player_facing_direction;
+ v1 = 3;
+ while (smoke_spr_spriteid[v1]) {
+ if ((--v1 & 0x80u) != 0)
+ goto LABEL_27;
+ }
+ smoke_spr_spriteid[v1] = 3;
+ static const uint8 kWallKickSmokeXOffs[2] = {12, -2};
+ smoke_spr_xpos_lo[v1] = kWallKickSmokeXOffs[v0] + player_xpos;
+ smoke_spr_ypos_lo[v1] = player_ypos + 16;
+ smoke_spr_timer[v1] = 19;
+ }
+LABEL_27:
+ player_current_pose = 13;
+ v2 = (char)(wallkick_temp_y_spd + 4) < 0;
+ v3 = wallkick_temp_y_spd + 4;
+ player_yspeed = wallkick_temp_y_spd + 4;
+ wallkick_temp_y_spd += 4;
+ if (!v2 && v3 >= 0x24u) {
+ player_yspeed = 36;
+ wallkick_temp_y_spd = 36;
+ }
+ return;
+ }
+ ++player_spin_jump_flag;
+ io_sound_ch3 = 4;
+ }
+ ++camera_bounce_off_spring_flag;
+ io_sound_ch1 = 1;
+ player_in_air_flag = 11;
+ player_yspeed = -72;
+ static const uint8 kWallKickXSpeed[2] = { -32, 32 };
+ player_xspeed = kWallKickXSpeed[player_facing_direction];
+ io_controller_hold1 &= ~wallkick_flags;
+ io_controller_press1 &= ~wallkick_flags;
+ wallkick_flags *= 4;
+ wallkick_no_back_timer = 16;
+ v4 = 3;
+ while (smoke_spr_spriteid[v4]) {
+ if ((--v4 & 0x80u) != 0)
+ return;
+ }
+ smoke_spr_spriteid[v4] = 1;
+ smoke_spr_xpos_lo[v4] = player_xpos;
+ smoke_spr_ypos_lo[v4] = player_ypos + 16;
+ smoke_spr_timer[v4] = 16;
+}
+
+uint8 LmFunc_ReadLevelInfoByte(const uint8 *p) {
+ return p[0] & 0xf0 | p[-2] >> 4;
+}
+
+static const uint16 kLmUploadGfx_Tab0[4] = { 0x140, 0, 0x100, 0};
+static const uint16 kLmUploadGfx_Tab1[4] = { 0x2000, 0x1000, 0x800, 0};
+static const uint16 kLmUploadGfx_Tab2[4] = { 0x50A0, 0x5000, 0x5080, 0x5800};
+
+void LmFunc_UploadGraphics_StepA(void) {
+ if (lm_var9 != 0x42 && lm_var9 != 0x41) {
+ lm_word_7E145E = 0;
+ lm_var1a = 0;
+ lm_var1b = 0;
+ lm_var1c = 0;
+ return;
+ }
+ const uint8 *t8a = (const uint8 *)GetLvlInfo();
+ lm_var1a = t8a[0x17] >> 4;
+ lm_var1c = LmFunc_ReadLevelInfoByte(t8a + 0x15);
+ lm_var1b = LmFunc_ReadLevelInfoByte(t8a + 7);
+ lm_word_7E145E = LmFunc_ReadLevelInfoByte(t8a + 0x1f) << 8 | LmFunc_ReadLevelInfoByte(t8a + 0x1b);
+ if (t8a[1] & 0x20) {
+ uint16 v2 = WORD(t8a[2]);
+ if ((v2 & 0xfff) != 0x7f) {
+ uint16 r0 = kLmUploadGfx_Tab0[(v2 >> 14) & 3];
+ uint16 v5 = kLmUploadGfx_Tab1[(v2 >> 12) & 3];
+ uint16 v6 = kLmUploadGfx_Tab2[(v2 >> 14) & 3];
+ if (v5 <= 0x1000) {
+ LmFunc15_DecompressSlotB(1);
+ SmwCopyToVram(v6, graphics_graphic_decompression_buffer + r0, v5 - r0);
+ } else {
+ SmwCopyToVram(0x4000, graphics_graphic_decompression_buffer + 0x1000, 0x1000);
+ LmFunc15_DecompressSlotB(1);
+ SmwCopyToVram(v6, graphics_graphic_decompression_buffer + r0, v5 - r0);
+ SmwCopyFromVram(0x4000, graphics_graphic_decompression_buffer + 0x1000, 0x1000);
+ }
+ }
+ lm_var1a |= 0x80;
+ }
+}
+
+uint16 LmFunc_10D796(uint8 r11, uint16 *r7, uint16 *r9) {
+ if (r11 == 1) {
+ *r7 = 0x404;
+ return 8;
+ } else if (r11 == 3) {
+ *r9 = 0x101;
+ *r7 = 0x5959;
+ return 8;
+ }
+ return 0;
+}
+
+void LmFunc_10D7BC(uint16 k, uint16 *r1, uint16 *r4, uint16 r7, uint16 r9) {
+ uint16 v1 = 0x1e00;
+ do {
+ r1[v1 >> 1] = r7;
+ if (r9)
+ r4[v1 >> 1] = r9;
+ v1 += 2;
+ } while ( --k );
+}
+
+void LmFunc_10D7CF(uint16 k, uint16 *r1, uint16 *r4, uint16 r7, uint16 r9) {
+ uint16 r14 = 16;
+ uint16 t = 0x1c00;
+ do {
+ uint16 v1 = t;
+ uint16 kcur = k;
+ do {
+ r1[v1 >> 1] = r7;
+ if (r9)
+ r4[v1 >> 1] = r9;
+ v1 += 2;
+ } while (--kcur);
+ t += 0x1b0;
+ } while (--r14);
+}
+
+void LmFunc_10D7FA(uint16 k, uint16 r1_value, uint16 *r1, uint16 *r4, uint16 r7, uint16 r9) {
+ uint16 j = 256;
+ uint16 t = 256;
+ for (;;) {
+ uint16 kcur = k;
+ do {
+ r1[j >> 1] = r7;
+ if (r9)
+ r4[j >> 1] = r9;
+ j += 2;
+ } while (--kcur);
+ bool v2 = __CFADD__(lm_level_height, t);
+ t += lm_level_height;
+ j = t;
+ if ((t + r1_value) >= 0x10000 || (t + r1_value + lm_level_height) > 0x10000)
+ return;
+ }
+}
+
+
+void LmHook_InitializeLevelLayer3_GenerateInteractiveTideWater(void) {
+ static const uint16 kword_10D776[16] = {
+ 0, 5, 5, 5, 0x130, 0x200, 0x201, 0x202,
+ 0x203, 0x204, 0x205, 0x206, 0x207, 0x208, 0x209, 0x20A,
+ };
+ uint16 *r1, *r4;
+ uint8 r11 = lm_var1b & 0xF;
+
+ r1 = (uint16 *)(g_ram + 0xc800);
+ r4 = (uint16 *)(g_ram + 0x1c800);
+
+ uint16 v1 = kword_10D776[r11];
+ uint16 r7 = (uint8)(v1) * 0x101;
+ uint16 r9 = (uint8)(v1 >> 8) * 0x101;
+ if (misc_level_layout_flags & 1) {
+ misc_level_layout_flags |= 2;
+ LmFunc_10D7BC(0xd00, r1, r4, r7, r9);
+ uint16 v2 = LmFunc_10D796(r11, &r7, &r9);
+ if (v2)
+ LmFunc_10D7BC(v2, r1, r4, r7, r9);
+ } else if (HAS_LM_FEATURE(kLmFeature_LoadLevel)) {
+ r1 = (uint16 *)(g_ram + L2_Screen_Lo[0].addr);
+ r4 = (uint16 *)(g_ram + L2_Screen_Hi[0].addr + 0x10000);
+ if (lm_level_height >= 0x110) {
+ LmFunc_10D7FA((lm_level_height - 0x100) >> 1, L2_Screen_Lo[0].addr, r1, r4, r7, r9);
+ uint16 v2 = LmFunc_10D796(r11, &r7, &r9);
+ if (v2)
+ LmFunc_10D7FA(v2, L2_Screen_Lo[0].addr, r1, r4, r7, r9);
+ }
+ } else {
+ LmFunc_10D7CF(0x58, r1, r4, r7, r9);
+ uint16 v2 = LmFunc_10D796(r11, &r7, &r9);
+ if (v2)
+ LmFunc_10D7CF(v2, r1, r4, r7, r9);
+ }
+ misc_level_layout_flags |= 0x80u;
+}
+
+void LmFunc_UpdateBG12NBA(void) { // FF9E0
+ // not used
+}
+
diff --git a/src/main.c b/src/main.c
index 624719d..e7af279 100644
--- a/src/main.c
+++ b/src/main.c
@@ -826,19 +826,41 @@ static void HandleGamepadAxisInput(int gamepad_id, int axis, int value) {
const uint8 *g_asset_ptrs[kNumberOfAssets];
uint32 g_asset_sizes[kNumberOfAssets];
-static void LoadAssets() {
- size_t length = 0;
- uint8 *data = ReadWholeFile("assets/smw_assets.dat", &length);
- if (!data)
- data = ReadWholeFile("smw_assets.dat", &length);
- if (!data) Die("Failed to read smw_assets.dat. Please see the README for information about how you get this file.");
-
+static bool VerifyAssetsFile(const uint8 *data, size_t length) {
static const char kAssetsSig[] = { kAssets_Sig };
-
if (length < 16 + 32 + 32 + 8 + kNumberOfAssets * 4 ||
memcmp(data, kAssetsSig, 48) != 0 ||
- *(uint32*)(data + 80) != kNumberOfAssets)
- Die("Invalid assets file");
+ *(uint32 *)(data + 80) != kNumberOfAssets)
+ return false;
+ return true;
+}
+
+static const char *kAssetFileCandidates[] = {
+ "smw_assets.dat",
+ "assets/smw_assets.dat"
+};
+
+static void LoadAssets() {
+ const char *verify_failed = NULL;
+
+ size_t length = 0;
+ uint8 *data = NULL;
+ for (int i = 0; i < 2 && data == NULL; i++) {
+ data = ReadWholeFile(kAssetFileCandidates[i], &length);
+ if (data && !VerifyAssetsFile(data, length)) {
+ verify_failed = kAssetFileCandidates[i];
+ free(data);
+ data = NULL;
+ }
+ }
+
+ if (!data) {
+ if (verify_failed)
+ Die("Invalid assets file - Please re run 'python assets/restool.py'");
+ else
+ Die("Failed to read smw_assets.dat. Please see the README for information about how you get this file.");
+ }
+
uint32 offset = 88 + kNumberOfAssets * 4 + *(uint32 *)(data + 84);
@@ -857,6 +879,10 @@ MemBlk FindInAssetArray(int asset, int idx) {
return FindIndexInMemblk((MemBlk) { g_asset_ptrs[asset], g_asset_sizes[asset] }, idx);
}
+const uint8 *FindPtrInAsset(int asset, uint32 addr) {
+ return FindAddrInMemblk((MemBlk){g_asset_ptrs[asset], g_asset_sizes[asset]}, addr);
+}
+
// Go some steps up and find smw.ini
static void SwitchDirectory(void) {
char buf[4096];
diff --git a/src/smw.vcxproj b/src/smw.vcxproj
index e4bad1a..c746ddb 100644
--- a/src/smw.vcxproj
+++ b/src/smw.vcxproj
@@ -38,7 +38,7 @@
Application
true
- v142
+ v143
Application
@@ -164,6 +164,7 @@
+
diff --git a/src/smw.vcxproj.filters b/src/smw.vcxproj.filters
index ad5ab2e..7abf1e8 100644
--- a/src/smw.vcxproj.filters
+++ b/src/smw.vcxproj.filters
@@ -10,9 +10,6 @@
{2b72ed96-9194-4c2c-b1e5-15445f0a9550}
-
- {e1763dbc-4fb3-417f-ad1a-8436411c3b7a}
-
{4FC737F1-C7A5-4376-A066-2A32D752A2FF}
cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
@@ -20,43 +17,46 @@
{c20be95b-4f11-4834-a006-bfb273e4bc0b}
+
+ {e1763dbc-4fb3-417f-ad1a-8436411c3b7a}
+
Smw
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
Common\Shader
@@ -101,7 +101,7 @@
Smw
- Common\Snes
+ Snes
Smb1
@@ -157,6 +157,9 @@
Smb1
+
+ Smw
+
@@ -169,40 +172,40 @@
Smw
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
- Common\Snes
+ Snes
Common\Shader
@@ -211,7 +214,7 @@
Common\Shader
- Common\Snes
+ Snes
Smb1
diff --git a/src/smw_00.c b/src/smw_00.c
index acf919e..17fc6bc 100644
--- a/src/smw_00.c
+++ b/src/smw_00.c
@@ -97,38 +97,17 @@ static FuncV *const kGameMode14_InLevel_PlayerStatePtrs[14] = {
};
static const uint8 kCompressOAMTileSizeBuffer_DATA_008475[31] = { 0x0, 0x0, 0x8, 0x0, 0x10, 0x0, 0x18, 0x0, 0x20, 0x0, 0x28, 0x0, 0x30, 0x0, 0x38, 0x0, 0x40, 0x0, 0x48, 0x0, 0x50, 0x0, 0x58, 0x0, 0x60, 0x0, 0x68, 0x0, 0x70, 0x0, 0x78, };
-static const uint8 kClearLayer3Tilemap_PARAMS_008649[7] = { 0x8, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, };
-static const uint8 kUploadLevelLayer1And2Tilemaps_PARAMS_008A16[7] = { 0x1, 0x18, 0xe6, 0x1b, 0x0, 0x40, 0x0, };
-static const uint8 kUploadLevelLayer1And2Tilemaps_PARAMS_008A1D[7] = { 0x1, 0x18, 0x26, 0x1c, 0x0, 0x2c, 0x0, };
-static const uint8 kUploadLevelLayer1And2Tilemaps_PARAMS_008A24[7] = { 0x1, 0x18, 0x66, 0x1c, 0x0, 0x40, 0x0, };
-static const uint8 kUploadLevelLayer1And2Tilemaps_PARAMS_008A2B[7] = { 0x1, 0x18, 0xa6, 0x1c, 0x0, 0x2c, 0x0, };
-static const uint8 kUploadLevelLayer1And2Tilemaps_PARAMS_008A32[7] = { 0x1, 0x18, 0xe8, 0x1c, 0x0, 0x40, 0x0, };
-static const uint8 kUploadLevelLayer1And2Tilemaps_PARAMS_008A39[5] = { 0x1, 0x18, 0x28, 0x1d, 0x0, };
-static const uint8 kUploadLevelLayer1And2Tilemaps_PARAMS_008A40[7] = { 0x1, 0x18, 0x68, 0x1d, 0x0, 0x40, 0x0, };
-static const uint8 kUploadLevelLayer1And2Tilemaps_PARAMS_008A47[5] = { 0x1, 0x18, 0xa8, 0x1d, 0x0, };
static const uint16 kManipulateMode7Image_DATA_008AB4[4] = { 0x0, 0xfe, 0x0, 0xfe, };
static const uint16 kManipulateMode7Image_DATA_008ABC[4] = { 0x0, 0x2, 0x0, 0x2, };
static const uint16 kManipulateMode7Image_DATA_008B57[149] = { 0x0, 0x3, 0x6, 0x9, 0xc, 0xf, 0x12, 0x15, 0x19, 0x1c, 0x1f, 0x22, 0x25, 0x28, 0x2b, 0x2e, 0x31, 0x35, 0x38, 0x3b, 0x3e, 0x41, 0x44, 0x47, 0x4a, 0x4d, 0x50, 0x53, 0x56, 0x59, 0x5c, 0x5f, 0x61, 0x64, 0x67, 0x6a, 0x6d, 0x70, 0x73, 0x75, 0x78, 0x7b, 0x7e, 0x80, 0x83, 0x86, 0x88, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x98, 0x9b, 0x9d, 0x9f, 0xa2, 0xa4, 0xa7, 0xa9, 0xab, 0xae, 0xb0, 0xb2, 0xb5, 0xb7, 0xb9, 0xbb, 0xbd, 0xbf, 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, 0xd1, 0xd3, 0xd4, 0xd6, 0xd8, 0xd9, 0xdb, 0xdd, 0xde, 0xe0, 0xe1, 0xe3, 0xe4, 0xe6, 0xe7, 0xe8, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf1, 0xf2, 0xf3, 0xf4, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x100, 0x3cb7, 0xbcb7, 0x3cb8, 0x3cb9, 0x3cba, 0x3cbb, 0x3cba, 0xbcba, 0x3cbc, 0x3cbd, 0x3cbe, 0x3cbf, 0x3cc0, 0xbcb7, 0x3cc1, 0x3cb9, 0x3cc2, 0xbcc2, 0x3cb7, 0xfcc0, };
static const uint8 kStatusBarTilemap_SecondRow[118] = { 0x30, 0x28, 0x31, 0x28, 0x32, 0x28, 0x33, 0x28, 0x34, 0x28, 0xfc, 0x38, 0xfc, 0x3c, 0xfc, 0x3c, 0xfc, 0x3c, 0xfc, 0x3c, 0xfc, 0x38, 0xfc, 0x38, 0x4a, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0x4a, 0x78, 0xfc, 0x38, 0x3d, 0x3c, 0x3e, 0x3c, 0x3f, 0x3c, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0x2e, 0x3c, 0x26, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0x0, 0x38, 0x26, 0x38, 0xfc, 0x38, 0x0, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0x64, 0x28, 0x26, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0x4a, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0x4a, 0x78, 0xfc, 0x38, 0xfe, 0x3c, 0xfe, 0x3c, 0x0, 0x3c, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x38, 0x0, 0x38, 0x3a, 0xb8, 0x3b, 0xb8, 0x3b, 0xb8, 0x3a, 0xf8, };
-static const uint8 kInitializeStatusBarTilemap_PARAMS_008D90[7] = { 0x1, 0x18, 0x81, 0x8c, 0x0, 0x8, 0x0, };
-static const uint8 kInitializeStatusBarTilemap_PARAMS_008D97[7] = { 0x1, 0x18, 0x89, 0x8c, 0x0, 0x38, 0x0, };
-static const uint8 kInitializeStatusBarTilemap_PARAMS_008D9E[7] = { 0x1, 0x18, 0xc1, 0x8c, 0x0, 0x36, 0x0, };
-static const uint8 kInitializeStatusBarTilemap_PARAMS_008DA5[7] = { 0x1, 0x18, 0xf7, 0x8c, 0x0, 0x8, 0x0, };
-static const uint8 kUploadStatusBarTilemap_PARAMS_StBr1[7] = { 0x0, 0x18, 0xf9, 0xe, 0x0, 0x1c, 0x0, };
-static const uint8 kUploadStatusBarTilemap_PARAMS_StBr2[7] = { 0x0, 0x18, 0x15, 0xf, 0x0, 0x1b, 0x0, };
static const uint8 kUpdateStatusBarCounters_DATA_008DF5[5] = { 0x40, 0x41, 0x42, 0x43, 0x44, };
static const uint8 kUpdateStatusBarCounters_ItemBoxItemTile[4] = { 0x24, 0x26, 0x48, 0xe, };
static const uint8 kUpdateStatusBarCounters_StarPaletteFrames[4] = { 0x0, 0x2, 0x4, 0x2, };
static const uint8 kUpdateStatusBarCounters_ItemBoxItemProperties[4] = { 0x8, 0xa, 0x0, 0x4, };
static const uint8 kUpdateStatusBarCounters_BonusStarCounterNumberTiles[20] = { 0xb7, 0xc3, 0xb8, 0xb9, 0xba, 0xbb, 0xba, 0xbf, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc3, 0xc1, 0xb9, 0xc2, 0xc4, 0xb7, 0xc5, };
static const uint16 kUpdateStatusBarCounters_DATA_008FFA[12] = { 0x1, 0x86a0, 0x0, 0x2710, 0x0, 0x3e8, 0x0, 0x64, 0x0, 0xa, 0x0, 0x1, };
-static const uint8 kDrawLoadingLetters_TileData[52] = { 0x0, 0xff, 0x4d, 0x4c, 0x3, 0x4d, 0x5d, 0xff, 0x3, 0x0, 0x4c, 0x3, 0x4, 0x15, 0x0, 0x2, 0x0, 0x4a, 0x4e, 0xff, 0x4c, 0x4b, 0x4a, 0x3, 0x5f, 0x5, 0x4, 0x3, 0x2, 0x0, 0xff, 0x1, 0x4a, 0x5f, 0x5, 0x4, 0x0, 0x4d, 0x5d, 0x3, 0x2, 0x1, 0x0, 0xff, 0x5b, 0x14, 0x5f, 0x1, 0x5e, 0xff, 0xff, 0xff, };
-static const uint8 kDrawLoadingLetters_TileData_BottomTiles[52] = { 0x10, 0xff, 0x0, 0x5c, 0x13, 0x0, 0x5d, 0xff, 0x3, 0x0, 0x5c, 0x13, 0x14, 0x15, 0x0, 0x12, 0x0, 0x3, 0x5e, 0xff, 0x5c, 0x4b, 0x5a, 0x3, 0x5f, 0x5, 0x14, 0x13, 0x12, 0x10, 0xff, 0x11, 0x3, 0x5f, 0x5, 0x14, 0x0, 0x0, 0x5d, 0x3, 0x12, 0x11, 0x10, 0xff, 0x5b, 0x1, 0x5f, 0x1, 0x5e, 0xff, 0xff, 0xff, };
-// oob
-static const uint8 kDrawLoadingLetters_TileData_TopProp[52] = { 0x34, 0x0, 0x34, 0x34, 0x34, 0x34, 0x30, 0x0, 0x34, 0x34, 0x34, 0x34, 0x74, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x0, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x0, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0,0xB4 };
-static const uint8 kDrawLoadingLetters_TileData_BottomProp[52] = { 0x34, 0x0, 0xb4, 0x34, 0x34, 0xb4, 0xf0, 0x0, 0xb4, 0xb4, 0x34, 0x34, 0x74, 0xb4, 0xb4, 0x34, 0xb4, 0xb4, 0x34, 0x0, 0x34, 0xb4, 0x34, 0xb4, 0xb4, 0xb4, 0x34, 0x34, 0x34, 0x34, 0x0, 0x34, 0xb4, 0xb4, 0xb4, 0x34, 0xb4, 0xb4, 0xb4, 0xb4, 0x34, 0x34, 0x34, 0x34, 0xf4, 0xb4, 0xf4, 0xb4, 0xb4, 0xa5, 0x71, 0xc9 };
-static const uint8 kUpdateEntirePalette_PARAMS_009249[7] = { 0x0, 0x22, 0x3, 0x7, 0x0, 0x0, 0x2, };
static const uint8 kGameMode00_LoadNintendoPresents_XDisp[4] = { 0x60, 0x70, 0x80, 0x90, };
static const uint8 kGameMode00_LoadNintendoPresents_Tiles[4] = { 0x2, 0x4, 0x6, 0x8, };
const uint8 kGameMode19_Cutscene_SkyColorSetting[8] = { 0x2, 0x0, 0x4, 0x1, 0x0, 0x6, 0x4, 0x3, };
@@ -145,7 +124,6 @@ static const uint16 kHandleMenuCursor_DATA_009E6A[5] = { 0x2, 0x4, 0x2, 0x2, 0x4
static const uint16 kHandleMenuCursor_DATA_009E74[5] = { 0x51cb, 0x51e8, 0x5208, 0x51c4, 0x51e5, };
static const uint8 kHandleMenuCursor_DATA_009E7E[4] = { 0x1, 0x2, 0x4, 0x8, };
static const uint16 kInitializeSaveData_InitialLevelFlags[8] = { 0x328, 0x14d, 0x152, 0x153, 0x85b, 0x25c, 0x457, 0x130, };
-static const uint8 kInitializeSaveData_InitialOWPlayerPos[22] = { 0x1, 0x1, 0x2, 0x0, 0x2, 0x0, 0x68, 0x0, 0x78, 0x0, 0x68, 0x0, 0x78, 0x0, 0x6, 0x0, 0x7, 0x0, 0x6, 0x0, 0x7, 0x0, };
const uint8 kGameModeXX_FadeInOrOut_DATA_009F2F[2] = { 0x1, 0xff, };
const uint8 kGameModeXX_FadeInOrOut_DATA_009F31[2] = { 0xf0, 0x10, };
const uint8 kGameModeXX_FadeInOrOut_DATA_009F33[2] = { 0xf, 0x0, };
@@ -156,17 +134,21 @@ static const uint8 kGameMode14_InLevel_GrndShakeDispYLo[4] = { 0xfe, 0x0, 0x2, 0
static const uint8 kGameMode14_InLevel_GrndShakeDispYHi[4] = { 0xff, 0x0, 0x0, 0x0, };
static const uint8 kUploadOverworldLayer1And2Tilemaps_DATA_00A521[4] = { 0x0, 0x4, 0x8, 0xc, };
static const uint8 kUploadOverworldLayer1And2Tilemaps_DATA_00A525[4] = { 0x0, 0x8, 0x10, 0x18, };
-static const uint8 kUploadOverworldLayer1And2Tilemaps_PARAMS_00A586[7] = { 0x1, 0x18, 0x0, 0x40, 0x7f, 0x0, 0x8, };
-static const uint8 kUploadOverworldLayer1And2Tilemaps_PARAMS_00A58D[7] = { 0x1, 0x18, 0x0, 0xe4, 0x7e, 0x0, 0x8, };
static const uint8 kInitializeLevelRAM_DATA_00A60D[4] = { 0x0, 0x1, 0x1, 0x1, };
static const uint16 kInitializeLevelRAM_DATA_00A611[4] = { 0xd, 0xfff3, 0xfffe, 0xfffe, };
static const uint16 kInitializeLevelRAM_DATA_00A619[4] = { 0x0, 0x0, 0xa, 0 };
static const uint8 kInitializeLevelRAM_DATA_00A621[4] = { 0x1A,0x1A, 0xA, 0xA, };
static const uint8 kInitializeLevelRAM_DATA_00A625[16] = { 0x0, 0x80, 0x40, 0x0, 0x1, 0x2, 0x40, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, };
-static const uint8 kUploadGraphicsFiles_SpriteGFXList[104] = { 0x0, 0x1, 0x13, 0x2, 0x0, 0x1, 0x12, 0x3, 0x0, 0x1, 0x13, 0x5, 0x0, 0x1, 0x13, 0x4, 0x0, 0x1, 0x13, 0x6, 0x0, 0x1, 0x13, 0x9, 0x0, 0x1, 0x13, 0x4, 0x0, 0x1, 0x6, 0x11, 0x0, 0x1, 0x13, 0x20, 0x0, 0x1, 0x13, 0xf, 0x0, 0x1, 0x13, 0x23, 0x0, 0x1, 0xd, 0x14, 0x0, 0x1, 0x24, 0xe, 0x0, 0x1, 0xa, 0x22, 0x0, 0x1, 0x13, 0xe, 0x0, 0x1, 0x13, 0x14, 0x0, 0x0, 0x0, 0x8, 0x10, 0xf, 0x1c, 0x1d, 0x0, 0x1, 0x24, 0x22, 0x0, 0x1, 0x25, 0x22, 0x0, 0x22, 0x13, 0x2d, 0x0, 0x1, 0xf, 0x22, 0x0, 0x26, 0x2e, 0x22, 0x21, 0xb, 0x25, 0xa, 0x0, 0xd, 0x24, 0x22, 0x2c, 0x30, 0x2d, 0xe, };
+static const uint8 kUploadGraphicsFiles_SpriteGFXList[104] = {
+ 0x0, 0x1, 0x13, 0x2,
+ 0x0, 0x1, 0x12, 0x3,
+ 0x0, 0x1, 0x13, 0x5,
+ 0x0, 0x1, 0x13, 0x4,
+ 0x0, 0x1, 0x13, 0x6,
+ 0x0, 0x1, 0x13, 0x9,
+ 0x0, 0x1, 0x13, 0x4, 0x0, 0x1, 0x6, 0x11, 0x0, 0x1, 0x13, 0x20, 0x0, 0x1, 0x13, 0xf, 0x0, 0x1, 0x13, 0x23, 0x0, 0x1, 0xd, 0x14, 0x0, 0x1, 0x24, 0xe, 0x0, 0x1, 0xa, 0x22, 0x0, 0x1, 0x13, 0xe, 0x0, 0x1, 0x13, 0x14, 0x0, 0x0, 0x0, 0x8, 0x10, 0xf, 0x1c, 0x1d, 0x0, 0x1, 0x24, 0x22, 0x0, 0x1, 0x25, 0x22, 0x0, 0x22, 0x13, 0x2d, 0x0, 0x1, 0xf, 0x22, 0x0, 0x26, 0x2e, 0x22, 0x21, 0xb, 0x25, 0xa, 0x0, 0xd, 0x24, 0x22, 0x2c, 0x30, 0x2d, 0xe, };
static const uint8 kUploadGraphicsFiles_FGAndBGGFXList[104] = { 0x14, 0x17, 0x19, 0x15, 0x14, 0x17, 0x1b, 0x18, 0x14, 0x17, 0x1b, 0x16, 0x14, 0x17, 0xc, 0x1a, 0x14, 0x17, 0x1b, 0x8, 0x14, 0x17, 0xc, 0x7, 0x14, 0x17, 0xc, 0x16, 0x14, 0x17, 0x1b, 0x15, 0x14, 0x17, 0x19, 0x16, 0x14, 0x17, 0xd, 0x1a, 0x14, 0x17, 0x1b, 0x8, 0x14, 0x17, 0x1b, 0x18, 0x14, 0x17, 0x19, 0x1f, 0x14, 0x17, 0xd, 0x7, 0x14, 0x17, 0x19, 0x1a, 0x14, 0x17, 0x14, 0x14, 0xe, 0xf, 0x17, 0x17, 0x1c, 0x1d, 0x8, 0x1e, 0x1c, 0x1d, 0x8, 0x1e, 0x1c, 0x1d, 0x8, 0x1e, 0x1c, 0x1d, 0x8, 0x1e, 0x1c, 0x1d, 0x8, 0x1e, 0x1c, 0x1d, 0x8, 0x1e, 0x1c, 0x1d, 0x8, 0x1e, 0x14, 0x17, 0x19, 0x2c, 0x19, 0x17, 0x1b, 0x18, };
static const uint8 kUploadGraphicsFiles_DATA_00A9D2[4] = { 0x78, 0x70, 0x68, 0x60, };
-static const uint8 kUploadGraphicsFiles_DATA_00A9D6[4] = { 0x18, 0x10, 0x8, 0x0, };
static const uint8 kBufferPalettesRoutines_DATA_00ABD3[12] = { 0x0, 0x18, 0x30, 0x48, 0x60, 0x78, 0x90, 0xa8, 0x0, 0x14, 0x28, 0x3c, };
static const uint8 kBufferPalettesRoutines_DATA_00AD1E[7] = { 0x1, 0x0, 0x3, 0x4, 0x3, 0x5, 0x2, };
static const uint8 kUpdatePaletteFromIndexedTable_DATA_00AE41[3] = { 0x0, 0x5, 0xa, };
@@ -176,26 +158,11 @@ static const uint16 kHandlePaletteFades_DATA_00AE6B[3] = { 0xffff, 0xffe0, 0xfc0
static const uint16 kHandlePaletteFades_DATA_00AE71[3] = { 0x1, 0x20, 0x400, };
static const uint16 kHandlePaletteFades_DATA_00AE77[64] = { 0x0, 0x0, 0x1, 0x0, 0x8000, 0x8000, 0x8020, 0x400, 0x8080, 0x8080, 0x8208, 0x1040, 0x8420, 0x8420, 0x8844, 0x2210, 0x8888, 0x8888, 0x9122, 0x4488, 0x9248, 0x9248, 0xa492, 0x4924, 0xa4a4, 0xa4a4, 0xa949, 0x5294, 0xaaaa, 0x5294, 0xaaaa, 0x5554, 0xaaaa, 0xaaaa, 0xd5aa, 0xaaaa, 0xd5aa, 0xd5aa, 0xd6b5, 0xad6a, 0xdada, 0xdada, 0xdb6d, 0xb6da, 0xedb6, 0xedb6, 0xeedd, 0xbb76, 0xeeee, 0xeeee, 0xf7bb, 0xddee, 0xfbde, 0xfbde, 0xfdf7, 0xefbe, 0xfefe, 0xfefe, 0xffdf, 0xfbfe, 0xfffe, 0xfffe, 0xffff, 0xfffe, };
static const uint16 kHandlePaletteFades_DATA_00AEF7[16] = { 0x8000, 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, };
-const uint16 kGlobalPalettes_Sky[8] = { 0x5b9f, 0x6ffb, 0x5d80, 0x0, 0x1d22, 0x24c3, 0x7393, 0x7fff, };
static const uint16 kGlobalPalettes_BowserEnd[6] = { 0x0, 0x63fb, 0x30c, 0x20b, 0x1535, 0x1a5f, };
static const uint16 kGlobalPalettes_B3CC[6] = { 0x0, 0x3434, 0x443a, 0x659f, 0x116, 0x27f, };
-static const uint16 kGlobalPalettes_Flashing[16] = { 0x2df, 0x35f, 0x27ff, 0x5fff, 0x73ff, 0x5fff, 0x27ff, 0x35f, 0x1bf, 0x1f, 0x1b, 0x18, 0x18, 0x1b, 0x1f, 0x1bf, };
-static const uint16 kGlobalPalettes_Layer3Smasher[4] = { 0x7393, 0x0, 0xd71, 0x1e9b, };
-const uint16 kGlobalPalettes_Bowser[56] = { 0x7fff, 0x18c0, 0x63fb, 0x30c, 0x20b, 0x1535, 0x1a5f, 0x779b, 0x1860, 0x5b97, 0x2a8, 0x1a7, 0xcd1, 0x11fb, 0x6f37, 0x1800, 0x5333, 0x245, 0x143, 0x46e, 0x997, 0x66d3, 0x1000, 0x4acf, 0x1e1, 0xe0, 0xa, 0x133, 0x5e6f, 0x0, 0x426b, 0x180, 0x80, 0x6, 0xcf, 0x560b, 0x0, 0x3a07, 0x120, 0x20, 0x2, 0x6b, 0x4da7, 0x0, 0x31a3, 0xc0, 0x0, 0x0, 0x7, 0x4543, 0x0, 0x2940, 0x60, 0x0, 0x0, 0x3, };
static const uint16 kGlobalPalettes_EndingLuigi[6] = { 0x44c4, 0x320, 0x4adf, 0x200, 0x13b, 0x4e08, };
static const uint16 kGlobalPalettes_EndingMario[6] = { 0x44c4, 0x391f, 0x4adf, 0x2874, 0x13f, 0x4e08, };
static const uint16 kGlobalPalettes_EndingToadstool[6] = { 0x28d2, 0x551e, 0x635f, 0x7b1f, 0x1fb, 0x2de, };
-
-const uint8 kLevelDataLayoutTables_EightBitLo_Horizontal[32] = { 0x0, 0xb0, 0x60, 0x10, 0xc0, 0x70, 0x20, 0xd0, 0x80, 0x30, 0xe0, 0x90, 0x40, 0xf0, 0xa0, 0x50,
-0x0, 0xb0, 0x60, 0x10, 0xc0, 0x70, 0x20, 0xd0, 0x80, 0x30, 0xe0, 0x90, 0x40, 0xf0, 0xa0, 0x50,};
-const uint8 kLevelDataLayoutTables_EightBitLo_Vertical[28] = {
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-};
-const uint8 kLevelDataLayoutTables_EightBitHi_Horizontal[32] = { 0xc8, 0xc9, 0xcb, 0xcd, 0xce, 0xd0, 0xd2, 0xd3, 0xd5, 0xd7, 0xd8, 0xda, 0xdc, 0xdd, 0xdf, 0xe1,
-0xe3, 0xe4, 0xe6, 0xe8, 0xe9, 0xeb, 0xed, 0xee, 0xf0, 0xf2, 0xf3, 0xf5, 0xf7, 0xf8, 0xfa, 0xfc,};
-const uint8 kLevelDataLayoutTables_EightBitHi_Vertical[28] = { 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2,
-0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,};
static const uint16 kSetItemMemoryBit_DATA_00BFFF[3] = { 0x0, 0x80, 0x100, };
static const uint8 kSetItemMemoryBit_DATA_00C005[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, };
static const uint8 kGenericPage00Tile_Map16Page00TileLo[9] = { 0x25, 0x25, 0x25, 0x6, 0x49, 0x48, 0x2b, 0xa2, 0xc6, };
@@ -203,13 +170,13 @@ static const uint8 kGenericPage01Tile_Map16Page01TileLo[15] = { 0x52, 0x1b, 0x23
static const uint8 kGameMode14_InLevel_DATA_00C470[4] = { 0x90, 0x0, 0x90, 0x0, };
static const uint8 kGameMode14_InLevel_DATA_00C474[4] = { 0x4, 0xfc, 0x4, 0xfc, };
static const uint8 kGameMode14_InLevel_DATA_00C478[6] = { 0x30, 0x33, 0x33, 0x30, 0x1, 0x0, };
-static const uint8 kPlayerState0C_CastleDestructionMoves_DATA_00C5E1[8] = { 0x10, 0x30, 0x31, 0x32, 0x33, 0x34, 0xe, 0x26};
+static const uint8 kPlayerState0C_CastleDestructionMoves_DATA_00C5E1[9] = { 0x10, 0x30, 0x31, 0x32, 0x33, 0x34, 0xe, 0x26, 0x11};
static const uint8 kPlayerState0C_CastleDestructionMoves_CastleDestructionMovementData[247] = { 0x26, 0x11, 0x2, 0x48, 0x0, 0x60, 0x1, 0x9, 0x80, 0x8, 0x0, 0x20, 0x4, 0x60, 0x0, 0x1, 0xff, 0x1, 0x2, 0x48, 0x0, 0x60, 0x41, 0x2c, 0xc1, 0x4, 0x27, 0x4, 0x2f, 0x8, 0x25, 0x1, 0x2f, 0x4, 0x27, 0x4, 0x0, 0x8, 0x41, 0x1b, 0xc1, 0x4, 0x27, 0x4, 0x2f, 0x8, 0x25, 0x1, 0x2f, 0x4, 0x27, 0x4, 0x0, 0x4, 0x1, 0x8, 0x20, 0x1, 0x1, 0x10, 0x0, 0x8, 0x41, 0x12, 0x81, 0xa, 0x0, 0x40, 0x82, 0x10, 0x2, 0x20, 0x0, 0x30, 0x1, 0x1, 0x0, 0x50, 0x22, 0x1, 0xff, 0x1, 0x2, 0x48, 0x0, 0x60, 0x1, 0x9, 0x80, 0x8, 0x0, 0x20, 0x4, 0x60, 0x0, 0x20, 0x10, 0x20, 0x1, 0x58, 0x0, 0x2c, 0x31, 0x1, 0x3a, 0x10, 0x31, 0x1, 0x3a, 0x10, 0x31, 0x1, 0x3a, 0x20, 0x28, 0xa0, 0x28, 0x40, 0x29, 0x4, 0x28, 0x4, 0x29, 0x4, 0x28, 0x4, 0x29, 0x4, 0x28, 0x40, 0x22, 0x1, 0xff, 0x1, 0x2, 0x48, 0x0, 0x60, 0x1, 0x9, 0x80, 0x8, 0x0, 0x20, 0x4, 0x60, 0x10, 0x20, 0x31, 0x1, 0x18, 0x60, 0x31, 0x1, 0x3b, 0x80, 0x31, 0x1, 0x3c, 0x40, 0xff, 0x1, 0x2, 0x48, 0x0, 0x60, 0x2, 0x30, 0x1, 0x84, 0x0, 0x20, 0x23, 0x1, 0x1, 0x16, 0x2, 0x20, 0x20, 0x1, 0x1, 0x20, 0x2, 0x20, 0x1, 0x2, 0x0, 0x80, 0xff, 0x1, 0x2, 0x48, 0x0, 0x60, 0x2, 0x28, 0x1, 0x83, 0x0, 0x28, 0x24, 0x1, 0x2, 0x1, 0x0, 0xff, 0x0, 0x40, 0x20, 0x1, 0x0, 0x40, 0x2, 0x60, 0x0, 0x30, 0xff, 0x1, 0x2, 0x48, 0x0, 0x60, 0x1, 0x4e, 0x0, 0x40, 0x26, 0x1, 0x0, 0x1e, 0x20, 0x1, 0x0, 0x20, 0x8, 0x10, 0x20, 0x1, 0x2d, 0x18, 0x0, 0xa0, 0x20, 0x1, 0x2e, 0x1, 0xff, };
static const uint8 kPlayerState0C_CastleDestructionMoves_DATA_00C5E9[16] = { 0x11, 0x2, 0x48, 0x0, 0x60, 0x1, 0x9, 0x80, 0x8, 0x0, 0x20, 0x4, 0x60, 0x0, 0x1, 0xff, };
static const uint8 kPlayerState0C_CastleDestructionMoves_UNK_00C6DF[8] = { 0x1, 0x0, 0x10, 0xa0, 0x84, 0x50, 0xbc, 0xd8, };
static const uint16 kPlayerState08_WarpToYoshiWingsBonus_DATA_00C7F9[2] = { 0xffc0, 0xa0, };
-static const uint8 kPlayerState0A_NoYoshiCutscene_DATA_00C848[40] = { 0x1, 0x5f, 0x0, 0x30, 0x8, 0x30, 0x0, 0x20, 0x40, 0x1, 0x0, 0x30, 0x1, 0x80, 0xff, 0x1, 0x3f, 0x0, 0x30, 0x20, 0x1, 0x80, 0x6, 0x0, 0x3a, 0x1, 0x38, 0x0, 0x30, 0x8, 0x30, 0x0, 0x20, 0x40, 0x1, 0x0, 0x30, 0x1, 0x80, 0xff, };
-static const uint8 kPlayerState00_LevelsThatTriggerCutscenes[8] = { 0x25, 0x7, 0x40, 0xe, 0x20, 0x1a, 0x34, 0x32, };
+// todo: oob read
+static const uint8 kPlayerState0A_NoYoshiCutscene_DATA_00C848[41] = { 0x1, 0x5f, 0x0, 0x30, 0x8, 0x30, 0x0, 0x20, 0x40, 0x1, 0x0, 0x30, 0x1, 0x80, 0xff, 0x1, 0x3f, 0x0, 0x30, 0x20, 0x1, 0x80, 0x6, 0x0, 0x3a, 0x1, 0x38, 0x0, 0x30, 0x8, 0x30, 0x0, 0x20, 0x40, 0x1, 0x0, 0x30, 0x1, 0x80, 0xff, 0x9c };
static const uint8 kPlayerState00_FreeMovementDebugPlayerSpeed[12] = { 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x6, 0x0, 0xfe, 0xff, 0xfa, 0xff, };
static const uint8 kPlayerState_OnYoshiAnimations[4] = { 0x20, 0x21, 0x27, 0x28, };
static const uint8 kSetPlayerPose_DATA_00CE79[6] = { 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, };
@@ -252,7 +219,6 @@ static const uint8 kHandlePlayerPhysics_ClimbingPoses[2] = { 0x15, 0x22, };
static const uint8 kHandlePlayerPhysics_NetPunchingPoses[2] = { 0x1e, 0x23, };
static const uint8 kHandlePlayerPhysics_DATA_00DADF[18] = { 0x10, 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, };
static const uint16 kHandlePlayerPhysics_DATA_00DAF1[18] = { 0x120, 0x140, 0x12a, 0x12a, 0x130, 0x133, 0x132, 0x134, 0x136, 0x138, 0x13a, 0x13b, 0x145, 0x145, 0x145, 0x145, 0x145, 0x145, };
-static const uint8 kSetPlayerPose_WalkingPoseCount[4] = { 0x1, 0x2, 0x2, 0x2, };
static const uint8 kSetPlayerPose_AnimationSpeedTable[112] = { 0xa, 0x8, 0x6, 0x4, 0x3, 0x2, 0x1, 0x1, 0xa, 0x8, 0x6, 0x4, 0x3, 0x2, 0x1, 0x1, 0xa, 0x8, 0x6, 0x4, 0x3, 0x2, 0x1, 0x1, 0x8, 0x6, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x8, 0x6, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x5, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x5, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x5, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x5, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x5, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x5, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, };
static const uint8 kPlayerGFXRt_PlayerXYDispIndexIndex[70] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x4, 0x4, 0x4, 0xe, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, };
static const uint8 kPlayerGFXRt_PlayerXYDispIndex[28] = { 0x0, 0x8, 0x10, 0x14, 0x18, 0x1e, 0x24, 0x24, 0x28, 0x30, 0x38, 0x3e, 0x44, 0x4a, 0x50, 0x54, 0x58, 0x58, 0x5c, 0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x80, };
@@ -261,8 +227,6 @@ static const uint16 kPlayerGFXRt_YDisp[114] = { 0x1, 0x11, 0x11, 0x19, 0x1, 0x11
static const uint8 kPlayerGFXRt_PowerupTilesetIndex[4] = { 0x0, 0x46, 0x83, 0x46, };
static const uint8 kPlayerGFXRt_Tiles[50] = { 0x0, 0x2, 0x80, 0x80, 0x0, 0x2, 0xc, 0x80, 0x0, 0x2, 0x1a, 0x1b, 0x0, 0x2, 0xd, 0x80, 0x0, 0x2, 0x22, 0x23, 0x0, 0x2, 0x32, 0x33, 0x0, 0x2, 0xa, 0xb, 0x0, 0x2, 0x30, 0x31, 0x0, 0x2, 0x20, 0x21, 0x0, 0x2, 0x7e, 0x80, 0x0, 0x2, 0x2, 0x80, 0x4, 0x7f, 0x4a, 0x5b, 0x4B, 0x5A };
static const uint8 kPlayerGFXRt_TilesIndex[192] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0xc, 0xc, 0xc, 0x0, 0x0, 0x10, 0x10, 0x14, 0x14, 0x18, 0x18, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0xc, 0xc, 0xc, 0x0, 0x0, 0x10, 0x10, 0x14, 0x14, 0x18, 0x18, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, };
-static const uint8 kPlayerGFXRt_HeadTilePointerIndex[192] = { 0x50, 0x50, 0x50, 0x9, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x9, 0x2b, 0x50, 0x2d, 0x50, 0xd5, 0x2e, 0xc4, 0xc4, 0xc4, 0xd6, 0xb6, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0xc5, 0xd7, 0x2a, 0xe0, 0x50, 0xd5, 0x29, 0x2c, 0xb6, 0xd6, 0x28, 0xe0, 0xe0, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0x5c, 0x5c, 0x50, 0x5a, 0xb6, 0x50, 0x28, 0x28, 0xc5, 0xd7, 0x28, 0x70, 0xc5, 0x70, 0x1c, 0x93, 0xc5, 0xc5, 0xb, 0x85, 0x90, 0x84, 0x70, 0x70, 0x70, 0xa0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xa0, 0x74, 0x70, 0x80, 0x70, 0x84, 0x17, 0xa4, 0xa4, 0xa4, 0xb3, 0xb0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xe2, 0x72, 0xf, 0x61, 0x70, 0x63, 0x82, 0xc7, 0x90, 0xb3, 0xd4, 0xa5, 0xc0, 0x8, 0x54, 0xc, 0xe, 0x1b, 0x51, 0x49, 0x4a, 0x48, 0x4b, 0x4c, 0x5d, 0x5e, 0x5f, 0xe3, 0x90, 0x5f, 0x5f, 0xc5, 0x70, 0x70, 0x70, 0xa0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xa0, 0x74, 0x70, 0x80, 0x70, 0x84, 0x17, 0xa4, 0xa4, 0xa4, 0xb3, 0xb0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xe2, 0x72, 0xf, 0x61, 0x70, 0x63, 0x82, 0xc7, 0x90, 0xb3, 0xd4, 0xa5, 0xc0, 0x8, 0x64, 0xc, 0xe, 0x1b, 0x51, 0x49, 0x4a, 0x48, 0x4b, 0x4c, 0x5d, 0x5e, 0x5f, 0xe3, 0x90, 0x5f, 0x5f, 0xc5, };
-static const uint8 kPlayerGFXRt_BodyTilePointerIndex[192] = { 0x71, 0x60, 0x60, 0x19, 0x94, 0x96, 0x96, 0xa2, 0x97, 0x97, 0x18, 0x3b, 0xb4, 0x3d, 0xa7, 0xe5, 0x2f, 0xd3, 0xc3, 0xc3, 0xf6, 0xd0, 0xb1, 0x81, 0xb2, 0x86, 0xb4, 0x87, 0xa6, 0xd1, 0xf7, 0x3a, 0xf0, 0xf4, 0xf5, 0x39, 0x3c, 0xc6, 0xe6, 0x38, 0xf1, 0xf0, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0x6c, 0x4d, 0x71, 0x6a, 0x6b, 0x60, 0x38, 0xf1, 0x5b, 0x69, 0xf1, 0xf1, 0x4e, 0xe1, 0x1d, 0xa3, 0xc5, 0xc5, 0x1a, 0x95, 0x10, 0x7, 0x2, 0x1, 0x0, 0x2, 0x14, 0x13, 0x12, 0x30, 0x27, 0x26, 0x30, 0x3, 0x15, 0x4, 0x31, 0x7, 0xe7, 0x25, 0x24, 0x23, 0x62, 0x36, 0x33, 0x91, 0x34, 0x92, 0x35, 0xa1, 0x32, 0xf2, 0x73, 0x1f, 0xc0, 0xc1, 0xc2, 0x83, 0xd2, 0x10, 0xb7, 0xe4, 0xb5, 0x61, 0xa, 0x55, 0xd, 0x75, 0x77, 0x1e, 0x59, 0x59, 0x58, 0x2, 0x2, 0x6d, 0x6e, 0x6f, 0xf3, 0x68, 0x6f, 0x6f, 0x6, 0x2, 0x1, 0x0, 0x2, 0x14, 0x13, 0x12, 0x30, 0x27, 0x26, 0x30, 0x3, 0x15, 0x4, 0x31, 0x7, 0xe7, 0x25, 0x24, 0x23, 0x62, 0x36, 0x33, 0x91, 0x34, 0x92, 0x35, 0xa1, 0x32, 0xf2, 0x73, 0x1f, 0xc0, 0xc1, 0xc2, 0x83, 0xd2, 0x10, 0xb7, 0xe4, 0xb5, 0x61, 0xa, 0x55, 0xd, 0x75, 0x77, 0x1e, 0x59, 0x59, 0x58, 0x2, 0x2, 0x6d, 0x6e, 0x6f, 0xf3, 0x68, 0x6f, 0x6f, 0x6, };
static const uint8 kPlayerGFXRt_TileXFlip[2] = { 0x0, 0x40, };
static const uint8 kPlayerGFXRt_DATA_00E18E[70] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x10, 0x13, 0x22, 0x25, 0x28, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x19, 0x1c, 0x4, 0x1f, 0x10, 0x10, 0x0, 0x16, 0x10, 0x6, 0x4, 0x8, 0x2b, 0x30, 0x35, 0x3a, 0x3f, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x16, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x4, 0x0, };
// todo: oob
@@ -473,7 +437,10 @@ LABEL_24:
UpdateCreditsBackground();
goto LABEL_17;
}
- UploadLevelLayer1And2Tilemaps();
+ if (g_lunar_magic)
+ LmHook_UploadLevelLayer1And2Tilemaps();
+ else
+ UploadLevelLayer1And2Tilemaps();
if (!flag_upload_load_screen_letters_tovram) {
UploadLevelExAnimationData();
LABEL_17:
@@ -650,6 +617,7 @@ void UploadLevelLayer1And2Tilemaps() { // 0087ad
}
LOBYTE(blocks_layer1_vramupload_address) = 0;
if ((uint8)blocks_layer2_vramupload_address) {
+ uint8 size = g_lunar_magic ? 0x40 : 0x2c;
if ((misc_level_layout_flags & 2) != 0) {
SmwCopyToVram(swap16(blocks_layer2_vramupload_address), g_ram + 0x1ce8, 0x40);
SmwCopyToVram(swap16(blocks_layer2_vramupload_address) + 0x400, g_ram + 0x1d28, 0x40);
@@ -657,9 +625,9 @@ void UploadLevelLayer1And2Tilemaps() { // 0087ad
SmwCopyToVram(swap16(blocks_layer2_vramupload_address) + 0x420, g_ram + 0x1da8, 0x40);
} else {
SmwCopyToVramPitch32(swap16(blocks_layer2_vramupload_address), g_ram + 0x1ce8, 0x40);
- SmwCopyToVramPitch32(swap16(blocks_layer2_vramupload_address) + 0x800, g_ram + 0x1d28, 0x2c);
+ SmwCopyToVramPitch32(swap16(blocks_layer2_vramupload_address) + 0x800, g_ram + 0x1d28, size);
SmwCopyToVramPitch32(swap16(blocks_layer2_vramupload_address) + 1, g_ram + 0x1d68, 0x40);
- SmwCopyToVramPitch32(swap16(blocks_layer2_vramupload_address) + 0x801, g_ram + 0x1dA8, 0x2c);
+ SmwCopyToVramPitch32(swap16(blocks_layer2_vramupload_address) + 0x801, g_ram + 0x1dA8, size);
}
}
LOBYTE(blocks_layer2_vramupload_address) = 0;
@@ -1216,7 +1184,7 @@ void GameMode1D_LoadYoshisHouse_GameMode1FEntry() { // 0095ab
ResetSpritesFunc(0);
GameMode1D_LoadYoshisHouse_Bank0C();
++counter_local_frames;
- HandleLevelTileAnimations();
+ LmHook_LevelTileAnimations();
CompressOamEntExt();
}
@@ -1331,13 +1299,19 @@ void GameMode11_LoadSublevel_0096D5() { // 0096d5
flag_disable_layer3_scroll = 0;
pointer_current_overworld_process = 0;
timer_wait_before_score_tally = 80;
- LoadLevel();
+ if (LoadLevel())
+ return;
for (uint8 i = 7; (i & 0x80) == 0; --i)
LOBYTE(get_PointU16(misc_layer1_pos, i)->x) = *((uint8 *)&mirror_current_layer1_xpos + i);
HandleSPCUploads_008134();
InitializeLevelRAM();
- camera_last_screen_horiz = 32;
- GameMode11_LoadSublevel_00A796();
+ bool skip_it = false;
+ if (g_lunar_magic)
+ skip_it = LmHook_GameMode11_LoadSublevel();
+ else
+ camera_last_screen_horiz = 32;
+ if (!skip_it)
+ GameMode11_LoadSublevel_00A796();
++flag_scroll_up_to_player;
HandleStandardLevelCameraScroll();
LoadSublevel();
@@ -1398,6 +1372,7 @@ void GameMode17_ShowDeathMessage() { // 009759
if (v3 == 40)
r0w = 120 - timer_display_death_message_animation;
DrawLoadingLetters_Draw(v2++, v3, r0w);
+ r0w -= 8;
v3 -= 8;
} while (v3);
CompressOamEntExt();
@@ -1485,8 +1460,6 @@ void GameMode14_InLevel_InMode7Level() { // 00987d
}
}
-const uint16 kLevelTileAnimations_FrameData[208] = { 0x9500, 0x9700, 0x9900, 0x9b00, 0x9580, 0x9780, 0x9980, 0x9b80, 0x9600, 0x9600, 0x9600, 0x9600, 0x9d80, 0x9f80, 0xa180, 0xa380, 0x9600, 0x9800, 0x9a00, 0x9c00, 0x6d80, 0x6f80, 0x7c00, 0x7c80, 0xac20, 0xac20, 0xac20, 0xac20, 0xac20, 0xac20, 0xac20, 0xac20, 0x9380, 0x9380, 0x9380, 0x9380, 0xa400, 0xa480, 0xa400, 0xa480, 0xac20, 0xac20, 0xac20, 0xac20, 0xac00, 0xac00, 0xac00, 0xac00, 0x9100, 0x9100, 0x9100, 0x9100, 0x9680, 0x9880, 0x9a80, 0x9c80, 0x9d00, 0x9f00, 0xa100, 0xa300, 0x8e80, 0x9080, 0x9280, 0x9480, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9d00, 0x9f00, 0xa100, 0xa300, 0x8e80, 0x9080, 0x9280, 0x9480, 0x7d00, 0x7f00, 0x8100, 0x8300, 0x8300, 0x8100, 0x7f00, 0x7d00, 0x9e00, 0xa000, 0xa200, 0xa000, 0x9d00, 0x9f00, 0xa100, 0xa300, 0xa500, 0xa700, 0xa900, 0xab00, 0xa580, 0xa780, 0xa980, 0xab80, 0xab80, 0xa980, 0xa780, 0xa580, 0x9500, 0x9500, 0x9500, 0x9500, 0x9e80, 0xa080, 0xa280, 0xa080, 0x7d80, 0x7f80, 0x8180, 0x8380, 0x7e00, 0x8000, 0x8200, 0x8400, 0x7e80, 0x8080, 0x8280, 0x8480, 0x8380, 0x8180, 0x7f80, 0x7d80, 0x9500, 0x9500, 0x9500, 0x9500, 0xa680, 0xa880, 0xaa80, 0xa880, 0x8e00, 0x9000, 0x9200, 0x9400, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9e80, 0xa080, 0xa280, 0xa080, 0xa600, 0xa800, 0xaa00, 0xa800, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9500, 0x9180, 0x9180, 0x9180, 0x9180, 0x9680, 0x9880, 0x9a80, 0x9c80, 0x9680, 0x9880, 0x9a80, 0x9c80, 0x9680, 0x9880, 0x9a80, 0x9c80, 0x9500, 0x9700, 0x9900, 0x9b00, 0xac80, 0xac80, 0xac80, 0xac80, 0x9300, 0x9300, 0x9300, 0x9300, 0x9380, 0x9380, 0x9380, 0x9380, };
-
void UploadMode7KoopaBossesAndLavaAnimation() { // 0098a9
int8 v0 = misc_nmito_use_flag & 1;
if (!(misc_nmito_use_flag & 1)) {
@@ -1673,7 +1646,7 @@ void GameMode09_EraseFile() { // 009b1a
uint8 v0;
uint16 v3;
- FileSelectColorMath(0x39C9, 0x60);
+ FileSelectColorMath(g_lunar_magic ? palettes_background_color : 0x39C9, 0x60);
if (((io_controller_press2 | io_controller_press1) & 0x40) != 0) {
Gamemode_9_A_Common();
} else {
@@ -1776,12 +1749,22 @@ void GameMode07_TitleScreenDemo() { // 009c64
GameMode07_TitleScreenDemo_InitializeFileSelect();
} else {
DamagePlayer_DisableButtons();
+
+ if (HAS_LM_FEATURE(kLmFeature_CustomTitleScreenDemo)) {
+ if (LmHook_CustomTitleScreenDemo())
+ GameMode14_InLevel();
+ else
+ misc_game_mode = 2;
+ return;
+ }
+
uint8 v0 = misc_title_screen_movement_data_index;
if (!--timer_title_screen_input_timer) {
timer_title_screen_input_timer = kGameMode07_TitleScreenDemo_ItrCntrlrSqnc[misc_title_screen_movement_data_index + 1];
v0 = misc_title_screen_movement_data_index + 2;
misc_title_screen_movement_data_index += 2;
}
+ assert(v0 != 0);
if (kGameMode07_TitleScreenDemo_ItrCntrlrSqnc[v0 - 2] == 0xFF) {
GameMode07_TitleScreenDemo_FadeOutToTitleScreen();
} else {
@@ -1829,7 +1812,7 @@ uint8 GameMode07_TitleScreenDemo_009CBE() { // 009cbe
void GameMode08_FileSelect() { // 009cd1
uint8 v0;
- FileSelectColorMath(0x7393, 0x20);
+ FileSelectColorMath(g_lunar_magic ? palettes_background_color : 0x7393, 0x20);
CheckWhichControllersArePluggedIn();
if ((v0 = HandleMenuCursor_Main_ReturnsTwice(2)) == 0xff)
return;
@@ -2026,12 +2009,10 @@ void HandleMenuCursor_009ED4(uint8 k) { // 009ed4
}
void InitializeSaveData() { // 009f06
- uint8 v0 = -115;
- do
- ow_save_buffer[--v0] = 0;
- while (v0);
+ memset(ow_save_buffer, 0, 141);
for (uint8 i = 7; (i & 0x80) == 0; --i)
ow_save_buffer[LOBYTE(kInitializeSaveData_InitialLevelFlags[i])] = HIBYTE(kInitializeSaveData_InitialLevelFlags[i]);
+ LmHook_InitializeSaveData();
for (uint8 j = 21; (j & 0x80) == 0; --j)
ow_save_buffer[j + 111] = kInitializeSaveData_InitialOWPlayerPos[j];
}
@@ -2132,6 +2113,10 @@ LABEL_16:
}
void InitializeLevelLayer3_GenerateInteractiveTideWater() { // 00a045
+ if (HAS_LM_FEATURE(kLmFeature_TideWaterTweak)) {
+ LmHook_InitializeLevelLayer3_GenerateInteractiveTideWater();
+ return;
+ }
for (uint16 i = 256; i < 0x1B00; i += 256) {
int16 v1 = 88;
do {
@@ -2196,8 +2181,10 @@ void GameMode0C_LoadOverworld() { // 00a087
mirror_current_layer2_xpos = mirror_current_layer1_xpos;
mirror_current_layer1_ypos = kGameMode0C_LoadOverworld_DATA_00A079[v4];
mirror_current_layer2_ypos = mirror_current_layer1_ypos;
+ if (g_lunar_magic)
+ LmHook_GameMode0C_LoadOverworld(v4);
UploadGraphicsFiles();
- GraphicsDecompress(0x14);
+ LmHook_OwGraphicsDecompress();
BufferPalettesRoutines_Overworld();
UpdateEntirePalette();
graphics_stripe_image_to_upload = 6;
@@ -2285,7 +2272,9 @@ void GameMode14_InLevel() { // 00a1da
HandleStandardLevelCameraScroll();
HandleScrollSpriteAndLayer3Scrolling();
CheckIfLevelTilemapsNeedScrollUpdate();
- HandleLevelTileAnimations();
+ if (HAS_HACK(kHack_Walljump))
+ HackHandleWalljump();
+ LmHook_LevelTileAnimations();
} else {
GameMode14_InLevel_InMode7Level();
}
@@ -2315,10 +2304,6 @@ void UpdateCurrentPlayerPositionRAM() { // 00a2f3
player_current_ypos = player_ypos;
}
-static const uint16 kPlayerPalettes[] = {
- 0x635f, 0x581d, 0x0a, 0x391f, 0x44c4, 0x4e08, 0x6770, 0x30b6, 0x35df, 0x3ff, 0x4f3f, 0x581d, 0x1140, 0x3fe0, 0x3c07, 0x7cae, 0x7db3, 0x2f00, 0x165f, 0x3ff, 0x635f, 0x581d, 0x2529, 0x7fff, 0x08, 0x17, 0x1f, 0x577b, 0xddf, 0x3ff, 0x3b1f, 0x581d, 0x2529, 0x7fff, 0x1140, 0x1e0, 0x2e0, 0x577b, 0xddf, 0x3ff
-};
-
const uint16 *GetPlayerPalette() {
return kPlayerPalettes + ((pointer_player_palette - 0xb2c8) >> 1);
}
@@ -2359,6 +2344,8 @@ void UploadLevelExAnimationData() { // 00a390
SmwCopyToVram(graphics_tile_anim_vramaddress1, g_ram + graphics_tile_anim_source_address1, 0x80);
}
}
+ if (g_lunar_magic)
+ LmHook_UploadLevelAnimations();
UploadLevelAnimations_YellowFlash(0x64);
}
@@ -2374,7 +2361,7 @@ void UploadLevelAnimations_RedFlash(uint8 a, uint8 r0) { // 00a41e
}
void RestoreSP1AfterMarioStart() { // 00a436
- if (flag_restoresp1_tiles_after_mario_start) {
+ if (flag_restoresp1_tiles_after_mario_start && !g_lunar_magic) {
flag_restoresp1_tiles_after_mario_start = 0;
SmwCopyToVram(0x64a0, g_ram + 0xbf6, 0xc0);
SmwCopyToVram(0x65a0, g_ram + 0xcb6, 0xc0);
@@ -2424,12 +2411,17 @@ void GameMode12_PrepareLevel() { // 00a59c
ClearLayer3Tilemap();
DamagePlayer_DisableButtons();
flag_upload_load_screen_letters_tovram = 0;
- SetStandardPPUSettings();
+ if (g_lunar_magic)
+ LmHook_SetStandardPPUSettings();
+ else
+ SetStandardPPUSettings();
InitializeStatusBarTilemap();
InitializeLevelLayer1And2Tilemaps();
if ((misc_nmito_use_flag & 0x80) == 0) {
UploadGraphicsFiles();
BufferPalettesRoutines_Levels();
+ if (g_lunar_magic)
+ LmHook_PrepareLevel();
GameMode12_PrepareLevel_InitializeLayer3RAM();
InitializeLevelLayer3();
InitializeLevelTileAnimations();
@@ -2443,7 +2435,10 @@ void GameMode12_PrepareLevel() { // 00a59c
UpdateStatusBarCounters();
uint8 *v0 = g_ram + 0x905;
uint8 *v1 = g_ram + 0x703;
- MemCpy(v0, v1, 0x1F0);
+ if (HAS_LM_FEATURE(kLmFeature_Copy512colors) && misc_nmito_use_flag != 0x80)
+ MemCpy(v0, v1, 0x200);
+ else
+ MemCpy(v0, v1, 0x1F0);
palettes_copy_of_background_color = palettes_background_color;
GameMode12_PrepareLevel_00919B();
CompressOamEntExt();
@@ -2453,7 +2448,7 @@ void GameMode12_PrepareLevel() { // 00a59c
void InitializeLevelTileAnimations() { // 00a5f9
counter_local_frames &= 0x18;
do {
- HandleLevelTileAnimations();
+ LmHook_LevelTileAnimations();
UploadLevelExAnimationData();
++counter_local_frames;
} while ((counter_local_frames & 7) != 0);
@@ -2501,6 +2496,11 @@ LABEL_6:
InitializeLevelRAM_00A6CC(1);
} else {
player_in_air_flag = 0;
+ if (g_lunar_magic) {
+ lm_var13CD = 0;
+ flag_got_midpoint = 0;
+ lunar_magic_FE = 0;
+ }
player_facing_direction = 1;
player_pipe_action = 1;
if (yoshi_carry_over_levels_flag)
@@ -2602,7 +2602,7 @@ void UploadLoadingLettersTiles() { // 00a7c2
}
void BufferLoadingLetterTiles() { // 00a82d
- const uint8 *p0 = GraphicsDecompress(0xF);
+ uint8 *p0 = LmHook_GraphicsDecompress(0xF);
if (flag_active_bonus_game)
p0 += 48;
uint16 v0 = 0;
@@ -2622,27 +2622,29 @@ void BufferLoadingLetterTiles() { // 00a82d
--v2;
} while (v2);
} while (v0 < 0x300);
- GraphicsDecompress(0);
- p0 = g_ram + 0xb3f0;
- uint16 v3 = 0;
- do {
- int16 v4 = 8;
+ if (!g_lunar_magic) {
+ LmHook_GraphicsDecompress(0);
+ p0 = g_ram + 0xb3f0;
+ uint16 v3 = 0;
do {
- decompressed_gfx_plus_256[v3 >> 1] = WORD(p0[0]);
- v3 += 2;
- p0 += 2;
- --v4;
- } while (v4);
- int16 v5 = 8;
- do {
- decompressed_gfx_plus_256[v3 >> 1] = p0[0];
- v3 += 2;
- p0 += 1;
- --v5;
- } while (v5);
- if (v3 == 192)
- p0 = &g_ram[0xb570];
- } while (v3 < 0x180);
+ int16 v4 = 8;
+ do {
+ decompressed_gfx_plus_256[v3 >> 1] = WORD(p0[0]);
+ v3 += 2;
+ p0 += 2;
+ --v4;
+ } while (v4);
+ int16 v5 = 8;
+ do {
+ decompressed_gfx_plus_256[v3 >> 1] = p0[0];
+ v3 += 2;
+ p0 += 1;
+ --v5;
+ } while (v5);
+ if (v3 == 192)
+ p0 = &g_ram[0xb570];
+ } while (v3 < 0x180);
+ }
flag_upload_load_screen_letters_tovram = 1;
flag_restoresp1_tiles_after_mario_start = 1;
}
@@ -2652,62 +2654,64 @@ void UploadGraphicsFiles_Layer3() { // 00a993
const uint8 *p0 = GraphicsDecompress(40 + i);
SmwCopyToVram(0x4000 + i * 0x400, p0, 0x800);
}
- UploadGraphicsFiles_UploadGFXFile(0x6000, 0);
+ UploadGraphicsFiles_UploadGFXFile(0x6000, 0, 0);
}
void UploadGraphicsFiles() { // 00a9da
uint8 arr[4];
- int8 v0 = 3;
- uint8 v1 = 4 * graphics_level_sprite_graphics_setting;
- do
- arr[v0--] = kUploadGraphicsFiles_SpriteGFXList[v1++];
- while (v0 >= 0);
- uint8 r15 = 3;
- do {
- uint8 v2 = r15;
- uint16 vmaddl = kUploadGraphicsFiles_DATA_00A9D2[v2] << 8;
- if (misc_currently_loaded_sprite_graphics_files[v2] != arr[v2])
- UploadGraphicsFiles_UploadGFXFile(vmaddl, arr[v2]);
- --r15;
- } while ((r15 & 0x80) == 0);
- for (uint8 i = 3; (i & 0x80) == 0; --i)
- misc_currently_loaded_sprite_graphics_files[i] = arr[i];
+
+ bool lunar_magic_upload_hack = HAS_LM_FEATURE(kLmFeature_GfxUpload);
+
+ for (int i = 0; i < 4; i++)
+ arr[3 - i] = kUploadGraphicsFiles_SpriteGFXList[4 * graphics_level_sprite_graphics_setting + i];
+ for(int i = 3; i >= 0; i--) {
+ uint16 vmaddr = kUploadGraphicsFiles_DATA_00A9D2[i] << 8;
+ if (lunar_magic_upload_hack || misc_currently_loaded_sprite_graphics_files[i] != arr[i])
+ UploadGraphicsFiles_UploadGFXFile(vmaddr, arr[i], i + 8);
+ }
+ memcpy(misc_currently_loaded_sprite_graphics_files, arr, 4);
if (misc_level_tileset_setting >= 0xFE) {
if (misc_level_tileset_setting != 0xFE)
ConvertGFX27IntoNormallFormat(RtlGetVramAddr());
- for (int8 j = 3; j >= 0; --j)
- misc_currently_loaded_sprite_graphics_files[(uint8)j + 4] = 0x80;
+ for(int i = 0; i < 4; i++)
+ misc_currently_loaded_sprite_graphics_files[i + 4] = 0x80;
} else {
- int8 v4 = 3;
- uint8 v5 = 4 * misc_level_tileset_setting;
- do
- arr[v4--] = kUploadGraphicsFiles_FGAndBGGFXList[v5++];
- while (v4 >= 0);
- r15 = 3;
- do {
- uint8 v6 = r15;
- uint16 vmaddl = kUploadGraphicsFiles_DATA_00A9D6[v6] << 8;
- if (misc_currently_loaded_sprite_graphics_files[v6 + 4] != arr[v6])
- UploadGraphicsFiles_UploadGFXFile(vmaddl, arr[v6]);
- --r15;
- } while ((r15 & 0x80) == 0);
- for (uint8 k = 3; (k & 0x80) == 0; --k)
- misc_currently_loaded_sprite_graphics_files[k + 4] = arr[k];
+ for (int i = 0; i < 4; i++)
+ arr[3 - i] = kUploadGraphicsFiles_FGAndBGGFXList[4 * misc_level_tileset_setting + i];
+
+ static const uint8 kBgVramAddrs[6] = { 0x28,0x20,0x18,0x10, 8, 0 };
+ if (lunar_magic_upload_hack && lm_var9 == 0x42) {
+ for(int i = 5; i >= 0; i--)
+ UploadGraphicsFiles_UploadGFXFile(kBgVramAddrs[i] << 8, (i < 2) ? 0xff : arr[i - 2], i + 2);
+ } else {
+ for(int i = 3; i >= 0; i--) {
+ if (lunar_magic_upload_hack || misc_currently_loaded_sprite_graphics_files[i + 4] != arr[i])
+ UploadGraphicsFiles_UploadGFXFile(kBgVramAddrs[i + 2] << 8, arr[i], i + 4);
+ }
+ }
+ memcpy(&misc_currently_loaded_sprite_graphics_files[4], arr, 4);
+ if (lunar_magic_upload_hack)
+ LmHook_UploadGraphicsFiles();
}
}
-void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j) { // 00aa6b
+void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j, uint8 index) { // 00aa6b
uint16 v4;
uint16 v11;
uint16 *dst = RtlGetVramAddr() + dst_addr;
+ const uint8 *p0;
- const uint8 *p0 = GraphicsDecompress(j);
+ bool lunar_magic_upload_hack = HAS_LM_FEATURE(kLmFeature_GfxUpload);
+
+ p0 = lunar_magic_upload_hack ? LmHook_UploadGFXFile(j, index) : GraphicsDecompress(j);
if (j == 1 && (ow_level_tile_settings[73] & 0x80) != 0) {
p0 = GraphicsDecompress(0x31);
j = 1;
}
- if (misc_level_tileset_setting >= 0x11 && j == 8 || j == 30) {
+ bool lm_flag = HAS_LM_FEATURE(kLmFeature_4bppgfx);
+
+ if (misc_level_tileset_setting >= 0x11 && j == (lm_flag ? 0x32 : 8) || j == (lm_flag ? 0x32 : 30)) {
uint16 r10w = -256;
for (int8 i = 127; i >= 0; --i) {
for (int8 k = 7; k >= 0; --k) {
@@ -2736,17 +2740,25 @@ void UploadGraphicsFiles_UploadGFXFile(uint16 dst_addr, uint8 j) { // 00aa6b
else
r10w = 0;
}
- for (int8 ii = 7; ii >= 0; --ii) {
- v4 = WORD(*p0);
- *dst++ = v4;
- *(uint16 *)&graphics_3_bppto4_bppbuffer[(uint8)ii] = WORD(p0[0]) | swap16(v4);
- p0 += 2;
- }
- for (int8 jj = 7; jj >= 0; --jj) {
- uint16 r12w = p0[0];
- const uint8 *v7 = p0;
- *dst++ = r12w | r10w & (*(uint16 *)&graphics_3_bppto4_bppbuffer[(uint8)jj] | swap16(*(uint16 *)v7));
- ++p0;
+ if (lm_flag) {
+ for (int8 ii = 15; ii >= 0; --ii) {
+ v4 = WORD(*p0);
+ *dst++ = v4;
+ p0 += 2;
+ }
+ } else {
+ for (int8 ii = 7; ii >= 0; --ii) {
+ v4 = WORD(*p0);
+ *dst++ = v4;
+ *(uint16 *)&graphics_3_bppto4_bppbuffer[(uint8)ii] = WORD(p0[0]) | swap16(v4);
+ p0 += 2;
+ }
+ for (int8 jj = 7; jj >= 0; --jj) {
+ uint16 r12w = p0[0];
+ const uint8 *v7 = p0;
+ *dst++ = r12w | r10w & (*(uint16 *)&graphics_3_bppto4_bppbuffer[(uint8)jj] | swap16(*(uint16 *)v7));
+ ++p0;
+ }
}
}
}
@@ -2772,52 +2784,6 @@ void ConvertGFX27IntoNormallFormat(uint16 *dst) { // 00ab42
} while (--v11);
}
-static const uint16 kGlobalPalettes_Layer3[] = {
- 0x7393, 0x0, 0xcfb, 0x2feb, 0x7393, 0x0, 0x7fdd, 0x2d7f,
- 0x7393, 0x0, 0x7aab, 0x7fff, 0x7393, 0x0, 0x1e9b, 0x3b7f,
-};
-
-static const uint16 kGlobalPalettes_Objects[] = {
- 0x39ce, 0x00, 0x6318, 0x7f34, 0x7f95, 0x7ff8, 0x00, 0x32b7, 0x67fb, 0x200, 0x320, 0x3e0, 0x00, 0xd71, 0x7c3f, 0x1e9b, 0x137f, 0x3ff, 0x00, 0x2817, 0x401f, 0x4529, 0x59ad, 0x6610, 0x00, 0xd71, 0x1e9b, 0x3b7f, 0x7fff, 0x7fff, 0x00, 0x39ce, 0x5294, 0x6318, 0x739c, 0x2c5f, 0x00, 0x1ff, 0x31f, 0x3ff, 0xb7, 0x23f, 0x00, 0x6d08, 0x6dad, 0x7e31, 0xb7, 0x23f, 0x00, 0x11, 0x17, 0x1f, 0xb7, 0x23f, 0x00, 0x1e0, 0x2e0, 0x3e0, 0xb7, 0x23f
-};
-
-static const uint16 kGlobalPalettes_YoshiBerry[] = {
- 0x7FFF, 0, 0x320, 0x16, 0x1F, 0x17F, 0x29F,
- 0x7FFF, 0, 0x320,0x347D,0x551E,0x65FF,0x7B1F,
- 0x7FFF, 0, 0x320, 0x380,0x1FF1, 0x3F9,0x4FFF,
-};
-
-const uint16 kGlobalPalettes_Background[] = {
- 0x3a49, 0x428b, 0x4acd, 0x530f, 0x5b51, 0x6393, 0x7fff, 0x0, 0x7f20, 0x7f80, 0x7fe0, 0x7fe0,
- 0x3942, 0x5208, 0x6ace, 0x6312, 0x6b55, 0x7398, 0x3942, 0x5208, 0x6ace, 0x3942, 0x5208, 0x6ace,
- 0x4ed6, 0x5718, 0x5f5a, 0x679c, 0x6fde, 0x77ff, 0x7fff, 0x0, 0x7f20, 0x7f80, 0x7fe0, 0x7fe0,
- 0x20a3, 0x3148, 0x3dac, 0x39ce, 0x3e32, 0x4ab6, 0x20a2, 0x2d25, 0x3568, 0x358a, 0x24e4, 0x4a52,
- 0x50c8, 0x59cc, 0x526d, 0x58eb, 0x654c, 0x5ad0, 0x5d80, 0x7f39, 0x7e93, 0x65a8, 0x5648, 0x5728,
- 0x1462, 0x3546, 0x45a9, 0x520d, 0x62b1, 0x7b77, 0x0, 0x7b1e, 0x7b9f, 0x7f99, 0x7ff6, 0x7ffc,
- 0x0, 0x24c5, 0x2d49, 0x2dad, 0x2253, 0x3f18, 0x1060, 0x1881, 0x1ca3, 0x1ce4, 0x2909, 0x254b,
- 0x960, 0x1a4, 0x1e8, 0x22c, 0x291, 0x2f5, 0x7fff, 0x0, 0x7ee0, 0x7f20, 0x7f80, 0x7fe0,
-};
-
-static const uint16 kGlobalPalettes_Sprites[] = {
- 0x0, 0x24c5, 0x2d49, 0x2dad, 0x2253, 0x3f18, 0x2523, 0x35c4, 0x3e25, 0x4686, 0x4ee7, 0x401f,
- 0x0, 0x41c6, 0x7354, 0x7ffa, 0x7ffd, 0x6d08, 0x0, 0x3434, 0x443a, 0x659f, 0x116, 0x27f,
- 0x0, 0x24c5, 0x2d49, 0x2dad, 0x2253, 0x3f18, 0x0, 0x2dae, 0x3e32, 0x4ab6, 0x52f9, 0x2cf3,
- 0x0, 0x516b, 0x4e6d, 0x4fb3, 0x30bf, 0x371d, 0x2e32, 0x4a0d, 0x1088, 0x214a, 0x296d, 0x3dcf,
- 0x0, 0x2940, 0x3de0, 0x5280, 0xb7, 0x23f, 0x0, 0x39ce, 0x5294, 0x6318, 0xb7, 0x23f,
- 0x0, 0x7e70, 0x7ed3, 0x7f36, 0x7f99, 0x401f, 0x0, 0x39ce, 0x5294, 0x6318, 0x739c, 0x2c5f,
- 0x0, 0x4edf, 0x5ade, 0x66bd, 0x727c, 0x401f, 0x0, 0x7ff5, 0x7ff7, 0x7ff9, 0x7ffc, 0x7fff,
-};
-
-static const uint16 kGlobalPalettes_Foreground[] = {
- 0x0, 0xdaf, 0x2e79, 0x25e0, 0x2b1c, 0x320, 0x0, 0x2d6b, 0x3def, 0x4e73, 0x6318, 0x739c,
- 0x0, 0xe9, 0x220d, 0x58e, 0x1a33, 0x32b7, 0x0, 0x2de0, 0x52e0, 0x157f, 0x325f, 0x4b3f,
- 0x0, 0x59c8, 0x72ce, 0x39cb, 0x3e30, 0x4ab3, 0x0, 0x16, 0x1b, 0x15f, 0x21f, 0x31f,
- 0x0, 0x49ec, 0x524f, 0x5ab2, 0x6715, 0x7fdb, 0x0, 0x16, 0x1b, 0x15f, 0x21f, 0x31f,
- 0x0, 0x8c9, 0x194e, 0x29d3, 0x3e78, 0x531d, 0x0, 0x14c8, 0x1d09, 0x296c, 0x35cf, 0x4232,
- 0x55ef, 0x6eb5, 0x76f7, 0x7f39, 0x7f7b, 0x7fbd, 0x0, 0x2cc9, 0x414e, 0x55d3, 0x6e78, 0x7f1d,
- 0x0, 0x1e9, 0x2ac, 0x32f, 0x399, 0x53fe, 0x0, 0x0, 0x0, 0x3c8f, 0x61d8, 0x7e7f,
- 0x0, 0x24c5, 0x2d49, 0x2dad, 0x2253, 0x3f18, 0x0, 0x16, 0x1b, 0x15f, 0x21f, 0x31f,
-};
void BufferPalettesRoutines_Levels() { // 00abed
BufferPalettesRoutines_LoadColorInVerticalStrip(2, 0x7fdd);
@@ -2851,57 +2817,19 @@ void BufferPalettesRoutines_LoadColors(const uint16 *r0, uint16 r4, uint16 r6, u
} while ((--r8 & 0x8000) == 0);
}
-static const uint16 kGlobalPalettes_OW_Objects[] = {
- 0x0, 0x2ce7, 0x3d6b, 0x4def, 0x5e73, 0x6ef7, 0x7fff,
- 0x7ff1, 0x1bf, 0x7e00, 0x3bf, 0x3e0, 0x7ffc, 0x7fff,
- 0x0, 0x194f, 0x3e78, 0x573e, 0x7e20, 0x7ee0, 0x7fe0,
- 0x0, 0x5231, 0x66f6, 0x7b9c, 0x1685, 0x2f4b, 0x47f1,
- 0x0, 0x194f, 0x3e78, 0x573e, 0x3ff, 0x7bde, 0x7c1f,
- 0x0, 0x194f, 0x3e78, 0x573e, 0x2d7f, 0x2f4b, 0x47f1,
-};
-
-static const uint16 GlobalPalettes_OW_Sprites[] = {
- 0x7fff, 0x0, 0xd71, 0x37f, 0x4fff, 0x4f3f, 0x7fe0,
- 0x7fff, 0x0, 0x1e0, 0x7dad, 0x380, 0xb7, 0x23f,
- 0x7fff, 0x0, 0x16, 0x1f, 0x6d08, 0x2ddd, 0x635f,
- 0x7fff, 0x0, 0x280, 0x3e0, 0x6d08, 0x261a, 0x573b,
- 0x7fff, 0x0, 0x7ee0, 0x7f20, 0x7f80, 0x7fe0, 0x7fe0,
- 0x7fff, 0x0, 0x7ee0, 0x7f20, 0x7f80, 0x7fe0, 0x7fe0,
- 0x0, 0x1b, 0x462d, 0x5ef3, 0x1685, 0x2f4b, 0x47f1,
- 0x0, 0x2ce7, 0x3d6b, 0x4def, 0x5e73, 0x6ef7, 0x7fff,
-};
-
-static const uint16 kGlobalPalettes_B5EC[] = {
- 0x7393, 0x0, 0x3ff, 0x573b, 0x7393, 0x3e75, 0x3212, 0x25af, 0x7393, 0x573b, 0x7fff, 0x0, 0x7393, 0x0, 0x573b, 0x7e6c,
-};
-
-static const uint16 kGlobalPalettes_OW_Areas[][28] = {
- {0x0, 0x1228, 0x12a8, 0x1348, 0x327b, 0x5bbf, 0x7d60, 0x0, 0x7bde, 0x1348, 0x7d60, 0x327b, 0x37bf, 0x2d7f, 0x0, 0x3268, 0x32e8, 0x1348, 0x5eff, 0x6f7f, 0x7d60, 0x0, 0x7bde, 0x573b, 0x7ea0, 0x1f6, 0x12a8, 0x1348,},
- {0x0, 0x1228, 0x12a8, 0x1348, 0x327b, 0x5bbf, 0x7e28, 0x0, 0x7bde, 0x1348, 0x7e28, 0x327b, 0x37bf, 0x3ff, 0x0, 0x3212, 0x3e75, 0x573b, 0x327b, 0x5bbf, 0x7e28, 0x0, 0x7bde, 0x573b, 0x7e28, 0x327b, 0x38c4, 0x1348,},
- {0x2cc7, 0x69f0, 0x66b2, 0x67d5, 0x6634, 0x53de, 0x7fff, 0x2cc7, 0x4560, 0x6680, 0x7ff7, 0x31f, 0x37f, 0x47ff, 0x412c, 0x69f0, 0x66b2, 0x67d5, 0x1f, 0x7fff, 0x2cc7, 0x2cc7, 0x69f0, 0x66b2, 0x67d5, 0x412c, 0x3ad5, 0x5b9c,},
- {0x0, 0x49ec, 0x562e, 0x62f1, 0x3126, 0x5bbf, 0x0, 0x0, 0x7bde, 0x5795, 0x7e28, 0x3126, 0x37bf, 0x2d7f, 0x0, 0x3126, 0x3d89, 0x49ec, 0x3126, 0x5bbf, 0x7e28, 0x0, 0x7bde, 0x573b, 0x32c6, 0x3126, 0x37f, 0x37f,},
- {0x0, 0x1a05, 0xac5, 0x22ef, 0x1a75, 0x4359, 0x7d60, 0x0, 0x7739, 0x22ef, 0x7d60, 0x1e18, 0x375c, 0x7e09, 0x0, 0x3660, 0x4b20, 0x22ef, 0x4e5a, 0x533a, 0x7d60, 0x0, 0x327b, 0x22ef, 0x2119, 0x1f6, 0x2de6, 0x36a8,},
- {0x2cc7, 0x69f0, 0x0, 0x0, 0x6634, 0x7ff9, 0x7fff, 0x0, 0x4560, 0x6680, 0x7ff7, 0x31f, 0x37f, 0x47ff, 0x412c, 0x69f0, 0x66b2, 0x67d5, 0x1f, 0x7fff, 0x2cc7, 0x2cc7, 0x69f0, 0x66b2, 0x67d5, 0x412c, 0x3ad5, 0x5b9c,},
-};
-
-static const uint16 kGlobalPalettes_OW_AreasPassed[][28] = {
- {0x0, 0x1533, 0x25b7, 0x363b, 0x25af, 0x5bbf, 0x5ac6, 0x0, 0x7bde, 0x363b, 0x5ac6, 0x25af, 0x37bf, 0x2d7f, 0x0, 0x1533, 0x25b7, 0x363b, 0x5eff, 0x6f7f, 0x5ac6, 0x0, 0x7bde, 0x573b, 0x5ac6, 0x25af, 0x12a8, 0x1348,},
- {0x0, 0x25b7, 0x363b, 0x46bf, 0x25af, 0x5b5f, 0x5ac6, 0x0, 0x7bde, 0x46bf, 0x5ac6, 0x25af, 0x37bf, 0x3ff, 0x0, 0x1685, 0x2f4b, 0x47f1, 0x25af, 0x5b5f, 0x5ac6, 0x0, 0x7bde, 0x573b, 0x5ac6, 0x25af, 0x38c4, 0x1348,},
- {0x1ce7, 0x19f3, 0x32b9, 0x4b7f, 0x7610, 0x2eb9, 0x7fff, 0x1ce7, 0x4560, 0x6680, 0x7ff7, 0x31f, 0x37f, 0x47ff, 0x1ce7, 0x19f3, 0x32b9, 0x4b7f, 0x1f, 0x7fff, 0x1ce7, 0x1ce7, 0x19f3, 0x32b9, 0x4b7f, 0x58c6, 0x3ad5, 0x5b9c,},
- {0x0, 0x1d6d, 0x29d0, 0x3633, 0x2d6b, 0x4ef9, 0x0, 0x0, 0x7bde, 0x3633, 0x3082, 0x2d6b, 0x37bf, 0x2d7f, 0x0, 0xa7, 0x152b, 0x218e, 0x2d6b, 0x4ef9, 0x3082, 0x0, 0x7bde, 0x4ef9, 0x3082, 0x2d6b, 0x3082, 0x1348,},
- {0x0, 0x2171, 0x31f5, 0x3279, 0x41f6, 0x573b, 0x7d60, 0x0, 0x7739, 0x3279, 0x7d60, 0x1e18, 0x375c, 0x7e09, 0x0, 0x3660, 0x4b20, 0x22ef, 0x527a, 0x533a, 0x7d60, 0x0, 0x218e, 0x3279, 0x2119, 0x3e75, 0x1135, 0x1d98,},
- {0x2cc7, 0x69f0, 0x0, 0x0, 0x6634, 0x7ff9, 0x7fff, 0x0, 0x4560, 0x6680, 0x7ff7, 0x31f, 0x37f, 0x47ff, 0x412c, 0x69f0, 0x66b2, 0x67d5, 0x1f, 0x7fff, 0x2cc7, 0x2cc7, 0x69f0, 0x66b2, 0x67d5, 0x412c, 0x3ad5, 0x5b9c,},
-};
-
-
void BufferPalettesRoutines_Overworld() { // 00ad25
+ if (HAS_LM_FEATURE(kLmFeature_OwPalette)) {
+ LmHook_OverworldPalette();
+ return;
+ }
+
int tt = kBufferPalettesRoutines_DATA_00AD1E[(misc_level_tileset_setting & 0xF) - 1];
- const uint16 *v0 = kGlobalPalettes_OW_Areas[tt];
- if (*(int16 *)&ow_level_tile_settings[72] < 0)
- v0 = kGlobalPalettes_OW_AreasPassed[tt];
+ const uint16 *v0 = &kGlobalPalettes_OW_Areas[tt * 28];
+ if (ow_level_tile_settings[73] & 0x80)
+ v0 = &kGlobalPalettes_OW_AreasPassed[tt * 28];
BufferPalettesRoutines_LoadColors(v0, 130, 6, 3);
BufferPalettesRoutines_LoadColors(kGlobalPalettes_OW_Objects, 82, 6, 5);
- BufferPalettesRoutines_LoadColors(GlobalPalettes_OW_Sprites, 258, 6, 7);
+ BufferPalettesRoutines_LoadColors(kGlobalPalettes_OW_Sprites, 258, 6, 7);
BufferPalettesRoutines_LoadColors(kGlobalPalettes_B5EC, 16, 7, 1);
}
@@ -2966,19 +2894,54 @@ void HandlePaletteFades_00AF35(bool run_code_at_end) { // 00af35
uint16 r2w;
palettes_copy_of_palette_mirror[0] = 510;
- for (uint16 i = 238; (i & 0x8000) == 0; i -= 18) {
- uint16 r0w = 7;
- do {
- int v1 = i >> 1;
- r2w = palettes_copy_of_palette_mirror[v1];
- palettes_copy_of_palette_mirror[v1] = HandlePaletteFades_00AFC0(palettes_palette_mirror[v1], r2w, r12, r14);
+ if (!g_lunar_magic) {
+ for (uint16 i = 0xee; (i & 0x8000) == 0; i -= 18) {
+ uint16 r0w = 7;
+ do {
+ int v1 = i >> 1;
+ r2w = palettes_copy_of_palette_mirror[v1];
+ palettes_copy_of_palette_mirror[v1] = HandlePaletteFades_00AFC0(palettes_palette_mirror[v1], r2w, r12, r14);
+ i -= 2;
+ } while (--r0w);
+ }
+ for (uint16 j = 4; (j & 0x8000) == 0; j -= 2) {
+ int v3 = j >> 1;
+ r2w = palettes_copy_of_palette_mirror[v3 + 13];
+ palettes_copy_of_palette_mirror[v3 + 13] = HandlePaletteFades_00AFC0(palettes_palette_mirror[v3 + 13], r2w, r12, r14);
+ }
+
+ } else if (HAS_LM_FEATURE(kLmFeature_WeirdPalette)) {
+ for (uint16 i = 0xfe; (i & 0x8000) == 0;) {
+ uint16 r0w = 0xf;
+ do {
+ int v1 = i >> 1;
+ r2w = palettes_copy_of_palette_mirror[v1];
+ palettes_copy_of_palette_mirror[v1] = HandlePaletteFades_00AFC0(palettes_palette_mirror[v1], r2w, r12, r14);
+ i -= 2;
+ } while (--r0w);
i -= 2;
- } while (--r0w);
- }
- for (uint16 j = 4; (j & 0x8000) == 0; j -= 2) {
- int v3 = j >> 1;
- r2w = palettes_copy_of_palette_mirror[v3 + 13];
- palettes_copy_of_palette_mirror[v3 + 13] = HandlePaletteFades_00AFC0(palettes_palette_mirror[v3 + 13], r2w, r12, r14);
+ }
+ palettes_copy_of_palette_mirror[9] = palettes_palette_mirror[9];
+ palettes_copy_of_palette_mirror[10] = palettes_palette_mirror[10];
+ palettes_copy_of_palette_mirror[11] = palettes_palette_mirror[11];
+ palettes_copy_of_palette_mirror[25] = palettes_palette_mirror[25];
+ palettes_copy_of_palette_mirror[26] = palettes_palette_mirror[26];
+ palettes_copy_of_palette_mirror[27] = palettes_palette_mirror[27];
+ palettes_copy_of_palette_mirror[29] = palettes_palette_mirror[29];
+ palettes_copy_of_palette_mirror[30] = palettes_palette_mirror[30];
+ palettes_copy_of_palette_mirror[31] = palettes_palette_mirror[31];
+ } else {
+ for (uint16 i = 0xfe; (i & 0x8000) == 0; ) {
+ uint16 r0w = 1;
+ do {
+ int v1 = i >> 1;
+ r2w = palettes_copy_of_palette_mirror[v1];
+ palettes_copy_of_palette_mirror[v1] = HandlePaletteFades_00AFC0(palettes_palette_mirror[v1], r2w, r12, r14);
+ i -= 2;
+ } while (--r0w);
+ if (i == 0x3e || i == 0x1e)
+ i -= 16;
+ }
}
r2w = palettes_background_color;
palettes_background_color = HandlePaletteFades_00AFC0(palettes_copy_of_background_color, r2w, r12, r14);
@@ -3051,30 +3014,35 @@ void PlayerState00_00B03E() { // 00b03e
}
void GraphicsDecompressionRoutines_DecompressGFX32And33() { // 00b888
- memcpy(g_ram + 0x2000, kGfx33, kGfx33_SIZE);
- uint8 *t8d = g_ram + 0xacfe;
- int16 v0 = 0x23ff;
-LABEL_2:;
- int16 v1 = 8;
- do {
- WORD(t8d[0]) = graphics_decompressedgfx32[(uint16)v0--];
- t8d -= 2;
- } while (--v1);
- int16 v2 = 8;
- while (1) {
- uint16 v3 = v0 - 1;
- WORD(t8d[0]) = *(uint16 *)&graphics_decompressedgfx32[v3];
- v0 = v3 - 1;
- if (v0 < 0)
- break;
- t8d -= 2;
- if (!--v2)
- goto LABEL_2;
+ if (HAS_LM_FEATURE(kLmFeature_4bppgfx)) {
+ memcpy(g_ram + 0x7d00, kGfx33, kGfx33_SIZE);
+ memcpy(g_ram + 0x2000, kGfx32, kGfx32_SIZE);
+ } else {
+ memcpy(g_ram + 0x2000, kGfx33, kGfx33_SIZE);
+ uint8 *t8d = g_ram + 0xacfe;
+ int16 v0 = 0x23ff;
+ LABEL_2:;
+ int16 v1 = 8;
+ do {
+ WORD(t8d[0]) = graphics_decompressedgfx32[(uint16)v0--];
+ t8d -= 2;
+ } while (--v1);
+ int16 v2 = 8;
+ while (1) {
+ uint16 v3 = v0 - 1;
+ WORD(t8d[0]) = *(uint16 *)&graphics_decompressedgfx32[v3];
+ v0 = v3 - 1;
+ if (v0 < 0)
+ break;
+ t8d -= 2;
+ if (!--v2)
+ goto LABEL_2;
+ }
+ memcpy(g_ram + 0x2000, kGfx32, kGfx32_SIZE);
}
- memcpy(g_ram + 0x2000, kGfx32, kGfx32_SIZE);
}
-void GraphicsDecompressTo(const uint8 *src, uint8 *pdst) { // 00b8de
+int DecompressTo(const uint8 *src, uint8 *pdst) { // 00b8de
uint8 cmd;
uint16 v0 = 0;
while (1) {
@@ -3127,12 +3095,12 @@ void GraphicsDecompressTo(const uint8 *src, uint8 *pdst) { // 00b8de
} while (--len);
}
}
+ return v0;
}
-const uint8 *GraphicsDecompress(uint8 j) { // 00ba28
+uint8 *GraphicsDecompress(uint8 j) { // 00ba28
MemBlk blk = kGraphicsPtrs(j);
- memcpy(g_ram + 0xad00, blk.ptr, blk.size);
-// GraphicsDecompressTo(p, g_ram + 0xad00);
+ DecompressTo(blk.ptr, g_ram + 0xad00);
return g_ram + 0xad00;
}
@@ -3161,15 +3129,26 @@ void GenerateTile() { // 00beb0
ptr_lo_map16_data = NULL;
gta.ptr_lo_map16_data = GetPtrToLevelDataLayout();
// @25: Write to 0x6 = 0x25: 0xbf67: r18=0x4100: r20=0xc19e: a = 0x25, x = 0x0, y = 0xd, c = 0, r4 = 24, r5 = 40, r6 = 25, r9=1, blocks_ypos = 482/15e
- uint8 v3, v4;
- if ((r9 & 1) != 0) {
- v3 = HIBYTE(blocks_ypos) & 1;
- v4 = HIBYTE(blocks_xpos) & 1;
+ uint8 v3, v4, r4;
+ if (g_lunar_magic) {
+ if ((r9 & 1) != 0) {
+ v3 = HIBYTE(blocks_ypos) & 1;
+ v4 = HIBYTE(blocks_xpos);
+ } else {
+ v3 = HIBYTE(blocks_xpos) & 1;
+ v4 = HIBYTE(blocks_ypos);
+ }
+ r4 = (4 * (2 * v4 + v3)) & 0xc | 0x20;
} else {
- v3 = HIBYTE(blocks_xpos) & 1;
- v4 = HIBYTE(blocks_ypos);
+ if ((r9 & 1) != 0) {
+ v3 = HIBYTE(blocks_ypos) & 1;
+ v4 = HIBYTE(blocks_xpos) & 1;
+ } else {
+ v3 = HIBYTE(blocks_xpos) & 1;
+ v4 = HIBYTE(blocks_ypos);
+ }
+ r4 = (4 * (2 * v4 + v3)) | 0x20;
}
- uint8 r4 = (4 * (2 * v4 + v3)) | 0x20;
if (misc_current_layer_being_processed)
r4 += 16;
bool v6 = __CFSHL__(blocks_ypos & 0xF0, 1);
@@ -3187,11 +3166,22 @@ void GenerateTile() { // 00beb0
v8 = mirror_current_layer2_ypos;
}
} else {
- v7 = mirror_current_layer1_xpos - 128;
- v8 = mirror_current_layer1_ypos;
- if (misc_current_layer_being_processed) {
- v7 = mirror_current_layer2_xpos;
- v8 = mirror_current_layer2_ypos - 128;
+ if (g_lunar_magic) {
+ v7 = mirror_current_layer1_xpos;
+ v8 = mirror_current_layer1_ypos;
+ if (misc_current_layer_being_processed) {
+ v7 = mirror_current_layer2_xpos;
+ v8 = mirror_current_layer2_ypos;
+ }
+ v7 -= 0x80;
+ v8 -= 0x80;
+ } else {
+ v7 = mirror_current_layer1_xpos - 128;
+ v8 = mirror_current_layer1_ypos;
+ if (misc_current_layer_being_processed) {
+ v7 = mirror_current_layer2_xpos;
+ v8 = mirror_current_layer2_ypos - 128;
+ }
}
}
gta.r8 = v7;
@@ -3220,7 +3210,10 @@ void sub_C077(GenTileArgs *gta) { // 00c077
uint16 v0 = blocks_ypos & 0x1F0 | ((uint8)blocks_xpos >> 4);
uint16 v1 = blocks_map16_to_generate;
uint8 *v2 = gta->ptr_lo_map16_data + v0;
- v2[0x10000] &= ~1;
+ if (g_lunar_magic)
+ v2[0x10000] = 0;
+ else
+ v2[0x10000] &= ~1;
uint8 v3 = kGenericPage00Tile_Map16Page00TileLo[v1];
v2[0] = v3;
GenericPage01Tile_00C0FB(gta, 2 * v3);
@@ -3235,7 +3228,10 @@ void GenericPage01Tile(GenTileArgs *gta) { // 00c0c4
uint16 v0 = blocks_ypos & 0x1F0 | ((uint8)blocks_xpos >> 4);
uint16 v1 = (uint8)(blocks_map16_to_generate - 9);
uint8 *v2 = gta->ptr_lo_map16_data + v0;
- v2[0x10000] |= 1;
+ if (g_lunar_magic)
+ v2[0x10000] = 1;
+ else
+ v2[0x10000] |= 1;
uint8 v3 = kGenericPage01Tile_Map16Page01TileLo[v1];
v2[0] = v3;
GenericPage01Tile_00C0FB(gta, 2 * (v3 | 0x100));
@@ -3249,44 +3245,50 @@ void GenericPage01Tile_00C0FB(GenTileArgs *gta, uint16 j) { // 00c0fb
uint16 v1 = gta->r8 & 0xFFF0;
if ((gta->r8 & 0x8000) == 0) {
if (v1 == gta->r12)
- goto LABEL_15;
+ goto LABEL_X;
if (v1 >= gta->r12)
return;
}
uint16 v2 = v1 + 512;
if (v2 <= gta->r12)
return;
-LABEL_15:;
- uint16 v5 = stripe_image_upload;
- uint8 v6 = gta->r6;
- stripe_image_upload_data[v5] = v6;
- stripe_image_upload_data[v5 + 8] = v6;
- uint8 v8 = gta->r7;
- stripe_image_upload_data[v5 + 1] = v8;
- stripe_image_upload_data[v5 + 9] = v8 + 32;
- stripe_image_upload_data[v5 + 2] = 0;
- stripe_image_upload_data[v5 + 10] = 0;
- stripe_image_upload_data[v5 + 3] = 3;
- stripe_image_upload_data[v5 + 11] = 3;
- stripe_image_upload_data[v5 + 16] = -1;
- const uint16 *rp = GetMap16RomAddr(13, pointer_map16_tiles[j >> 1]);
- *(uint16 *)&stripe_image_upload_data[v5 + 4] = rp[0];
- *(uint16 *)&stripe_image_upload_data[v5 + 12] = rp[1];
- *(uint16 *)&stripe_image_upload_data[v5 + 6] = rp[2];
- *(uint16 *)&stripe_image_upload_data[v5 + 14] = rp[3];
- stripe_image_upload = v5 + 16;
- return;
- }
- uint16 v3 = gta->r10 & 0xFFF0;
- if ((gta->r10 & 0x8000) == 0) {
- if (v3 == gta->r14)
- goto LABEL_15;
- if (v3 >= gta->r14)
+LABEL_X:
+ if (g_lunar_magic)
+ goto LABEL_11;
+ } else {
+LABEL_11:;
+ uint16 v3 = gta->r10 & 0xFFF0;
+ if ((gta->r10 & 0x8000) == 0) {
+ if (v3 == gta->r14)
+ goto LABEL_15;
+ if (v3 >= gta->r14)
+ return;
+ }
+ uint16 v4 = v3 + 512;
+ if (v4 <= gta->r14)
return;
}
- uint16 v4 = v3 + 512;
- if (v4 > gta->r14)
- goto LABEL_15;
+
+LABEL_15:;
+ uint16 v5 = stripe_image_upload;
+ uint8 v6 = gta->r6;
+ stripe_image_upload_data[v5] = v6;
+ stripe_image_upload_data[v5 + 8] = v6;
+ uint8 v8 = gta->r7;
+ stripe_image_upload_data[v5 + 1] = v8;
+ stripe_image_upload_data[v5 + 9] = v8 + 32;
+ stripe_image_upload_data[v5 + 2] = 0;
+ stripe_image_upload_data[v5 + 10] = 0;
+ stripe_image_upload_data[v5 + 3] = 3;
+ stripe_image_upload_data[v5 + 11] = 3;
+ stripe_image_upload_data[v5 + 16] = -1;
+ const uint16 *rp = Lm_GetMap16RomAddr(j >> 1);
+ *(uint16 *)&stripe_image_upload_data[v5 + 4] = rp[0];
+ *(uint16 *)&stripe_image_upload_data[v5 + 12] = rp[1];
+ *(uint16 *)&stripe_image_upload_data[v5 + 6] = rp[2];
+ *(uint16 *)&stripe_image_upload_data[v5 + 14] = rp[3];
+ stripe_image_upload = v5 + 16;
+ return;
}
void EraseYoshiCoin(GenTileArgs *gta) { // 00c1ac
@@ -3322,7 +3324,7 @@ LABEL_14:;
stripe_image_upload_data[v4 + 15] = 7;
stripe_image_upload_data[v4 + 24] = -1;
g_ram[6] = 13;
- const uint16 *rp = GetMap16RomAddr(13, pointer_map16_tiles[37]);
+ const uint16 *rp = Lm_GetMap16RomAddr(37);
uint16 v9 = rp[0];
*(uint16 *)&stripe_image_upload_data[v4 + 4] = v9;
*(uint16 *)&stripe_image_upload_data[v4 + 8] = v9;
@@ -3748,7 +3750,7 @@ void PlayerState00_00C96B() { // 00c96b
PlayerState00_00CD24();
if (!timer_hdmawindow_scaling_factor) {
uint8 v0 = flag_secret_goal_sprite + 1;
- if (flag_secret_goal_sprite == 2) {
+ if (flag_secret_goal_sprite == 2 && !g_lunar_magic) {
ow_players_map[0] = 1;
v0 = 0;
}
@@ -3766,7 +3768,7 @@ void PlayerState00_00C96B() { // 00c96b
}
}
} else {
- if (timer_end_level >= 0x28) {
+ if (timer_end_level >= (g_lunar_magic ? 0x38 : 0x28)) {
player_facing_direction = 1;
io_controller_hold1 = 1;
player_xspeed = 5;
@@ -3790,10 +3792,10 @@ void PlayerState00_LevelFinished(uint8 j, uint8 a) { // 00c9fe
misc_exit_level_action = a;
if (misc_currently_active_boss_end_cutscene) {
uint8 v2 = 8;
- if (ow_level_number_lo == 19)
+ if (ow_level_number_lo == kLevelsThatTriggerCutscenes[8])
++misc_exit_level_action;
- if (ow_level_number_lo != 49) {
- while (ow_level_number_lo != kPlayerState00_LevelsThatTriggerCutscenes[v2 - 1]) {
+ if (ow_level_number_lo != kLevelsThatTriggerCutscenes[9]) {
+ while (ow_level_number_lo != kLevelsThatTriggerCutscenes[v2 - 1]) {
if (!--v2)
goto LABEL_9;
}
@@ -5914,7 +5916,7 @@ void RunPlayerBlockCode_00F2C9(uint8 j, uint8 a) { // 00f2c9
blocks_map16_to_generate = 2;
GenerateTile();
SpawnGlitterEffectForCoin();
- if (unusedram_disable_midpoint)
+ if (g_lunar_magic || lm_var13CD)
PlayerState00_SetMidpointFlag();
if (!player_current_power_up)
player_current_power_up = 1;
@@ -6041,42 +6043,74 @@ PairU16 GetPlayerLevelCollisionMap16ID_WallRun(uint8 k) { // 00f44d
uint8 v1 = k; // moved incr to outside
blocks_xpos = kGetPlayerLevelCollisionMap16ID_DATA_00E832[(v1 >> 1) - 1] + player_xpos;
blocks_ypos = kGetPlayerLevelCollisionMap16ID_DATA_00E89C[(v1 >> 1) - 1] + player_ypos;
- return GetPlayerLevelCollisionMap16ID_Entry2(v1);
+ PairU16 p = GetPlayerLevelCollisionMap16ID_Entry2(v1);
+ return p;
+}
+
+static const uint8 kLevelDataLayoutTables_EightBitLo_Horizontal[32] = { 0x0, 0xb0, 0x60, 0x10, 0xc0, 0x70, 0x20, 0xd0, 0x80, 0x30, 0xe0, 0x90, 0x40, 0xf0, 0xa0, 0x50,
+0x0, 0xb0, 0x60, 0x10, 0xc0, 0x70, 0x20, 0xd0, 0x80, 0x30, 0xe0, 0x90, 0x40, 0xf0, 0xa0, 0x50,};
+
+static const uint8 kLevelDataLayoutTables_EightBitLo_Vertical[28] = {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+};
+static const uint8 kLevelDataLayoutTables_EightBitHi_Horizontal[32] = { 0xc8, 0xc9, 0xcb, 0xcd, 0xce, 0xd0, 0xd2, 0xd3, 0xd5, 0xd7, 0xd8, 0xda, 0xdc, 0xdd, 0xdf, 0xe1,
+0xe3, 0xe4, 0xe6, 0xe8, 0xe9, 0xeb, 0xed, 0xee, 0xf0, 0xf2, 0xf3, 0xf5, 0xf7, 0xf8, 0xfa, 0xfc,};
+
+static const uint8 kLevelDataLayoutTables_EightBitHi_Vertical[28] = { 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2,
+0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,};
+
+
+uint16 GetLevelLayoutPtr_Vertical(int i) {
+ assert(i < 28);
+ return PAIR16(kLevelDataLayoutTables_EightBitHi_Vertical[i], kLevelDataLayoutTables_EightBitLo_Vertical[i]);
+}
+
+uint16 GetLevelLayoutPtr_Horizontal(int i) {
+ if (i >= 32)
+ printf("WARNING: GetLevelLayoutPtr_Horizontal: Reading invalid slot %d\n", i);
+ if (HAS_LM_FEATURE(kLmFeature_LoadLevel))
+ return PAIR16(L1_Screen_8bit_Hi[i], L1_Screen_8bit_Lo[i]);
+ else
+ return PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[i], kLevelDataLayoutTables_EightBitLo_Horizontal[i]);
}
PairU16 GetPlayerLevelCollisionMap16ID_Entry2(uint8 k) { // 00f465
uint16 r0w;
+ uint16 level_height = g_lunar_magic ? lm_level_height : 0x1b0;
+
misc_color_of_palace_switch_pressed2 = 0;
if ((temp8e & 0x80) != 0) {
if (temp8e & 0x7f) {
if (HIBYTE(blocks_xpos) >= 2 || HIBYTE(blocks_ypos) >= 0xE)
- return MakePairU16_AY(0, 0x25);
- r0w = PAIR16(kLevelDataLayoutTables_EightBitHi_Vertical[HIBYTE(blocks_ypos) + 14], kLevelDataLayoutTables_EightBitLo_Vertical[HIBYTE(blocks_ypos) + 14]) +
- (blocks_ypos & 0xF0 | ((uint8)blocks_xpos >> 4) | HIBYTE(blocks_xpos) << 8);
- } else if (blocks_ypos < 0x1B0) {
+ goto default_return;
+ r0w = GetLevelLayoutPtr_Vertical(HIBYTE(blocks_ypos) + 14) + (blocks_ypos & 0xF0 | ((uint8)blocks_xpos >> 4) | HIBYTE(blocks_xpos) << 8);
+ } else if (blocks_ypos < level_height) {
if (HIBYTE(blocks_xpos) >= 0x10)
- return MakePairU16_AY(0, 0x25);
- r0w = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[HIBYTE(blocks_xpos) + 16], kLevelDataLayoutTables_EightBitLo_Horizontal[HIBYTE(blocks_xpos) + 16]) +
- (blocks_ypos & 0xF0 | ((uint8)blocks_xpos >> 4) | HIBYTE(blocks_ypos) << 8);
+ goto default_return;
+ r0w = GetLevelLayoutPtr_Horizontal(HIBYTE(blocks_xpos) + 16) + (blocks_ypos & 0xF0 | ((uint8)blocks_xpos >> 4) | HIBYTE(blocks_ypos) << 8);
} else {
- return MakePairU16_AY(0, 0x25);
+ goto default_return;
}
} else {
if (temp8e) {
if (HIBYTE(blocks_xpos) >= 2 || HIBYTE(blocks_ypos) >= misc_screens_in_lvl)
- return MakePairU16_AY(0, 0x25);
- r0w = PAIR16(kLevelDataLayoutTables_EightBitHi_Vertical[HIBYTE(blocks_ypos)], kLevelDataLayoutTables_EightBitLo_Vertical[HIBYTE(blocks_ypos)]) +
- (blocks_ypos & 0xF0 | ((uint8)blocks_xpos >> 4) | HIBYTE(blocks_xpos) << 8);
+ goto default_return;
+ r0w = GetLevelLayoutPtr_Vertical(HIBYTE(blocks_ypos)) + (blocks_ypos & 0xF0 | ((uint8)blocks_xpos >> 4) | HIBYTE(blocks_xpos) << 8);
} else {
- if (blocks_ypos >= 0x1B0 || HIBYTE(blocks_xpos) >= misc_screens_in_lvl)
- return MakePairU16_AY(0, 0x25);
- r0w = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[HIBYTE(blocks_xpos)], kLevelDataLayoutTables_EightBitLo_Horizontal[HIBYTE(blocks_xpos)]) +
- (blocks_ypos & 0xF0 | ((uint8)blocks_xpos >> 4) | HIBYTE(blocks_ypos) << 8);
+ if (blocks_ypos >= level_height || HIBYTE(blocks_xpos) >= misc_screens_in_lvl)
+ goto default_return;
+ r0w = GetLevelLayoutPtr_Horizontal(HIBYTE(blocks_xpos)) + (blocks_ypos & 0xF0 | ((uint8)blocks_xpos >> 4) | HIBYTE(blocks_ypos) << 8);
}
}
blocks_currently_processed_map16_tile_lo = g_ram[r0w];
- uint8 v7 = ModifyMap16IDForSpecialBlocks(g_ram[0x10000 + r0w]);
+ uint8 v7 = LmHook_ModifyMap16IDForSpecialBlocks(g_ram[0x10000 + r0w]);
return MakePairU16_AY(v7, blocks_currently_processed_map16_tile_lo);
+
+default_return:
+ if (g_lunar_magic)
+ blocks_currently_processed_map16_tile_lo = 0x25;
+ return MakePairU16_AY(0, 0x25);
}
uint8 ModifyMap16IDForSpecialBlocks(uint8 a) { // 00f545
@@ -6195,6 +6229,9 @@ void PlayerGFXRt_00F636(uint8 r10, uint8 r11, uint8 r12, uint8 r13) { // 00f636
}
void HandleStandardLevelCameraScroll() { // 00f6db
+ if (g_lunar_magic)
+ LmHook_HandleStandardLevelCameraScroll();
+
camera_pos_for_scroll[0] = player_relative_position_needed_to_scroll_screen - 12;
camera_pos_for_scroll[1] = player_relative_position_needed_to_scroll_screen - 12 + 24;
PointU16 *pt = get_PointU16(misc_layer1_pos, 0);
@@ -6209,8 +6246,8 @@ void HandleStandardLevelCameraScroll() { // 00f6db
uint16 r0w = player_xpos - mirror_current_layer1_xpos;
if ((int16)(r0w - player_relative_position_needed_to_scroll_screen) >= 0)
v7 = 2;
- uint16 r2w = player_xpos - mirror_current_layer1_xpos - camera_pos_for_scroll[v7 >> 1];
- if (((kHandleStandardLevelCameraScroll_DATA_00F6A3[v7 >> 1] ^ r2w) & 0x8000) != 0) {
+ uint16 r2w = r0w - camera_pos_for_scroll[v7 >> 1];
+ if ((r2w != 0 || !g_lunar_magic) && ((kHandleStandardLevelCameraScroll_DATA_00F6A3[v7 >> 1] ^ r2w) & 0x8000) != 0) {
r2w = HandleStandardLevelCameraScroll_00F8AB(r2w);
uint16 v8 = mirror_current_layer1_xpos + r2w;
if ((int16)v8 < 0)
@@ -6221,7 +6258,7 @@ void HandleStandardLevelCameraScroll() { // 00f6db
}
}
} else {
- HandleStandardLevelCameraScroll_00F7F4(0xC0);
+ HandleStandardLevelCameraScroll_00F7F4(g_lunar_magic ? LmHook_HandleStandardLevelCameraScrollD() : 0xc0);
if (flag_layer1_horiz_scroll_level_setting) {
uint16 r0w = player_xpos - mirror_current_layer1_xpos;
uint8 v1 = ((int16)(r0w - player_relative_position_needed_to_scroll_screen) < 0) ? 0 : 2;
@@ -6245,27 +6282,37 @@ void HandleStandardLevelCameraScroll() { // 00f6db
}
}
}
- if (flag_layer2_horiz_scroll_level_setting) {
- uint16 v9 = mirror_current_layer1_xpos;
- if (flag_layer2_horiz_scroll_level_setting != 1)
- v9 >>= 1;
- mirror_current_layer2_xpos = v9;
- }
- if (flag_layer2_vert_scroll_level_setting) {
- uint16 v10 = mirror_current_layer1_ypos;
- if (flag_layer2_vert_scroll_level_setting != 1)
- v10 = (flag_layer2_vert_scroll_level_setting != 2) ? v10 >> 5 : v10 >> 1;
- mirror_current_layer2_ypos = camera_layer2_ypos_relative_to_layer1 + v10;
+ if (g_lunar_magic) {
+ LmHook_HandleStandardLevelCameraScrollB();
+ } else {
+ if (flag_layer2_horiz_scroll_level_setting) {
+ uint16 v9 = mirror_current_layer1_xpos;
+ if (flag_layer2_horiz_scroll_level_setting != 1)
+ v9 >>= 1;
+ mirror_current_layer2_xpos = v9;
+ }
+ if (flag_layer2_vert_scroll_level_setting) {
+ uint16 v10 = mirror_current_layer1_ypos;
+ if (flag_layer2_vert_scroll_level_setting != 1)
+ v10 = (flag_layer2_vert_scroll_level_setting != 2) ? v10 >> 5 : v10 >> 1;
+ mirror_current_layer2_ypos = camera_layer2_ypos_relative_to_layer1 + v10;
+ }
}
misc_layer1_xdisp = mirror_current_layer1_xpos - LOBYTE(pt->x);
misc_layer1_ydisp = mirror_current_layer1_ypos - LOBYTE(pt->y);
misc_layer2_xdisp = mirror_current_layer2_xpos - LOBYTE(pt[1].x);
misc_layer2_ydisp = mirror_current_layer2_ypos - LOBYTE(pt[1].y);
- for (uint8 i = 7; (i & 0x80) == 0; --i)
- LOBYTE(get_PointU16(misc_layer1_pos, i)->x) = *((uint8 *)&mirror_current_layer1_xpos + i);
+ if (g_lunar_magic) {
+ LmHook_HandleStandardLevelCameraScrollC();
+ } else {
+ for (uint8 i = 7; (i & 0x80) == 0; --i)
+ LOBYTE(get_PointU16(misc_layer1_pos, i)->x) = *((uint8 *)&mirror_current_layer1_xpos + i);
+ }
}
void HandleStandardLevelCameraScroll_00F7F4(uint16 a) { // 00f7f4
+ uint16 v7;
+
if (flag_layer1_vert_scroll_level_setting) {
uint16 r4w = a;
uint8 v1 = 0;
@@ -6290,8 +6337,13 @@ void HandleStandardLevelCameraScroll_00F7F4(uint16 a) { // 00f7f4
player_swimming_flag && (v4 = player_in_air_flag) != 0 ||
flag_layer1_vert_scroll_level_setting != 1 && (v4 = flag_enable_vert_scroll) == 0) {
flag_enable_vert_scroll = v4;
- if (!v4)
+ if (!v4) {
+ if (g_lunar_magic) {
+ v7 = LmHook_HandleStandardLevelCameraScrollG(r2w, r4w);
+ goto get_out;
+ }
v1 = 4;
+ }
} else if (!flag_scroll_up_to_player) {
if (player_in_air_flag)
return;
@@ -6305,9 +6357,11 @@ void HandleStandardLevelCameraScroll_00F7F4(uint16 a) { // 00f7f4
uint16 t = (v6 - kHandleStandardLevelCameraScroll_DATA_00F6A7[v5]) ^ kHandleStandardLevelCameraScroll_DATA_00F6A7[v5];
if (!sign16(t))
v6 = kHandleStandardLevelCameraScroll_DATA_00F6A7[v5];
- uint16 v7 = mirror_current_layer1_ypos + v6;
+ v7 = mirror_current_layer1_ypos + v6;
if ((int16)(v7 - kHandleStandardLevelCameraScroll_DATA_00F6AD[v5]) < 0)
v7 = kHandleStandardLevelCameraScroll_DATA_00F6AD[v5];
+
+get_out:
mirror_current_layer1_ypos = v7;
if (sign16(r4w - v7)) {
mirror_current_layer1_ypos = r4w;
@@ -6697,3 +6751,5 @@ void Spr089_Layer3Smasher_UpdatePos(uint8 k) { // 00ff61
uint16 v2 = GetSprYPos(k);
mirror_layer3_ypos = shaking_layer1_disp_y + 160 - v2;
}
+
+
diff --git a/src/smw_01.c b/src/smw_01.c
index fc7b5a9..6f18bb7 100644
--- a/src/smw_01.c
+++ b/src/smw_01.c
@@ -243,7 +243,7 @@ void (*kSprStatus08SpriteNormalPtrs[201])(uint8 k) = {
&Spr018_SurfaceJumpingCheepCheep,
&Spr03E_PSwitch,
&Spr01A_ClassicPiranhaPlant,
- &Spr0A0_ActivateBowserBattle,
+ &HandleExtraSprites,
&Spr01C_BulletBill,
&Spr01D_HoppingFlame,
&Spr01E_Lakitu,
@@ -297,7 +297,7 @@ void (*kSprStatus08SpriteNormalPtrs[201])(uint8 k) = {
&Spr04E_LedgeMontyMole,
&Spr04F_JumpingPiranhaPlant,
&Spr04F_JumpingPiranhaPlant,
- &Spr0A0_ActivateBowserBattle,
+ &HandleExtraSprites,
&Spr052_MovingLedgeHole,
&SprStatus08_Return,
&Spr054_ClimbingNetDoor,
@@ -338,9 +338,9 @@ void (*kSprStatus08SpriteNormalPtrs[201])(uint8 k) = {
&Spr077_Feather,
&SprXXX_PowerUps_StarEntry,
&Spr079_VineHead,
- &Spr0A0_ActivateBowserBattle,
+ &HandleExtraSprites,
&Spr07B_GoalTape,
- &Spr0A0_ActivateBowserBattle,
+ &HandleExtraSprites,
&Spr080_Key,
&Spr080_Key,
&Spr080_Key,
@@ -376,47 +376,47 @@ void (*kSprStatus08SpriteNormalPtrs[201])(uint8 k) = {
&Spr09D_BubbleWithSprite,
&Spr09E_BallNChain,
&Spr09E_BallNChain,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
&Spr09E_BallNChain,
&SprXXX_BuoyantPlatformsAndMine_SpikeBallEntry,
&Spr0A5_Sparky,
&Spr0A5_Sparky,
&Spr0A7_IggyBall,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
&SprXXX_NonBossBoos_BooEntry,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
&Spr0B4_NonLineGuideGrinder,
&Spr033_Podoboo,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
- &Spr0A0_ActivateBowserBattle,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
+ &HandleExtraSprites,
};
@@ -2044,39 +2044,35 @@ uint8 HandleNormalSpriteLevelColl_01944D(uint8 k, uint8 j, PointU16 *pt_out) {
pt_out->x = GetSprXPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingX[j];
if ((pt_out->x >> 8) < 2) {
r0 |= (uint8)pt_out->x >> 4;
- uint8 v4 = kLevelDataLayoutTables_EightBitLo_Vertical[r13];
- uint8 v5 = kLevelDataLayoutTables_EightBitHi_Vertical[r13];
- if (misc_scratch7e185e) {
- v4 = kLevelDataLayoutTables_EightBitLo_Vertical[r13 + 14];
- v5 = kLevelDataLayoutTables_EightBitHi_Vertical[r13 + 14];
- }
- return HandleNormalSpriteLevelColl_019523(PAIR16(pt_out->x >> 8, r0) + PAIR16(v5, v4));
+ uint16 pp = GetLevelLayoutPtr_Vertical(r13 + (misc_scratch7e185e ? 14 : 0));
+ return HandleNormalSpriteLevelColl_019523(pp + PAIR16(pt_out->x >> 8, r0));
}
}
LABEL_9:
- blocks_currently_processed_map16_tile_lo = 0;
sprites_distance_to_snap_down_to_nearest_tile = 0;
+ if (HAS_LM_FEATURE(kLmFeature_EnemyCollTweak)) {
+ blocks_currently_processed_map16_tile_lo = lm_word_7E145E & 4 ? 0x25 : 0;
+ } else {
+ blocks_currently_processed_map16_tile_lo = 0;
+ }
return 0;
}
uint16 r12w = GetSprYPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingY[j];
pt_out->y = r12w;
- if (r12w >= 0x1B0)
+ if (r12w >= (g_lunar_magic ? lm_level_height : 0x1B0))
goto LABEL_9;
pt_out->x = GetSprXPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingX[j];
int xx = pt_out->x >> 8;
if ((int8)xx < 0 || (uint8)xx >= misc_screens_in_lvl)
goto LABEL_9;
uint8 r0 = (r12w & 0xF0) | ((uint8)pt_out->x >> 4);
- uint16 v10 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[xx], kLevelDataLayoutTables_EightBitLo_Horizontal[xx]);
- if (misc_scratch7e185e) {
- v10 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[xx + 16], kLevelDataLayoutTables_EightBitLo_Horizontal[xx + 16]);
- }
+ uint16 v10 = GetLevelLayoutPtr_Horizontal(xx + (misc_scratch7e185e ? 16 : 0));
return HandleNormalSpriteLevelColl_019523(PAIR16(r12w >> 8, r0) + v10);
}
uint8 HandleNormalSpriteLevelColl_019523(uint16 r5) { // 019523
blocks_currently_processed_map16_tile_lo = g_ram[r5];
- return ModifyMap16IDForSpecialBlocks(g_ram[r5+0x10000]);
+ return LmHook_ModifyMap16IDForSpecialBlocks(g_ram[r5 + 0x10000]);
}
void SprStatus09_Stunned(uint8 k) { // 01953c
@@ -3695,8 +3691,9 @@ void SubOffscreen_Bank01_01AC33(uint8 k, uint8 r3) { // 01ac33
}
}
} else {
- uint16 y = GetSprYPos(k) + 80;
- if (!sign8((y >> 8) - 2)) {
+ uint16 y = GetSprYPos(k);
+ bool want_erase = g_lunar_magic ? LmHook_WantEraseSprite(k, y) : !sign8(((y + 80) >> 8) - 2);
+ if (want_erase) {
SubOffscreen_Bank01_EraseSprite(k);
} else if ((spr_property_bits167a[k] & 4) == 0) {
uint8 v4 = r3 | counter_global_frames & 1;
@@ -5134,9 +5131,11 @@ void Spr07B_GoalTape_Init(uint8 k) { // 01c075
SetHiLo(&spr_table151c[k], &spr_table00c2[k], GetSprXPos(k) - 8);
spr_table1528[k] = spr_ypos_lo[k];
uint8 v2 = spr_ypos_hi[k];
- spr_table187b[k] = v2;
- v2 &= 1;
- spr_ypos_hi[k] = v2;
+ if (!g_lunar_magic) {
+ spr_table187b[k] = v2;
+ v2 &= 1;
+ spr_ypos_hi[k] = v2;
+ }
spr_table1534[k] = v2;
}
@@ -6798,9 +6797,9 @@ uint8 SprXXX_LineGuided_01D94D(uint16 r0w, uint16 r2w) { // 01d94d
uint8 v3 = r0w & 0xF0 | (r2 >> 4);
uint16 r5;
if ((misc_level_layout_flags & 1) != 0) {
- r5 = PAIR16(kLevelDataLayoutTables_EightBitHi_Vertical[r0w >> 8], kLevelDataLayoutTables_EightBitLo_Vertical[r0w >> 8]) + PAIR16(r2w >> 8, v3);
+ r5 = GetLevelLayoutPtr_Vertical(r0w >> 8) + PAIR16(r2w >> 8, v3);
} else {
- r5 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[r2w >> 8], kLevelDataLayoutTables_EightBitLo_Horizontal[r2w >> 8]) + PAIR16(r0w >> 8, v3);
+ r5 = GetLevelLayoutPtr_Horizontal(r2w >> 8) + PAIR16(r0w >> 8, v3);
}
blocks_currently_processed_map16_tile_lo = g_ram[r5];
return kSprXXX_LineGuided_DATA_018000[v4 & 7] & g_ram[r5 + 0x10000];
diff --git a/src/smw_02.c b/src/smw_02.c
index 3519479..dfa945d 100644
--- a/src/smw_02.c
+++ b/src/smw_02.c
@@ -1628,13 +1628,8 @@ void GetBounceSpriteLevelCollisionMap16ID(uint8 k) { // 029265
return;
uint8 r2 = bounce_spr_xpos_hi[k];
r0 |= r1 >> 4;
- uint8 v3 = kLevelDataLayoutTables_EightBitLo_Vertical[r3];
- uint8 v4 = kLevelDataLayoutTables_EightBitHi_Vertical[r3];
- if (r15) {
- v3 = kLevelDataLayoutTables_EightBitLo_Vertical[r3 + 14];
- v4 = kLevelDataLayoutTables_EightBitHi_Vertical[r3 + 14];
- }
- r5w = PAIR16(r2, r0) + PAIR16(v4, v3);
+ uint16 v34 = GetLevelLayoutPtr_Vertical(r3 + (r15 ? 14 : 0));
+ r5w = PAIR16(r2, r0) + v34;
} else {
uint16 t = PAIR16(bounce_spr_ypos_hi[k], bounce_spr_ypos_lo[k]) - 3;
uint8 r0 = t & ~0xf;
@@ -1648,14 +1643,8 @@ void GetBounceSpriteLevelCollisionMap16ID(uint8 k) { // 029265
return;
uint8 r3 = bounce_spr_xpos_hi[k];
r0 |= r1 >> 4;
- uint8 v6 = v5;
- uint8 v7 = kLevelDataLayoutTables_EightBitLo_Horizontal[v5];
- uint8 v8 = kLevelDataLayoutTables_EightBitHi_Horizontal[v6];
- if (r15) {
- v7 = kLevelDataLayoutTables_EightBitLo_Horizontal[v6 + 16];
- v8 = kLevelDataLayoutTables_EightBitHi_Horizontal[v6 + 16];
- }
- r5w = PAIR16(r2, r0) + PAIR16(v8, v7);
+ uint16 v78 = GetLevelLayoutPtr_Horizontal(v5 + (r15 ? 16 : 0));
+ r5w = PAIR16(r2, r0) + v78;
}
uint8 v9 = sprites_currently_processed_misc_sprite;
blocks_currently_processed_map16_tile_lo = g_ram[r5w];
@@ -1816,17 +1805,12 @@ void HandleCapeLevelColl_029540(uint8 r15) { // 029540
if ((uint8)(posx >> 8) < 2) {
HIBYTE(blocks_xpos) = r2 = (posx >> 8);
r0 |= r1 >> 4;
- uint8 v2 = kLevelDataLayoutTables_EightBitLo_Vertical[r3];
- uint8 v3 = kLevelDataLayoutTables_EightBitHi_Vertical[r3];
- if (r15) {
- v2 = kLevelDataLayoutTables_EightBitLo_Vertical[r3 + 14];
- v3 = kLevelDataLayoutTables_EightBitHi_Vertical[r3 + 14];
- }
- r5 = PAIR16(r2, r0) + PAIR16(v3, v2);
+ uint16 pp = GetLevelLayoutPtr_Vertical(r3 + (r15 ? 14 : 0));
+ r5 = pp + PAIR16(r2, r0);
LABEL_17:
blocks_currently_processed_map16_tile_lo = g_ram[r5];
- uint8 *v8 = &g_ram[r5 + 0x10000];
- if (ModifyMap16IDForSpecialBlocks(*v8)) {
+ uint8 v8 = g_ram[r5 + 0x10000];
+ if (LmHook_ModifyMap16IDForSpecialBlocks(v8)) {
LOBYTE(misc_current_layer_being_processed) = r15;
CheckIfBlockWasHit(blocks_currently_processed_map16_tile_lo, 0);
}
@@ -1842,13 +1826,8 @@ LABEL_17:
if ((uint8)(posx >> 8) < misc_screens_in_lvl) {
HIBYTE(blocks_xpos) = r3 = posx >> 8;
r0 |= r1 >> 4;
- uint8 v6 = kLevelDataLayoutTables_EightBitLo_Horizontal[r3];
- uint8 v7 = kLevelDataLayoutTables_EightBitHi_Horizontal[r3];
- if (r15) {
- v6 = kLevelDataLayoutTables_EightBitLo_Horizontal[r3 + 16];
- v7 = kLevelDataLayoutTables_EightBitHi_Horizontal[r3 + 16];
- }
- r5 = PAIR16(r2, r0) + PAIR16(v7, v6);
+ uint16 pp = GetLevelLayoutPtr_Horizontal(r3 + (r15 ? 16 : 0));
+ r5 = pp + PAIR16(r2, r0);
goto LABEL_17;
}
}
@@ -2910,20 +2889,21 @@ uint8 HandleExtendedSpriteLevelColl_02A611(uint8 k, uint8 r15, ExtCollOut *out)
return 0;
HIBYTE(blocks_xpos) = r2 = (t >> 8);
r0 |= r1 >> 4;
- uint8 v4 = kLevelDataLayoutTables_EightBitLo_Vertical[r3];
- uint8 v5 = kLevelDataLayoutTables_EightBitHi_Vertical[r3];
- if (r15) {
- v4 = kLevelDataLayoutTables_EightBitLo_Vertical[r3 + 14];
- v5 = kLevelDataLayoutTables_EightBitHi_Vertical[r3 + 14];
- }
- r5 = PAIR16(r2, r0) + PAIR16(v5, v4);
+ uint16 pp = GetLevelLayoutPtr_Vertical(r3 + (r15 ? 14 : 0));
+ r5 = pp + PAIR16(r2, r0);
} else {
uint16 t = PAIR16(ext_spr_ypos_hi[k], ext_spr_ypos_lo[k]) + 8;
blocks_ypos = t;
- r0 = t & 0xf0;
+ t &= 0xfff0;
+ r0 = t;
r2 = t >> 8;
- if ((uint8)(r0 - mirror_current_layer1_ypos) >= 0xF0)
- return 0;
+ if (g_lunar_magic) {
+ if (t >= lm_level_height)
+ return 0;
+ } else {
+ if ((uint8)(r0 - mirror_current_layer1_ypos) >= 0xF0)
+ return 0;
+ }
uint16 xpos = PAIR16(ext_spr_xpos_hi[k], ext_spr_xpos_lo[k]) + 4;
LOBYTE(blocks_xpos) = r1 = xpos;
if ((xpos >> 8) >= misc_screens_in_lvl)
@@ -2931,17 +2911,12 @@ uint8 HandleExtendedSpriteLevelColl_02A611(uint8 k, uint8 r15, ExtCollOut *out)
r3 = (xpos >> 8);
HIBYTE(blocks_xpos) = (xpos >> 8);
r0 |= r1 >> 4;
- uint8 v10 = kLevelDataLayoutTables_EightBitLo_Horizontal[r3];
- uint8 v11 = kLevelDataLayoutTables_EightBitHi_Horizontal[r3];
- if (r15) {
- v10 = kLevelDataLayoutTables_EightBitLo_Horizontal[r3 + 16];
- v11 = kLevelDataLayoutTables_EightBitHi_Horizontal[r3 + 16];
- }
- r5 = PAIR16(r2, r0) + PAIR16(v11, v10);
+ uint16 pp = GetLevelLayoutPtr_Horizontal(r3 + (r15 ? 16 : 0));
+ r5 = pp + PAIR16(r2, r0);
}
k = spr_current_slotid;
blocks_currently_processed_map16_tile_lo = g_ram[r5];
- if (!ModifyMap16IDForSpecialBlocks(g_ram[r5 + 0x10000]))
+ if (!LmHook_ModifyMap16IDForSpecialBlocks(g_ram[r5 + 0x10000]))
return 0;
if (blocks_currently_processed_map16_tile_lo < 0x11)
return (blocks_ypos & 0xF) < 6;
@@ -2984,7 +2959,7 @@ void ParseLevelSpriteList() { // 02a7fc
void ParseLevelSpriteList_Entry2() { // 02a802
int8 v0;
- uint8 r0;
+ uint8 r0, r1;
if (misc_level_layout_flags & 1) {
uint16 t = kParseLevelSpriteList_DATA_02A7F6[camera_layer1_scrolling_direction] + (uint8)mirror_current_layer1_ypos;
r0 = t & 0xF0;
@@ -2994,131 +2969,136 @@ void ParseLevelSpriteList_Entry2() { // 02a802
r0 = t & 0xF0;
v0 = HIBYTE(mirror_current_layer1_xpos) + (t >> 8);
}
- int8 v1 = kParseLevelSpriteList_DATA_02A7F9[camera_layer1_scrolling_direction] + v0;
- if (v1 >= 0) {
- uint8 r1 = v1;
- ParseLevelSpriteList_LoadSpriteLoopStrt(0, 1, r0 | r1 << 8);
+ r1 = kParseLevelSpriteList_DATA_02A7F9[camera_layer1_scrolling_direction] + v0;
+
+ if (g_lunar_magic) {
+ LmHook_BE8A(r0 | r1 << 8);
+ } else {
+ if ((int8)r1 >= 0)
+ ParseLevelSpriteList_LoadSpriteLoopStrt(0, 1, (PointU16) { .x = r0 | r1 << 8, .y = 0 });
}
}
-void ParseLevelSpriteList_LoadSpriteLoopStrt(uint8 k, uint8 j, uint16 r0w) { // 02a82e
+bool LoadOneSprite(const uint8 *p, uint8 k, PointU16 pt) {
+ ++sprites_load_status[k];
+ uint8 v8 = p[2];
+ uint8 v9;
+ uint8 r5 = v8;
+ if (v8 >= 0xE7) {
+ if (!*(uint16 *)l1_l2_scroll_spr_spriteid) {
+ l1_l2_scroll_spr_spriteid[0] = r5 + 25;
+ l1_l2_scroll_spr_scroll_type_index[0] = p[0] >> 2;
+ InitializeScrollSprites();
+ }
+ return false;
+ }
+ if (v8 == 0xDE) {
+ Spr0DE_Load5Eeries(k, pt, k, p);
+ return false;
+ }
+ if (v8 == 0xE0) {
+ Spr0E0_Load3Platforms(pt, k, p);
+ return false;
+ }
+ if (v8 < 0xCB) {
+ if (v8 >= 0xC9) {
+ SprXXX_LoadShooter(k, v8, pt, p);
+ return false;
+ }
+ v9 = 1;
+ } else {
+ if (v8 < 0xDA) {
+ gen_spr_spriteid = v8 + 54;
+ sprites_load_status[k] = 0;
+ return false;
+ }
+ if (v8 >= 0xE1) {
+ Spr0E1_LoadBooCeiling(k, v8, pt, k, p);
+ return false;
+ }
+ v9 = 9;
+ }
+ uint8 r4 = v9;
+ uint8 v10 = kParseLevelSpriteList_SpriteSlotMax[sprites_sprite_memory_setting];
+ uint8 r6 = kParseLevelSpriteList_SpriteSlotStart[sprites_sprite_memory_setting];
+ if (r5 == kParseLevelSpriteList_ReservedSprite1[sprites_sprite_memory_setting]) {
+ v10 = kParseLevelSpriteList_SpriteSlotMax1[sprites_sprite_memory_setting];
+ r6 = kParseLevelSpriteList_SpriteSlotStart1[sprites_sprite_memory_setting];
+ }
+ if (r5 == kParseLevelSpriteList_ReservedSprite2[sprites_sprite_memory_setting] && (r5 != 100 || (pt.x & 0x10) != 0)) {
+ v10 = kParseLevelSpriteList_SpriteSlotMax2[sprites_sprite_memory_setting];
+ r6 = -1;
+ }
+ uint8 r15 = v10;
+ while (spr_current_status[v10]) {
+ if (--v10 == r6) {
+ if (r5 != 123) {
+ LABEL_38:
+ sprites_load_status[k] = 0;
+ return true;
+ }
+ v10 = r15;
+ while ((spr_property_bits167a[v10] & 2) != 0) {
+ if (--v10 == r6)
+ goto LABEL_38;
+ }
+ break;
+ }
+ }
+ if (misc_level_layout_flags & 1) {
+ SetSprXYPos(v10, *p & 0xF0 | (*p & 0xD) << 8, pt.x);
+ } else {
+ if (g_lunar_magic)
+ SetSprXYPos(v10, pt.x, pt.y + (*p & 0xF0 | (*p & 0x1) << 8));
+ else
+ SetSprXYPos(v10, pt.x, *p & 0xF0 | (*p & 0xD) << 8);
+ }
+ spr_current_status[v10] = r4;
+ uint8 v15 = p[2];
+ if (r4 >= 9)
+ v15 += 42;
+ if ((ow_level_tile_settings[73] & 0x80) != 0) {
+ if (v15 == 4)
+ v15 = 7;
+ if (v15 == 5)
+ v15 = 6;
+ }
+ spr_spriteid[v10] = v15;
+ spr_load_status_table_index[v10] = k;
+ if (!timer_silver_pswitch || (kInitializeNormalSpriteRAMTables_Sprite190FVals[spr_spriteid[v10]] & 0x40) != 0) {
+ InitializeNormalSpriteRAMTables(v10);
+ } else {
+ spr_spriteid[v10] = 33;
+ spr_current_status[v10] = 8;
+ InitializeNormalSpriteRAMTables(v10);
+ spr_table15f6[v10] = spr_table15f6[v10] & 0xF1 | 2;
+ }
+ spr_xoffscreen_flag[v10] = 1;
+ spr_decrementing_table1fe2[v10] = 4;
+ if (g_lunar_magic && r5 == 0x7b) {
+ spr_table187b[v10] = lm_var_0054 & 0xd;
+ }
+ return false;
+}
+
+void ParseLevelSpriteList_LoadSpriteLoopStrt(uint8 spr_index, uint8 j, PointU16 pt) { // 02a82e
const uint8 *p = GetSpriteListPtr();
- uint8 r2;
while (1) {
// printf("M: Load sprites offs %d: 0x%x\n", j, r0w);
const uint8 *v2 = &p[j];
if (*v2 == 0xFF)
break;
- r2 = (8 * *v2) & 0x10;
- uint8 v4 = r2 | p[j + 1] & 0xF;
- bool v5 = v4 < (r0w >> 8);
- int8 v6 = v4 - (r0w >> 8);
- if (v5)
- goto LABEL_3;
- if (v6)
- return;
- if ((p[j + 1] & 0xF0) != (uint8)r0w || sprites_load_status[k]) {
-LABEL_3:
- j += 3;
- ++k;
- } else {
- r2 = k;
- ++sprites_load_status[k];
- uint8 v8 = p[j + 2];
- uint8 v9;
- uint8 r5 = v8;
- if (v8 >= 0xE7) {
- if (!*(uint16 *)l1_l2_scroll_spr_spriteid) {
- l1_l2_scroll_spr_spriteid[0] = r5 + 25;
- l1_l2_scroll_spr_scroll_type_index[0] = p[j] >> 2;
- InitializeScrollSprites();
- }
- goto LABEL_3;
+ uint8 v4 = (8 * *v2) & 0x10 | p[j + 1] & 0xF;
+ if (v4 >= (pt.x >> 8)) {
+ if (v4 > (pt.x >> 8))
+ return;
+ if ((p[j + 1] & 0xF0) == (uint8)pt.x && !sprites_load_status[spr_index]) {
+ if (LoadOneSprite(p + j, spr_index, pt))
+ return;
}
- if (v8 == 0xDE) {
- Spr0DE_Load5Eeries(k, r0w, r2, p + j);
- goto LABEL_3;
- }
- if (v8 == 0xE0) {
- Spr0E0_Load3Platforms(r0w, r2, p + j);
- goto LABEL_3;
- }
- if (v8 < 0xCB) {
- if (v8 >= 0xC9) {
- SprXXX_LoadShooter(k, v8, r0w, p + j);
- goto LABEL_3;
- }
- v9 = 1;
- } else {
- if (v8 < 0xDA) {
- gen_spr_spriteid = v8 + 54;
- sprites_load_status[k] = 0;
- goto LABEL_3;
- }
- if (v8 >= 0xE1) {
- Spr0E1_LoadBooCeiling(k, v8, r0w, r2, p + j);
- goto LABEL_3;
- }
- v9 = 9;
- }
- uint8 r4 = v9;
- uint8 v10 = kParseLevelSpriteList_SpriteSlotMax[sprites_sprite_memory_setting];
- uint8 r6 = kParseLevelSpriteList_SpriteSlotStart[sprites_sprite_memory_setting];
- if (r5 == kParseLevelSpriteList_ReservedSprite1[sprites_sprite_memory_setting]) {
- v10 = kParseLevelSpriteList_SpriteSlotMax1[sprites_sprite_memory_setting];
- r6 = kParseLevelSpriteList_SpriteSlotStart1[sprites_sprite_memory_setting];
- }
- if (r5 == kParseLevelSpriteList_ReservedSprite2[sprites_sprite_memory_setting] && (r5 != 100 || (r0w & 0x10) != 0)) {
- v10 = kParseLevelSpriteList_SpriteSlotMax2[sprites_sprite_memory_setting];
- r6 = -1;
- }
- uint8 r15 = v10;
- while (spr_current_status[v10]) {
- if (--v10 == r6) {
- if (r5 != 123) {
-LABEL_38:
- sprites_load_status[r2] = 0;
- return;
- }
- v10 = r15;
- while ((spr_property_bits167a[v10] & 2) != 0) {
- if (--v10 == r6)
- goto LABEL_38;
- }
- break;
- }
- }
- const uint8 *v12 = &p[j];
- if (misc_level_layout_flags & 1) {
- SetSprXYPos(v10, *v12 & 0xF0 | (*v12 & 0xD) << 8, r0w);
- } else {
- SetSprXYPos(v10, r0w, *v12 & 0xF0 | (*v12 & 0xD) << 8);
- }
- spr_current_status[v10] = r4;
- uint8 v15 = p[j + 2];
- if (r4 >= 9)
- v15 += 42;
- if ((ow_level_tile_settings[73] & 0x80) != 0) {
- if (v15 == 4)
- v15 = 7;
- if (v15 == 5)
- v15 = 6;
- }
- spr_spriteid[v10] = v15;
- spr_load_status_table_index[v10] = r2;
- if (!timer_silver_pswitch || (kInitializeNormalSpriteRAMTables_Sprite190FVals[spr_spriteid[v10]] & 0x40) != 0) {
- InitializeNormalSpriteRAMTables(v10);
- } else {
- spr_spriteid[v10] = 33;
- spr_current_status[v10] = 8;
- InitializeNormalSpriteRAMTables(v10);
- spr_table15f6[v10] = spr_table15f6[v10] & 0xF1 | 2;
- }
- spr_xoffscreen_flag[v10] = 1;
- spr_decrementing_table1fe2[v10] = 4;
- j += 3;
- k = r2 + 1;
}
+ j += 3;
+ spr_index++;
}
}
@@ -3140,7 +3120,7 @@ uint8 FindFreeNormalSpriteSlot_02A9E6(uint8 r14) { // 02a9ef
return result;
}
-void Spr0E1_LoadBooCeiling(uint8 k, uint8 a, uint16 r0w, uint8 r2, const uint8 *edata) { // 02aac0
+void Spr0E1_LoadBooCeiling(uint8 k, uint8 a, PointU16 pt, uint8 r2, const uint8 *edata) { // 02aac0
flag_run_cluster_sprites = 1;
switch (a) {
case 0xE4:
@@ -3197,8 +3177,8 @@ void Spr0E1_LoadBooCeiling(uint8 k, uint8 a, uint16 r0w, uint8 r2, const uint8 *
uint8 v18 = *edata;
*(&cluster_spr04_boo_ring1_center_ypos_lo + v11) = v18 & 0xF0;
*(&cluster_spr04_boo_ring1_center_ypos_hi + v11) = v18 & 1;
- *(&cluster_spr04_boo_ring1_center_xpos_lo + v11) = r0w;
- *(&cluster_spr04_boo_ring1_center_xpos_hi + v11) = r0w >> 8;
+ *(&cluster_spr04_boo_ring1_center_xpos_lo + v11) = pt.x;
+ *(&cluster_spr04_boo_ring1_center_xpos_hi + v11) = pt.x >> 8;
*(&cluster_spr04_boo_ring1_offscreen_flag + v11) = 0;
*(&cluster_spr04_boo_ring_unused_ring1_level_list_index + v11) = r2;
}
@@ -3225,7 +3205,7 @@ void Spr0E1_LoadBooCeiling(uint8 k, uint8 a, uint16 r0w, uint8 r2, const uint8 *
}
}
-void SprXXX_LoadShooter(uint8 k, uint8 a, uint16 r0w, const uint8 *edata) { // 02ab78
+void SprXXX_LoadShooter(uint8 k, uint8 a, PointU16 pt, const uint8 *edata) { // 02ab78
uint8 r2 = k;
uint8 r4 = a;
uint8 v3 = 7;
@@ -3244,12 +3224,12 @@ void SprXXX_LoadShooter(uint8 k, uint8 a, uint16 r0w, const uint8 *edata) { //
uint8 v7 = *edata;
shooter_spr_xpos_lo[v3] = v7 & 0xF0;
shooter_spr_xpos_hi[v3] = v7 & 1;
- SetHiLo(&shooter_spr_ypos_hi[v3], &shooter_spr_ypos_lo[v3], r0w);
+ SetHiLo(&shooter_spr_ypos_hi[v3], &shooter_spr_ypos_lo[v3], pt.x);
} else {
uint8 v8 = *edata;
shooter_spr_ypos_lo[v3] = v8 & 0xF0;
shooter_spr_ypos_hi[v3] = v8 & 1;
- SetHiLo(&shooter_spr_xpos_hi[v3], &shooter_spr_xpos_lo[v3], r0w);
+ SetHiLo(&shooter_spr_xpos_hi[v3], &shooter_spr_xpos_lo[v3], pt.x);
}
shooter_spr_unused_level_list_index[v3] = r2;
shooter_spr_shoot_timer[v3] = 16;
@@ -3287,6 +3267,8 @@ void LoadSpritesOnLevelLoad() { // 02ac5c
if (misc_level_layout_flags & 1) {
uint8 v5 = camera_layer1_scrolling_direction;
camera_layer1_scrolling_direction = 1;
+ if (g_lunar_magic)
+ LmHook_LoadSpritesOnLevelLoad();
uint16 old_y = mirror_current_layer1_ypos;
mirror_current_layer1_ypos -= 96;
misc_scratch7e18b6 = 0;
@@ -3300,6 +3282,8 @@ void LoadSpritesOnLevelLoad() { // 02ac5c
} else {
uint8 v6 = camera_layer1_scrolling_direction;
camera_layer1_scrolling_direction = 1;
+ if (g_lunar_magic)
+ LmHook_LoadSpritesOnLevelLoad();
uint16 old_x = mirror_current_layer1_xpos;
mirror_current_layer1_xpos -= 96;
misc_scratch7e18b6 = 0;
@@ -3441,9 +3425,9 @@ LABEL_15:;
}
}
-void Spr0E0_Load3Platforms(uint16 r0w, uint8 r2, const uint8 *edata) { // 02af33
+void Spr0E0_Load3Platforms(PointU16 pt, uint8 r2, const uint8 *edata) { // 02af33
uint8 v3 = *edata;
- uint16 ypos = PAIR16(v3 & 1, v3 & 0xF0);
+ uint16 ypos = pt.y + PAIR16(v3 & 1, v3 & 0xF0);
uint8 r4 = 2;
do {
uint8 j = FindFreeNormalSpriteSlot_HighPriority();
@@ -3453,7 +3437,7 @@ void Spr0E0_Load3Platforms(uint16 r0w, uint8 r2, const uint8 *edata) { // 02af3
spr_current_status[j] = 1;
spr_spriteid[j] = -93;
InitializeNormalSpriteRAMTables(j);
- SetSprXYPos(j, r0w, ypos);
+ SetSprXYPos(j, pt.x, ypos);
uint8 v2 = r4;
spr_table1602[v1] = kSpr0E0_Load3Platforms_InitialAngleLo[r4];
spr_table151c[v1] = kSpr0E0_Load3Platforms_InitialAngleHi[v2];
@@ -3462,9 +3446,9 @@ void Spr0E0_Load3Platforms(uint16 r0w, uint8 r2, const uint8 *edata) { // 02af3
} while ((--r4 & 0x80) == 0);
}
-void Spr0DE_Load5Eeries(uint8 k, uint16 r0w, uint8 r2, const uint8 *edata) { // 02af9d
+void Spr0DE_Load5Eeries(uint8 k, PointU16 pt, uint8 r2, const uint8 *edata) { // 02af9d
uint8 v5 = *edata;
- uint16 ypos = PAIR16(v5 & 1, v5 & 0xF0);
+ uint16 ypos = pt.y + PAIR16(v5 & 1, v5 & 0xF0);
uint8 r4 = 4;
do {
uint8 j = FindFreeNormalSpriteSlot_HighPriority();
@@ -3474,7 +3458,7 @@ void Spr0DE_Load5Eeries(uint8 k, uint16 r0w, uint8 r2, const uint8 *edata) { //
spr_current_status[j] = 8;
spr_spriteid[j] = 57;
InitializeNormalSpriteRAMTables(j);
- SetSprXYPos(j, PAIR16(kSpr0DE_Load5Eeries_xhi[v3], kSpr0DE_Load5Eeries_xlo[v3]) + r0w, ypos);
+ SetSprXYPos(j, PAIR16(kSpr0DE_Load5Eeries_xhi[v3], kSpr0DE_Load5Eeries_xlo[v3]) + pt.x, ypos);
spr_yspeed[j] = kSpr0DE_Load5Eeries_InitialYSpeed[v3];
spr_table00c2[j] = kSpr0DE_Load5Eeries_InitialVerticalDirection[v3];
if (v3 == 4)
@@ -4072,15 +4056,13 @@ void CheckPlayerToNormalSpriteColl_02B9D9(uint8 j) { // 02b9d9
void CheckBerryTileCollisionWithYoshiTongue(CollInfo *ci) { // 02b9fa
uint8 r15 = 0;
uint8 r4 = ci->r1 & 0xF0;
- if (ci->r9 < 2) {
+ uint16 r9r1 = PAIR16(ci->r9, ci->r1);
+ if (r9r1 < (g_lunar_magic ? lm_level_height : 0x200)) {
uint8 r13 = ci->r9;
HIBYTE(yoshi_ypos) = ci->r9;
if (ci->r8 < misc_screens_in_lvl) {
r4 |= ci->r0 >> 4;
- uint16 vv = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[ci->r8], kLevelDataLayoutTables_EightBitLo_Horizontal[ci->r8]);
- if (r15)
- vv = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[ci->r8 + 16], kLevelDataLayoutTables_EightBitLo_Horizontal[ci->r8 + 16]);
-
+ uint16 vv = GetLevelLayoutPtr_Horizontal(ci->r8 + (r15 ? 16 : 0));
uint16 r5 = PAIR16(r13, r4) + vv;
blocks_currently_processed_map16_tile_lo = g_ram[r5];
if (!g_ram[r5 + 0x10000] && blocks_currently_processed_map16_tile_lo >= 0x45 && blocks_currently_processed_map16_tile_lo < 0x48) {
@@ -5370,8 +5352,9 @@ void SubOffscreen_Bank02_02D027(uint8 k, uint8 r3) { // 02d027
return;
}
if (r3 != 4) {
- uint16 ypos = GetSprYPos(k) + 0x50;
- if (!sign8((ypos >> 8) - 2)) {
+ uint16 y = GetSprYPos(k);
+ bool want_erase = g_lunar_magic ? LmHook_WantEraseSprite(k, y) : !sign8(((y + 80) >> 8) - 2);
+ if (want_erase) {
LABEL_10:
SubOffscreen_Bank02_EraseSprite(k);
return;
@@ -5421,8 +5404,9 @@ void Spr035_Yoshi_02D0E6(uint8 k) { // 02d0e6
uint8 r15 = 0;
uint16 t = GetSprYPos(k) + 8;
LOBYTE(yoshi_ypos) = t;
- uint8 r0 = t & 0xF0;
- if (t < 0x200) {
+ t &= 0xfff0;
+ uint8 r0 = t;
+ if (t < (g_lunar_magic ? lm_level_height : 0x200)) {
uint8 r2 = t >> 8;
HIBYTE(yoshi_ypos) = t >> 8;
uint8 v2 = spr_table157c[k];
@@ -5434,10 +5418,8 @@ void Spr035_Yoshi_02D0E6(uint8 k) { // 02d0e6
uint8 r3 = (xpos >> 8);
r0 |= r1 >> 4;
uint8 v6 = (xpos >> 8);
- uint16 v8 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[v6], kLevelDataLayoutTables_EightBitLo_Horizontal[v6]);
- if (r15)
- v8 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[v6 + 16], kLevelDataLayoutTables_EightBitLo_Horizontal[v6 + 16]);
- uint16 r5 = PAIR16(r2, r0) + v8;
+ uint16 pp = GetLevelLayoutPtr_Horizontal(v6 + (r15 ? 16 : 0));
+ uint16 r5 = pp + PAIR16(r2, r0);
uint8 v9 = spr_current_slotid;
blocks_currently_processed_map16_tile_lo = g_ram[r5];
if (!g_ram[0x10000 + r5] && blocks_currently_processed_map16_tile_lo >= 0x45 && blocks_currently_processed_map16_tile_lo < 0x48) {
diff --git a/src/smw_03.c b/src/smw_03.c
index 94efee3..2769615 100644
--- a/src/smw_03.c
+++ b/src/smw_03.c
@@ -2342,7 +2342,7 @@ void Spr0A0_ActivateBowserBattle_Init(uint8 k) { // 03a0f1
InitializeMode7TilemapsAndPalettes(k);
}
-void Spr0A0_ActivateBowserBattle(uint8 k) { // 03a118
+void HandleExtraSprites(uint8 k) { // 03a118
uint8 v1 = spr_spriteid[k];
switch (v1) {
case 0xC8: Spr0C8_LightSwitch(k); break;
@@ -3475,8 +3475,9 @@ void SubOffscreen_Bank03_03B85F(uint8 k, uint8 r3) { // 03b85f
goto LABEL_8;
}
} else {
- uint16 ypos = GetSprYPos(k) + 0x50;
- if (!sign8((ypos >> 8) - 2))
+ uint16 y = GetSprYPos(k);
+ bool want_erase = g_lunar_magic ? LmHook_WantEraseSprite(k, y) : !sign8(((y + 80) >> 8) - 2);
+ if (want_erase)
goto LABEL_8;
if ((spr_property_bits167a[k] & 4) == 0) {
uint8 r1 = r3 | counter_global_frames & 1;
@@ -4415,7 +4416,7 @@ void InitializeMode7TilemapsAndPalettes(uint8 k) { // 03dd7d
*((uint8 *)&palettes_palette_mirror[2] + i) = p0[i];
uint16 *dst = RtlGetVramAddr();
if (v1) {
- const uint8 *pp = GraphicsDecompress(v1);
+ const uint8 *pp = LmHook_GraphicsDecompress(v1);
uint8 r3 = 0x80;
do {
pp = InitializeMode7TilemapsAndPalettes_BufferTilemap(&dst, pp);
@@ -4584,8 +4585,6 @@ void UpdateMode7SpriteAnimations_03DFAE(uint8 j, uint16 a) { // 03dfae
*(uint16 *)((int8 *)&mirror_m7_xpos + j) = *(uint16 *)((int8 *)&mirror_current_layer1_xpos + j) + kUpdateMode7SpriteAnimations_DATA_03DEBB[j >> 1] - a;
}
-static const uint16 kGlobalPalettes_BowserLightningFlash[11] = { 0x0, 0x2ce7, 0x3d6b, 0x4def, 0x5e73, 0x6ef7, 0x7fff,0x7393, 0, 0x3FF,0x573B };
-
void Spr0A0_ActivateBowserBattle_UpdatePaletteAndLightningAnimation() { // 03dfcc
unsigned int v1;
uint16 v4;
@@ -4619,7 +4618,7 @@ LABEL_7:
--palettes_lightning_flash_color_index;
timer_lightning_frame_duration = 4;
}
- v4 = kGlobalPalettes_BowserLightningFlash[v3];
+ v4 = kGlobalPalettes_OW_Sprites[0x31 + v3];
goto LABEL_10;
}
}
diff --git a/src/smw_04.c b/src/smw_04.c
index 362a617..7ae349d 100644
--- a/src/smw_04.c
+++ b/src/smw_04.c
@@ -50,97 +50,125 @@ void (*kProcessOverworldSprites_OverworldSpritePtrs[11])(uint8 k) = {
&OWSpr0A_Boo,
};
+#if 0
+static const uint16 kOwStarPipeWarp_SrcX_048431[27] = { 0x11, 0xa, 0x9, 0xb, 0x12, 0xa, 0x7, 0x20a, 0x203, 0x410, 0x412, 0x41c, 0x414, 0x612, 0x200, 0x612, 0x10, 0x617, 0x14, 0x61c, 0x14, 0x61c, 0x617, 0x511, 0x511, 0x414, 0x106, };
+static const uint16 kOwStarPipeWarp_SrcY_048467[27] = { 0x7, 0x3, 0x10, 0xe, 0x17, 0x18, 0x12, 0x14, 0xb, 0x3, 0x1, 0x9, 0x9, 0x1d, 0xe, 0x18, 0xf, 0x16, 0x10, 0x18, 0x2, 0x1d, 0x18, 0x13, 0x11, 0x3, 0x7, };
+static const uint16 kOwStarPipeWarp_DstX_04849D[27] = { 0x4a8, 0x438, 0x908, 0x928, 0x9c8, 0x948, 0xd28, 0x118, 0xa8, 0x98, 0xb8, 0x128, 0xa8, 0x78, 0xd28, 0x408, 0xd78, 0x108, 0xdc8, 0x148, 0xdc8, 0x948, 0xb18, 0xd78, 0x268, 0xdc8, 0xd28, };
+static const uint16 kOwStarPipeWarp_DstY_0484D3[27] = { 0x148, 0xb8, 0x38, 0x18, 0x98, 0x98, 0x1d8, 0x78, 0x38, 0x108, 0xe8, 0x178, 0x188, 0x128, 0x188, 0xe8, 0x168, 0xf8, 0x188, 0x108, 0x1d8, 0x38, 0x138, 0x188, 0x78, 0x1d8, 0x1d8, };
-static const uint16 kOwTileAnimations_WaterTileNumbers[3] = { 0xb480, 0xb498, 0xb4b0, };
-static const uint16 kOwTileAnimations_TileNumbers[64] = { 0xb300, 0xb318, 0xb330, 0xb348, 0xb360, 0xb378, 0xb390, 0xb3a8, 0xb3c0, 0xb3d8, 0xb3f0, 0xb408, 0xb420, 0xb438, 0xb450, 0xb468, 0xb480, 0xb498, 0xb4b0, 0xb4c8, 0xb4e0, 0xb4f8, 0xb510, 0xb528, 0xb540, 0xb558, 0xb570, 0xb588, 0xb5a0, 0xb5b8, 0xb5d0, 0xb5e8, 0xb600, 0xb618, 0xb630, 0xb648, 0xb660, 0xb678, 0xb690, 0xb6a8, 0xb6c0, 0xb6d8, 0xb6f0, 0xb708, 0xb720, 0xb738, 0xb750, 0xb768, 0xb780, 0xb798, 0xb7b0, 0xb7c8, 0xb7e0, 0xb7f8, 0xb810, 0xb828, 0xb840, 0xb858, 0xb870, 0xb888, 0xb8a0, 0xb8b8, 0xb8d0, 0xb8e8, };
-static const uint16 kGameMode0E_ShowOverworld_DATA_048211[8] = { 0x0, 0x2, 0xfffe, 0x2, 0x0, 0x2, 0xfffe, 0x2, };
-static const uint16 kGameMode0E_ShowOverworld_DATA_048221[8] = { 0x0, 0x111, 0xffef, 0x111, 0x0, 0x132, 0xffd7, 0x132, };
-static const uint8 kGameMode0E_ShowOverworld_DATA_048231[16] = { 0xf, 0xf, 0x7, 0x7, 0x7, 0x3, 0x3, 0x3, 0x1, 0x1, 0x3, 0x3, 0x3, 0x7, 0x7, 0x7, };
-static const uint16 kHandleOverworldStarPipeWarp_DATA_048431[27] = { 0x11, 0xa, 0x9, 0xb, 0x12, 0xa, 0x7, 0x20a, 0x203, 0x410, 0x412, 0x41c, 0x414, 0x612, 0x200, 0x612, 0x10, 0x617, 0x14, 0x61c, 0x14, 0x61c, 0x617, 0x511, 0x511, 0x414, 0x106, };
-static const uint16 kHandleOverworldStarPipeWarp_DATA_048467[27] = { 0x7, 0x3, 0x10, 0xe, 0x17, 0x18, 0x12, 0x14, 0xb, 0x3, 0x1, 0x9, 0x9, 0x1d, 0xe, 0x18, 0xf, 0x16, 0x10, 0x18, 0x2, 0x1d, 0x18, 0x13, 0x11, 0x3, 0x7, };
-static const uint16 kHandleOverworldStarPipeWarp_DATA_04849D[27] = { 0x4a8, 0x438, 0x908, 0x928, 0x9c8, 0x948, 0xd28, 0x118, 0xa8, 0x98, 0xb8, 0x128, 0xa8, 0x78, 0xd28, 0x408, 0xd78, 0x108, 0xdc8, 0x148, 0xdc8, 0x948, 0xb18, 0xd78, 0x268, 0xdc8, 0xd28, };
-static const uint16 kHandleOverworldStarPipeWarp_DATA_0484D3[27] = { 0x148, 0xb8, 0x38, 0x18, 0x98, 0x98, 0x1d8, 0x78, 0x38, 0x108, 0xe8, 0x178, 0x188, 0x128, 0x188, 0xe8, 0x168, 0xf8, 0x188, 0x108, 0x1d8, 0x38, 0x138, 0x188, 0x78, 0x1d8, 0x1d8, };
-static const uint16 kDrawOverworldPlayer_PlayerTilesAndProp[192] = { 0x240e, 0x240f, 0x241e, 0x241f, 0x2420, 0x2421, 0x2430, 0x2431, 0x240e, 0x240f, 0x241e, 0x241f, 0x2420, 0x2421, 0x6431, 0x6430, 0x240a, 0x240b, 0x241a, 0x241b, 0x240c, 0x240d, 0x241c, 0x241d, 0x240a, 0x240b, 0x241a, 0x241b, 0x240c, 0x240d, 0x641d, 0x641c, 0x2408, 0x2409, 0x2418, 0x2419, 0x2406, 0x2407, 0x2416, 0x2417, 0x2408, 0x2409, 0x2418, 0x2419, 0x2406, 0x2407, 0x2416, 0x2417, 0x6409, 0x6408, 0x6419, 0x6418, 0x6407, 0x6406, 0x6417, 0x6416, 0x6409, 0x6408, 0x6419, 0x6418, 0x6407, 0x6406, 0x6417, 0x6416, 0x240e, 0x240f, 0x2438, 0x6438, 0x2420, 0x2421, 0x2439, 0x6439, 0x240e, 0x240f, 0x2438, 0x6438, 0x2420, 0x2421, 0x2439, 0x6439, 0x240a, 0x240b, 0x2438, 0x6438, 0x240c, 0x240d, 0x2439, 0x6439, 0x240a, 0x240b, 0x2438, 0x6438, 0x240c, 0x240d, 0x2439, 0x6439, 0x2408, 0x2409, 0x2438, 0x6438, 0x2406, 0x2407, 0x2439, 0x6439, 0x2408, 0x2409, 0x2438, 0x6438, 0x2406, 0x2407, 0x2439, 0x6439, 0x6409, 0x6408, 0x2438, 0x6438, 0x6407, 0x6406, 0x2439, 0x6439, 0x6409, 0x6408, 0x2438, 0x6438, 0x6407, 0x6406, 0x2439, 0x6439, 0x2424, 0x2425, 0x2434, 0x2435, 0x2424, 0x2425, 0x2434, 0x2435, 0x2424, 0x2425, 0x2434, 0x2435, 0x2424, 0x2425, 0x2434, 0x2435, 0x2424, 0x2425, 0x2438, 0x6438, 0x2424, 0x2425, 0x2438, 0x6438, 0x2424, 0x2425, 0x2438, 0x6438, 0x2424, 0x2425, 0x2438, 0x6438, 0x2446, 0x2447, 0x2456, 0x2457, 0x6447, 0x6446, 0x6457, 0x6456, 0x2446, 0x2447, 0x2456, 0x2457, 0x6447, 0x6446, 0x6457, 0x6456, 0x2446, 0x2447, 0x2456, 0x2457, 0x6447, 0x6446, 0x6457, 0x6456, 0x2446, 0x2447, 0x2456, 0x2457, 0x6447, 0x6446, 0x6457, 0x6456, };
-static const uint8 kDrawOverworldPlayer_StarWarpAnimationOffset[4] = { 0x20, 0x60, 0x0, 0x40, };
-static const uint8 kDrawOverworldPlayer_PlayerRidingYoshiTilesAndProp[384] = { 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0xa, 0x24, 0xb, 0x24, 0x1a, 0x24, 0x1b, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0xa, 0x24, 0xb, 0x24, 0x1a, 0x24, 0x1b, 0x24, 0x64, 0x24, 0x65, 0x24, 0x74, 0x24, 0x75, 0x24, 0x40, 0x22, 0x41, 0x22, 0x50, 0x22, 0x51, 0x22, 0x64, 0x24, 0x65, 0x24, 0x74, 0x24, 0x75, 0x24, 0x42, 0x22, 0x43, 0x24, 0x52, 0x24, 0x53, 0x24, 0x65, 0x64, 0x64, 0x64, 0x75, 0x64, 0x74, 0x64, 0x41, 0x62, 0x40, 0x62, 0x51, 0x62, 0x50, 0x62, 0x65, 0x64, 0x64, 0x64, 0x75, 0x64, 0x74, 0x64, 0x43, 0x62, 0x42, 0x62, 0x53, 0x62, 0x52, 0x62, 0x38, 0x24, 0x38, 0x64, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0xff, 0xff, 0xff, 0xff, 0x39, 0x24, 0x39, 0x64, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0xff, 0xff, 0xff, 0xff, 0x38, 0x24, 0x38, 0x64, 0x2f, 0x62, 0x2e, 0x62, 0xa, 0x24, 0xb, 0x24, 0x1a, 0x24, 0x1b, 0x24, 0x39, 0x24, 0x39, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0xa, 0x24, 0xb, 0x24, 0x1a, 0x24, 0x1b, 0x24, 0x38, 0x24, 0x38, 0x64, 0x64, 0x24, 0x65, 0x24, 0x74, 0x24, 0x75, 0x24, 0x40, 0x22, 0x41, 0x22, 0x39, 0x24, 0x39, 0x64, 0x64, 0x24, 0x65, 0x24, 0x74, 0x24, 0x75, 0x24, 0x42, 0x22, 0x42, 0x22, 0x38, 0x24, 0x38, 0x64, 0x65, 0x64, 0x64, 0x64, 0x75, 0x64, 0x74, 0x64, 0x41, 0x62, 0x40, 0x62, 0x39, 0x24, 0x39, 0x64, 0x65, 0x64, 0x64, 0x64, 0x75, 0x64, 0x74, 0x64, 0x43, 0x62, 0x42, 0x62, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x24, 0x24, 0x25, 0x24, 0x34, 0x24, 0x35, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x24, 0x24, 0x25, 0x24, 0x34, 0x24, 0x35, 0x24, 0x38, 0x24, 0x38, 0x64, 0x2f, 0x62, 0x2e, 0x62, 0x24, 0x24, 0x25, 0x24, 0x34, 0x24, 0x35, 0x24, 0x39, 0x24, 0x39, 0x64, 0x2e, 0x22, 0x2f, 0x22, 0x24, 0x24, 0x25, 0x24, 0x34, 0x24, 0x35, 0x24, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, };
-static const uint8 kDrawOverworldPlayer_PlayerAndYoshiXDisp[192] = { 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x7, 0xf, 0x7, 0xf, 0x0, 0x8, 0x0, 0x8, 0x7, 0xf, 0x7, 0xf, 0x0, 0x8, 0x0, 0x8, 0xf9, 0x1, 0xf9, 0x1, 0x0, 0x8, 0x0, 0x8, 0xf9, 0x1, 0xf9, 0x1, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x7, 0xf, 0x7, 0xf, 0x0, 0x8, 0x0, 0x8, 0x7, 0xf, 0x7, 0xf, 0x0, 0x8, 0x0, 0x8, 0xf9, 0x1, 0xf9, 0x1, 0x0, 0x8, 0x0, 0x8, 0xf9, 0x1, 0xf9, 0x1, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, };
-static const uint8 kDrawOverworldPlayer_PlayerAndYoshiYDisp[192] = { 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfa, 0xfa, 0x2, 0x2, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0x8, 0x8, 0xf8, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0xf9, 0xf9, 0x1, 0x1, 0xfc, 0xfc, 0x4, 0x4, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfc, 0xfc, 0x4, 0x4, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfa, 0xfa, 0x2, 0x2, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0xf8, 0xf8, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0xf9, 0xf9, 0x1, 0x1, 0x8, 0x8, 0xfc, 0xfc, 0x4, 0x4, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfc, 0xfc, 0x4, 0x4, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0xf8, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0xf8, 0xf8, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0xf8, 0xf8, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0xf8, 0xf8, 0x0, 0x0, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfa, 0xfa, 0x2, 0x2, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfa, 0xfa, 0x2, 0x2, 0x0, 0x0, 0x8, 0x8, };
-static const uint16 kDrawOverworldPlayer_YoshiPalette[4] = { 0x0, 0x200, 0x400, 0x600, };
-static const uint16 kGameMode0C_LoadOverworld_DATA_048D74[11] = { 0xb, 0x13, 0x1a, 0x1b, 0x1f, 0x20, 0x31, 0x32, 0x34, 0x35, 0x40, };
-static const uint8 kGameMode0C_LoadOverworld_DATA_048D8A[7] = { 0x2, 0x3, 0x4, 0x6, 0x7, 0x9, 0x5, };
-static const uint16 kGameMode0C_LoadOverworld_KoopaKidTeleportXPos[3] = { 0x128, 0x0, 0x188, };
-static const uint16 kGameMode0C_LoadOverworld_KoopaKidTeleportYPos[3] = { 0x1c8, 0x0, 0x1d8, };
-static const uint8 kOverworldProcess02_HandleLevelBeaten_DATA_048F7F[8] = { 0x58, 0x59, 0x5d, 0x63, 0x77, 0x79, 0x7e, 0x80, };
-static const uint16 kSharedOverworldPathTables_DATA_049058[4] = { 0xffff, 0x1, 0xffff, 0x1, };
-static const uint8 kSharedOverworldPathTables_DATA_049060[4] = { 0x5, 0x3, 0x1, 0x0, };
-static const uint16 kSharedOverworldPathTables_DATA_049064[4] = { 0x0, 0x2, 0x4, 0x6, };
-static const uint16 kSharedOverworldPathTables_NoAutoMoveLevels[6] = { 0x28, 0x8, 0x14, 0x36, 0x3f, 0x45, };
-static const uint8 kSharedOverworldPathTables_HardCodedOWPaths_LevelNums[10] = { 0x9, 0x15, 0x23, 0x1b, 0x43, 0x44, 0x24, 0xff, 0x30, 0x31, };
-static const uint16 kSharedOverworldPathTables_DATA_049082[1] = { 0x178, };
-static const uint16 kSharedOverworldPathTables_DATA_049084[1] = { 0x128, };
-static const uint8 kSharedOverworldPathTables_HardCodedOWPaths_Layer1Tiles[68] = { 0x10, 0x10, 0x1e, 0x19, 0x16, 0x66, 0x16, 0x19, 0x1e, 0x10, 0x10, 0x66, 0x4, 0x4, 0x4, 0x58, 0x4, 0x4, 0x4, 0x66, 0x4, 0x4, 0x4, 0x4, 0x4, 0x6a, 0x4, 0x4, 0x4, 0x4, 0x4, 0x66, 0x1e, 0x19, 0x6, 0x9, 0xf, 0x20, 0x1a, 0x21, 0x1a, 0x14, 0x19, 0x18, 0x1f, 0x17, 0x82, 0x17, 0x1f, 0x18, 0x19, 0x14, 0x1a, 0x21, 0x1a, 0x20, 0xf, 0x9, 0x6, 0x19, 0x1e, 0x66, 0x4, 0x4, 0x58, 0x4, 0x4, 0x5f, };
-static const uint8 kSharedOverworldPathTables_HardCodedOWPaths_MovementDirection[68] = { 0x2, 0x2, 0x2, 0x2, 0x6, 0x6, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x2, 0x2, 0x6, 0x6, 0x0, 0x0, 0x0, 0x4, 0x0, 0x4, 0x4, 0x0, 0x4, 0x0, 0x4, 0x6, 0x2, 0x6, 0x2, 0x6, 0x6, 0x2, 0x6, 0x2, 0x2, 0x2, 0x4, 0x4, 0x0, 0x0, 0x6, 0x6, 0x6, 0x4, 0x4, 0x4, };
-static const uint8 kSharedOverworldPathTables_HardCodedOWPaths_Layer1AndMovementTableIndex[10] = { 0x0, 0x6, 0xc, 0x10, 0x14, 0x1a, 0x20, 0x2f, 0x3e, 0x41, };
-static const uint8 kOverworldProcess04_PlayerIsMoving_OWPlayerPathSpeedOffset[2] = { 0xd, 0x8, };
-static const uint16 kOverworldProcess04_PlayerIsMoving_MaxOverworlCameraPosition[2] = { 0xffef, 0xffd7, };
-static const uint16 kOverworldProcess04_PlayerIsMoving_MaxOverworlCameraPosition_RightAndBottom[2] = { 0x111, 0x131, };
-static const uint16 kBitTable_Bank04[4] = { 0x8, 0x4, 0x2, 0x1, };
-static const uint16 kOverworldProcess04_PlayerIsMoving_DATA_049426[5] = { 0x4344, 0x4645, 0x4847, 0x4025, 0x4d42, };
-static const uint16 kOverworldProcess04_PlayerIsMoving_DATA_049430[15] = { 0xc, 0xe, 0x610, 0x12, 0x418, 0x21a, 0x620, 0x642, 0x44e, 0x250, 0x658, 0x5a, 0x670, 0x90, 0x6a0, };
-static const uint8 kOverworldProcess04_PlayerIsMoving_DATA_04944E[15] = { 0x1, 0x1, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, };
-static const uint8 kHandleOverworldPathExits_DATA_0499F0[28] = { 0x0, 0x4, 0x0, 0x9, 0x14, 0x2, 0x15, 0x5, 0x14, 0x5, 0x9, 0xd, 0x15, 0xe, 0x9, 0x1e, 0x15, 0x8, 0xa, 0x1c, 0x1e, 0x0, 0x10, 0x19, 0x1f, 0x8, 0x10, 0x1c, };
-static const uint16 kHandleOverworldPathExits_DATA_049A0C[12] = { 0xffef, 0xffd8, 0xffef, 0x80, 0xffef, 0x128, 0xf0, 0xffd8, 0xf0, 0x80, 0xf0, 0x128, };
+static const uint16 kOwLevelsForcedMusicChange_048D74[11] = { 0xb, 0x13, 0x1a, 0x1b, 0x1f, 0x20, 0x31, 0x32, 0x34, 0x35, 0x40, };
+static const uint8 kOwSubmapMusic_048D8A[7] = { 0x2, 0x3, 0x4, 0x6, 0x7, 0x9, 0x5, };
+
+static const uint16 kOw_KoopaKidTeleportXYPos_048E49[6] = { 0x128, 0x0, 0x188, 0x1c8, 0x0, 0x1d8, };
+static const uint8 kOwTriggerSaveTiles_048F7F[8] = { 0x58, 0x59, 0x5d, 0x63, 0x77, 0x79, 0x7e, 0x80, };
+static const uint16 kOwNoAutoMoveLevels_04906C[6] = { 0x28, 0x8, 0x14, 0x36, 0x3f, 0x45, };
+
+static const uint8 kOwHardcodedPathLevel_049078[10] = { 0x9, 0x15, 0x23, 0x1b, 0x43, 0x44, 0x24, 0xff, 0x30, 0x31, };
+static const uint16 kOwHardcodedPathChocolateIsland2_049082[2] = { 0x178, 0x128, };
+static const uint8 kOwHardcodedPathTiles_049086[68] = { 0x10, 0x10, 0x1e, 0x19, 0x16, 0x66, 0x16, 0x19, 0x1e, 0x10, 0x10, 0x66, 0x4, 0x4, 0x4, 0x58, 0x4, 0x4, 0x4, 0x66, 0x4, 0x4, 0x4, 0x4, 0x4, 0x6a, 0x4, 0x4, 0x4, 0x4, 0x4, 0x66, 0x1e, 0x19, 0x6, 0x9, 0xf, 0x20, 0x1a, 0x21, 0x1a, 0x14, 0x19, 0x18, 0x1f, 0x17, 0x82, 0x17, 0x1f, 0x18, 0x19, 0x14, 0x1a, 0x21, 0x1a, 0x20, 0xf, 0x9, 0x6, 0x19, 0x1e, 0x66, 0x4, 0x4, 0x58, 0x4, 0x4, 0x5f, };
+static const uint8 kOwHardcodedPathDirs_0490CA[68] = { 0x2, 0x2, 0x2, 0x2, 0x6, 0x6, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x2, 0x2, 0x6, 0x6, 0x0, 0x0, 0x0, 0x4, 0x0, 0x4, 0x4, 0x0, 0x4, 0x0, 0x4, 0x6, 0x2, 0x6, 0x2, 0x6, 0x6, 0x2, 0x6, 0x2, 0x2, 0x2, 0x4, 0x4, 0x0, 0x0, 0x6, 0x6, 0x6, 0x4, 0x4, 0x4, };
+static const uint8 kOwHardcodedPathStartIndex_04910E[10] = { 0x0, 0x6, 0xc, 0x10, 0x14, 0x1a, 0x20, 0x2f, 0x3e, 0x41, };
+
+static const uint16 kOwExitLevelTiles_049426[5] = { 0x4344, 0x4645, 0x4847, 0x4025, 0x4d42, };
static const uint16 kUpdateLevelName_DATA_049C91[31] = { 0x1cb, 0x0, 0x8, 0xd, 0x17, 0x23, 0x2e, 0x3a, 0x43, 0x4e, 0x59, 0x5f, 0x65, 0x75, 0x7d, 0x83, 0x87, 0x8c, 0x9a, 0xa8, 0xb2, 0xc2, 0xc9, 0xd3, 0xe5, 0xf7, 0xfe, 0x108, 0x113, 0x11a, 0x122, };
static const uint16 kUpdateLevelName_DATA_049CCF[15] = { 0x1cb, 0x12b, 0x131, 0x138, 0x146, 0x14d, 0x154, 0x160, 0x167, 0x16c, 0x175, 0x180, 0x18a, 0x18f, 0x195, };
static const uint16 kUpdateLevelName_DATA_049CED[13] = { 0x1cb, 0x19d, 0x19e, 0x19f, 0x1a0, 0x1a1, 0x1a2, 0x1a8, 0x1ac, 0x1b2, 0x1b7, 0x1c1, 0x1c6, };
-static const uint16 kSharedOverworldPathTables_DATA_049EA7[81] = { 0xf810, 0x10, 0xfc10, 0x10, 0xfc10, 0x10, 0xfc08, 0xf40c, 0x4fc, 0xfc04, 0x10f8, 0x1000, 0x8fc, 0x8fc, 0x10fc, 0x1000, 0x4f8, 0x10fc, 0x1000, 0x810, 0x410, 0x410, 0x408, 0xc0c, 0x404, 0x404, 0x1008, 0xf8fc, 0xf8fc, 0x1004, 0xfcf8, 0x1004, 0xf4f4, 0xf40c, 0x10, 0x1000, 0x1000, 0x10, 0x10, 0x8fc, 0x8fc, 0x1000, 0xfc10, 0xfc10, 0x4fc, 0xfc04, 0x10f8, 0x1000, 0x10fc, 0x410, 0x10, 0x1004, 0x404, 0xf8fc, 0x404, 0x810, 0xf40c, 0x1000, 0x10fc, 0x10, 0x1004, 0xf810, 0x1000, 0x1000, 0x10fc, 0x10, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xfc04, 0x404, 0x404, 0x1000, 0x1000, 0x10, 0x10, 0x10fc, 0x4fc, };
-static const uint16 kSharedOverworldPathTables_DATA_049F49[81] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x100, 0x100, 0x100, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x100, 0x1, 0x100, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x100, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, };
-static const uint8 kSharedOverworldPathTables_DATA_049FEB[81] = { 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x4, 0x4, 0x8, 0x8, 0x8, 0xc, 0xc, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc, 0xc, 0x8, 0x8, 0x8, 0x8, 0xc, 0x8, 0x8, 0x8, 0xc, 0x8, 0xc, 0x14, 0x14, 0x14, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x8, 0 };
-static const uint8 kSharedOverworldPathTables_DATA_04A03C[24] = { 0x7, 0x9, 0xa, 0xd, 0xe, 0x11, 0x17, 0x19, 0x1a, 0x1c, 0x1d, 0x1f, 0x28, 0x29, 0x2d, 0x2e, 0x35, 0x36, 0x37, 0x49, 0x4a, 0x4b, 0x4d, 0x51, };
-static const uint16 kSharedOverworldPathTables_DATA_04A054[24] = { 0xfc08, 0x8fc, 0x8fc, 0x8fc, 0x8fc, 0x4, 0x408, 0x804, 0x804, 0x4, 0x804, 0x4, 0x8fc, 0x0, 0x8fc, 0x8fc, 0x4, 0x4, 0x0, 0xfc08, 0x408, 0x408, 0x8fc, 0xfc08, };
-static const uint16 kSharedOverworldPathTables_DATA_04A084[48] = { 0x4, 0xfff8, 0x8, 0xfffc, 0xfff8, 0x4, 0xfff8, 0x4, 0x8, 0xfffc, 0x4, 0x4, 0x4, 0x8, 0x8, 0x4, 0xfff8, 0xfffc, 0x0, 0x0, 0x8, 0x4, 0x4, 0x4, 0xfff8, 0x4, 0x4, 0x4, 0x8, 0xfffc, 0xfff8, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, 0x4, 0x4, 0xfff8, 0x4, 0x8, 0xfffc, 0xfff8, 0xfff8, 0x4, 0xfffc, 0x8, };
-static const uint8 kSharedOverworldPathTables_DATA_04A0E4[24] = { 0x2, 0x2, 0x2, 0x2, 0x2, 0x0, 0x2, 0x2, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x2, 0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x2, 0x2, };
-static const uint8 kLoadOverworldLayer1AndEvents_DATA_04D678[113] = { 0x0, 0xc0, 0xc0, 0xc0, 0x30, 0xc0, 0xc0, 0x0, 0xc0, 0x20, 0x30, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, 0x40, 0x40, 0x40, 0xd0, 0x40, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x80, 0x20, 0x80, 0x40, 0x40, 0x80, 0x60, 0x90, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc0, 0x40, 0x20, 0x40, 0xc0, 0xe0, 0xc0, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x20, 0x80, 0x80, 0x80, 0x80, 0x30, 0x40, 0xe0, 0x0, 0x40, 0xe0, 0xe0, 0xd0, 0x70, 0xff, 0x40, 0x90, 0x55, 0x80, 0x80, 0x80, 0x80, 0x0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0x0, 0x80, 0xa0, 0x30, 0xaa, 0x60, 0xd0, 0x80, 0x0, 0x55, 0x55, 0x0, 0x0, 0xaa, 0x55, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, };
-static const uint16 kChangingLayer1OverworldTiles_Layer1TileLocation[112] = { 0x0, 0x0, 0x0, 0x469, 0x44b, 0x429, 0x409, 0xd3, 0xe5, 0xa5, 0xd1, 0x85, 0xa9, 0xcb, 0xbd, 0x9d, 0xa5, 0x207, 0x0, 0x227, 0x512, 0x608, 0x4e3, 0x4c8, 0x62a, 0x4ec, 0x60c, 0x61c, 0x64a, 0x0, 0x4e0, 0x3e, 0x130, 0x134, 0x136, 0x13a, 0x0, 0x157, 0x184, 0x13a, 0x0, 0x0, 0x6aa, 0x676, 0x6c8, 0x6ac, 0x676, 0x0, 0x0, 0x6a4, 0x6aa, 0x6c4, 0x0, 0x304, 0x0, 0x0, 0x579, 0x577, 0x559, 0x574, 0x0, 0x554, 0x0, 0x534, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b3, 0x0, 0x0, 0x0, 0x2df, 0x2dc, 0x0, 0x27e, 0x0, 0x0, 0x0, 0x4e0, 0x4e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x534, 0x534, 0x0, 0x0, 0x787, 0x0, 0x1f0, 0x368, 0x365, 0x3b5, 0x0, 0x736, 0x739, 0x73c, 0x71c, 0x719, 0x716, 0x713, 0x711, 0x0, 0x0, 0x0, };
-static const uint16 kOwEventProcess01_DestroyTileAnimation_DATA_04D93D[112] = { 0x0, 0x0, 0x0, 0x9221, 0x1621, 0x9220, 0x1220, 0x4623, 0x8a23, 0x8a22, 0x4223, 0xa22, 0x9222, 0x1623, 0xda22, 0x5a22, 0x8a22, 0xe28, 0x0, 0x8e28, 0x424, 0x1028, 0x8623, 0x1023, 0x9428, 0x9823, 0x1828, 0x5828, 0x1429, 0x0, 0x8023, 0xdc20, 0xc024, 0xc824, 0xcc24, 0xd424, 0x0, 0x4e25, 0x826, 0xd424, 0x0, 0x0, 0x942a, 0xcc29, 0x102b, 0x982a, 0xcc29, 0x0, 0x0, 0x882a, 0x942a, 0x82b, 0x0, 0x82c, 0x0, 0x0, 0xd225, 0xce25, 0x5225, 0xc825, 0x0, 0x4825, 0x0, 0xc824, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc62e, 0x0, 0x0, 0x0, 0x5e2b, 0x582b, 0x0, 0xdc29, 0x0, 0x0, 0x0, 0x8023, 0x8023, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc824, 0xc824, 0x0, 0x0, 0xe2e, 0x0, 0xc027, 0x902d, 0x8a2d, 0xca2e, 0x0, 0xcc2c, 0xd22c, 0xd82c, 0x582c, 0x522c, 0x4c2c, 0x462c, 0x422c, 0x0, 0x0, 0x0, };
-static const uint8 kChangingLayer1OverworldTiles_TilesThatChange[22] = { 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x59, 0x53, 0x52, 0x83, 0x4d, 0x57, 0x5a, 0x76, 0x78, 0x7a, 0x7b, 0x7d, 0x7f, 0x54, };
-static const uint8 kChangingLayer1OverworldTiles_TilesToBecome[22] = { 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x58, 0x43, 0x44, 0x45, 0x25, 0x5e, 0x5f, 0x77, 0x79, 0x63, 0x7c, 0x7e, 0x80, 0x23, };
-static const uint8 kInitializeOverworldTilemaps_PARAMS_04DAB3[7] = { 0x1, 0x18, 0x0, 0x40, 0x7f, 0x0, 0x20, };
-static const uint16 kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB08[2] = { 0xf900, 0x700, };
-static const uint8 kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB0C[4] = { 0x0, 0x0, 0x0, 0x70, };
-static const uint16 kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB10[2] = { 0xfac0, 0x540, };
-static const uint8 kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB14[4] = { 0x0, 0x0, 0x0, 0x54, };
-static const uint8 kSubmapSwitchProcess07_EndSubmapSwitch_DATA_04DBC8[7] = { 0x2, 0x3, 0x4, 0x6, 0x7, 0x9, 0x5, };
-static const uint8 kLoadOverworldLayer1AndEvents_DATA_04DC02[7] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, };
-static const uint16 kLayer2EventData_Ptrs[121] = { 0x0, 0x0, 0xd, 0xd, 0x10, 0x15, 0x18, 0x1a, 0x20, 0x23, 0x26, 0x29, 0x2c, 0x35, 0x39, 0x3a, 0x42, 0x46, 0x4a, 0x4c, 0x4d, 0x4e, 0x52, 0x59, 0x5d, 0x60, 0x67, 0x6a, 0x6c, 0x6f, 0x72, 0x75, 0x77, 0x77, 0x83, 0x83, 0x84, 0x8e, 0x90, 0x92, 0x98, 0x98, 0x98, 0xa0, 0xa5, 0xac, 0xb2, 0xbd, 0xc2, 0xc5, 0xcc, 0xd3, 0xd7, 0xe1, 0xe2, 0xe2, 0xe2, 0xe5, 0xe7, 0xe8, 0xed, 0xee, 0xf1, 0xf5, 0xfa, 0xfd, 0x100, 0x100, 0x100, 0x100, 0x100, 0x102, 0x108, 0x10f, 0x112, 0x114, 0x116, 0x117, 0x11e, 0x12b, 0x12b, 0x12b, 0x12b, 0x12f, 0x12f, 0x12f, 0x133, 0x133, 0x133, 0x137, 0x137, 0x137, 0x140, 0x140, 0x146, 0x146, 0x146, 0x147, 0x152, 0x156, 0x15c, 0x15c, 0x15f, 0x162, 0x165, 0x168, 0x16b, 0x16e, 0x171, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, };
-static const uint8 kBitTable_DATA_04E44B[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, };
-static const uint16 kOwEventProcess01_DestroyTileAnimation_DATA_04E587[16] = { 0x5220, 0xda22, 0x5828, 0xc024, 0x9424, 0x4223, 0x9428, 0x982a, 0xe25, 0x5225, 0xc425, 0xde2a, 0x982a, 0x4428, 0x502c, 0xc2c, };
-static const uint8 kCheckIfDestroyTileEventIsActive_DATA_04E5A7[5] = { 0x77, 0x79, 0x58, 0x4c, 0xa6, };
-static const uint8 kCheckIfDestroyTileEventIsActive_DATA_04E5AC[5] = { 0x85, 0x86, 0x0, 0x10, 0x0, };
-static const uint8 kCheckIfDestroyTileEventIsActive_DATA_04E5B1[5] = { 0x85, 0x86, 0x81, 0x81, 0x81, };
-static const uint16 kCheckIfDestroyTileEventIsActive_DATA_04E5B6[16] = { 0x419, 0xbd, 0x61c, 0x130, 0x12a, 0xd1, 0x62a, 0x6ac, 0x547, 0x559, 0x572, 0x2bf, 0x2ac, 0x212, 0x318, 0x306, };
-static const uint8 kCheckIfDestroyTileEventIsActive_EventNums[16] = { 0x6, 0xf, 0x1c, 0x21, 0x24, 0x28, 0x29, 0x37, 0x40, 0x41, 0x43, 0x4a, 0x4d, 0x2, 0x61, 0x35, };
-static const uint16 kOwEventProcess00_CheckIfEventShouldRun_DATA_04E5E6[4] = { 0x5958, 0x635d, 0x7977, 0x807e, };
-static const uint8 kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles[44] = { 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x14, 0x14, 0x14, 0x14, 0x14, 0x1d, 0x1d, 0x1d, 0x1d, 0x12, 0x12, 0x12, 0x1c, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x34, 0x34, 0x34, 0x47, 0x4e, 0x4e, 0x1, 0xf, 0x24, 0x24, 0x6c, 0xf, 0xf, 0x54, 0x55, 0x57, 0x58, 0x5d, };
-static const uint8 kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileLayer[44] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, };
-static const uint16 kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TilemapLocation[44] = { 0x215, 0x235, 0x245, 0x255, 0x265, 0x275, 0x1114, 0x1094, 0xa9, 0x5a4, 0x524, 0x728, 0x6a4, 0x1a8, 0x1ac, 0x1b0, 0x3c, 0x2900, 0x2880, 0x510, 0x154, 0x1830, 0x18b0, 0x192e, 0x192a, 0x1926, 0x1824, 0x1820, 0x181c, 0x597, 0x2aec, 0x57b, 0x212, 0x3194, 0x32a0, 0x3320, 0x1d16, 0x3114, 0x625, 0x1f0, 0x1f0, 0x304, 0x304, 0x227, };
-static const uint16 kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileNum[44] = { 0x68, 0x24, 0x24, 0x25, 0x0, 0x81, 0x938, 0x928, 0x66, 0x99c, 0x928, 0x9f8, 0x9fc, 0x998, 0x998, 0x928, 0x66, 0x938, 0x928, 0x66, 0x68, 0xa80, 0xa84, 0xa88, 0x998, 0x998, 0x994, 0x998, 0xa8c, 0x66, 0x384, 0x66, 0x79, 0xaa8, 0x938, 0x938, 0x9a0, 0xa30, 0x69, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, };
-static const uint8 kOwEventProcess01_DestroyTileAnimation_DATA_04EB56[44] = { 0xf5, 0x11, 0xf2, 0x15, 0xf5, 0x11, 0xf3, 0x14, 0xf5, 0x11, 0xf3, 0x14, 0xf6, 0x10, 0xf4, 0x13, 0xf7, 0xf, 0xf5, 0x12, 0xf8, 0xe, 0xf7, 0x11, 0xfa, 0xd, 0xf9, 0x10, 0xfc, 0xc, 0xfb, 0xd, 0xff, 0xa, 0xfe, 0xb, 0x1, 0x7, 0x1, 0x7, 0x0, 0x8, 0x0, 0x8, };
-static const uint8 kOwEventProcess01_DestroyTileAnimation_DATA_04EB82[44] = { 0xf8, 0xf8, 0x11, 0x12, 0xf8, 0xf8, 0x10, 0x11, 0xf8, 0xf8, 0x10, 0x11, 0xf9, 0xf9, 0xf, 0x10, 0xfa, 0xfa, 0xe, 0xf, 0xfb, 0xfb, 0xc, 0xd, 0xfc, 0xfc, 0xb, 0xb, 0xfe, 0xfe, 0xa, 0xa, 0x0, 0x0, 0x8, 0x8, 0x1, 0x1, 0x7, 0x7, 0x0, 0x0, 0x8, 0x8, };
-static const uint8 kOwEventProcess01_DestroyTileAnimation_DATA_04EBAE[44] = { 0xf6, 0xb6, 0x76, 0x36, 0xf6, 0xb6, 0x76, 0x36, 0x36, 0x76, 0xb6, 0xf6, 0x36, 0x76, 0xb6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x70, 0xb0, 0xf0, };
-static const uint8 kOwEventProcess01_DestroyTileAnimation_DATA_04EBDA[7] = { 0x22, 0x23, 0x32, 0x33, 0x32, 0x23, 0x22, };
-static const uint8 kOwEventProcess01_DestroyTileAnimation_DATA_04EBE1[10] = { 0x73, 0x73, 0x72, 0x72, 0x5f, 0x5f, 0x28, 0x28, 0x28, 0x28, };
+
+static const OwExits kOwExitSource_049964[] = {
+ {0x0140, 0x0028, 0},
+ {0x0150, 0x0058, 0},
+ {0x0010, 0x0048, 1},
+ {0x0010, 0x0098, 1},
+ {0x00a0, 0x00d8, 0},
+ {0x0140, 0x0058, 2},
+ {0x0090, 0x01e8, 4},
+ {0x0160, 0x00e8, 0},
+ {0x00a0, 0x01c8, 0},
+ {0x0160, 0x0088, 3},
+ {0x0108, 0x0190, 0},
+ {0x01e8, 0x0010, 3},
+ {0x0110, 0x01c8, 0},
+ {0x01f0, 0x0088, 3},
+};
+
+static const OwExits kOwExitDest_0499AA[] = {
+ {0x0000, 0x0048, 1},
+ {0x0000, 0x0098, 1},
+ {0x0150, 0x0028, 0},
+ {0x0160, 0x0058, 0},
+ {0x0150, 0x0058, 2},
+ {0x0090, 0x00d8, 0},
+ {0x0150, 0x00e8, 0},
+ {0x00a0, 0x01e8, 4},
+ {0x0150, 0x0088, 3},
+ {0x00b0, 0x01c8, 0},
+ {0x01e8, 0x0000, 3},
+ {0x0108, 0x01a0, 0},
+ {0x0200, 0x0088, 3},
+ {0x0100, 0x01c8, 0},
+};
+
+static const uint8 kOwExitExtra_0499F0[28] = { 0x0, 0x4, 0x0, 0x9, 0x14, 0x2, 0x15, 0x5, 0x14, 0x5, 0x9, 0xd, 0x15, 0xe, 0x9, 0x1e, 0x15, 0x8, 0xa, 0x1c, 0x1e, 0x0, 0x10, 0x19, 0x1f, 0x8, 0x10, 0x1c, };
+static const uint16 kOwExitLayerPosition_049A0C[12] = { 0xffef, 0xffd8, 0xffef, 0x80, 0xffef, 0x128, 0xf0, 0xffd8, 0xf0, 0x80, 0xf0, 0x128, };
+
+static const uint8 kOwUnknownTableA_From_04A03C[24] = { 0x7, 0x9, 0xa, 0xd, 0xe, 0x11, 0x17, 0x19, 0x1a, 0x1c, 0x1d, 0x1f, 0x28, 0x29, 0x2d, 0x2e, 0x35, 0x36, 0x37, 0x49, 0x4a, 0x4b, 0x4d, 0x51, };
+static const uint16 kOwUnknownTableA_Alpha_04A054[24] = { 0xfc08, 0x8fc, 0x8fc, 0x8fc, 0x8fc, 0x4, 0x408, 0x804, 0x804, 0x4, 0x804, 0x4, 0x8fc, 0x0, 0x8fc, 0x8fc, 0x4, 0x4, 0x0, 0xfc08, 0x408, 0x408, 0x8fc, 0xfc08, };
+static const uint16 kOwUnknownTableA_XY_04A084[48] = { 0x4, 0xfff8, 0x8, 0xfffc, 0xfff8, 0x4, 0xfff8, 0x4, 0x8, 0xfffc, 0x4, 0x4, 0x4, 0x8, 0x8, 0x4, 0xfff8, 0xfffc, 0x0, 0x0, 0x8, 0x4, 0x4, 0x4, 0xfff8, 0x4, 0x4, 0x4, 0x8, 0xfffc, 0xfff8, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, 0x4, 0x4, 0xfff8, 0x4, 0x8, 0xfffc, 0xfff8, 0xfff8, 0x4, 0xfffc, 0x8, };
+static const uint8 kOwUnknownTableA_Direction_04A0E4[24] = { 0x2, 0x2, 0x2, 0x2, 0x2, 0x0, 0x2, 0x2, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x2, 0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x2, 0x2, };
+static const uint8 kOwDirectionAfterBeatingLevel_04D678[113] = { 0x0, 0xc0, 0xc0, 0xc0, 0x30, 0xc0, 0xc0, 0x0, 0xc0, 0x20, 0x30, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, 0x40, 0x40, 0x40, 0xd0, 0x40, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x80, 0x20, 0x80, 0x40, 0x40, 0x80, 0x60, 0x90, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc0, 0x40, 0x20, 0x40, 0xc0, 0xe0, 0xc0, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x20, 0x80, 0x80, 0x80, 0x80, 0x30, 0x40, 0xe0, 0x0, 0x40, 0xe0, 0xe0, 0xd0, 0x70, 0xff, 0x40, 0x90, 0x55, 0x80, 0x80, 0x80, 0x80, 0x0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0x0, 0x80, 0xa0, 0x30, 0xaa, 0x60, 0xd0, 0x80, 0x0, 0x55, 0x55, 0x0, 0x0, 0xaa, 0x55, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, };
+
+static const uint8 kOwSubmapTileset_04DC02[7] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, };
+static const uint16 kLayer2EventData_Ptrs_04E359[121] = { 0x0, 0x0, 0xd, 0xd, 0x10, 0x15, 0x18, 0x1a, 0x20, 0x23, 0x26, 0x29, 0x2c, 0x35, 0x39, 0x3a, 0x42, 0x46, 0x4a, 0x4c, 0x4d, 0x4e, 0x52, 0x59, 0x5d, 0x60, 0x67, 0x6a, 0x6c, 0x6f, 0x72, 0x75, 0x77, 0x77, 0x83, 0x83, 0x84, 0x8e, 0x90, 0x92, 0x98, 0x98, 0x98, 0xa0, 0xa5, 0xac, 0xb2, 0xbd, 0xc2, 0xc5, 0xcc, 0xd3, 0xd7, 0xe1, 0xe2, 0xe2, 0xe2, 0xe5, 0xe7, 0xe8, 0xed, 0xee, 0xf1, 0xf5, 0xfa, 0xfd, 0x100, 0x100, 0x100, 0x100, 0x100, 0x102, 0x108, 0x10f, 0x112, 0x114, 0x116, 0x117, 0x11e, 0x12b, 0x12b, 0x12b, 0x12b, 0x12f, 0x12f, 0x12f, 0x133, 0x133, 0x133, 0x137, 0x137, 0x137, 0x140, 0x140, 0x146, 0x146, 0x146, 0x147, 0x152, 0x156, 0x15c, 0x15c, 0x15f, 0x162, 0x165, 0x168, 0x16b, 0x16e, 0x171, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, };
+
+static const uint8 kOwDestruction_TileToIdx_04E5A7[5] = { 0x77, 0x79, 0x58, 0x4c, 0xa6, };
+static const uint8 kOwDestruction_TopTile_04E5AC[5] = { 0x85, 0x86, 0x0, 0x10, 0x0, };
+static const uint8 kOwDestruction_BottomTile_04E5B1[5] = { 0x85, 0x86, 0x81, 0x81, 0x81, };
+static const uint8 kOwDestruction_TriggerEvent_04E5D6[16] = { 0x6, 0xf, 0x1c, 0x21, 0x24, 0x28, 0x29, 0x37, 0x40, 0x41, 0x43, 0x4a, 0x4d, 0x2, 0x61, 0x35, };
+
+#endif
+
+/////////////////////////////////////////////
+// Not important for the assets file
+
+static const uint8 kOverworldEventProcess01_DestroyTileAnimation_DATA_04ECD3[176] = { 134, 153, 134, 25, 134, 217, 134, 89, 150, 153, 150, 25, 150, 217, 150, 89, 134, 157, 134, 29, 134, 221, 134, 93, 150, 157, 150, 29, 150, 221, 150, 93, 134, 153, 134, 25, 134, 217, 134, 89, 150, 153, 150, 25, 150, 217, 150, 89, 134, 157, 134, 29, 134, 221, 134, 93, 150, 157, 150, 29, 150, 221, 150, 93, 136, 21, 152, 21, 137, 21, 153, 21, 164, 17, 180, 17, 165, 17, 181, 17, 34, 17, 144, 17, 34, 17, 145, 17, 194, 17, 210, 17, 195, 17, 211, 17, 166, 17, 182, 17, 167, 17, 183, 17, 130, 25, 146, 25, 131, 25, 147, 25, 200, 25, 248, 25, 201, 25, 249, 25, 128, 28, 144, 28, 129, 28, 144, 92, 128, 20, 144, 20, 129, 20, 144, 84, 162, 17, 178, 17, 163, 17, 179, 17, 130, 29, 146, 29, 131, 29, 147, 29, 134, 153, 134, 25, 134, 217, 134, 89, 134, 153, 134, 25, 134, 217, 134, 89, 168, 17, 184, 17, 169, 17, 185, 17, };
+
+static const uint16 kOverworldProcess04_PlayerIsMoving_DATA_049430[15] = { 0xc, 0xe, 0x610, 0x12, 0x418, 0x21a, 0x620, 0x642, 0x44e, 0x250, 0x658, 0x5a, 0x670, 0x90, 0x6a0, };
+static const uint8 kOverworldProcess04_PlayerIsMoving_DATA_04944E[15] = { 0x1, 0x1, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, };
+static const uint16 kOw_MaxRangeForScrollWalking_049416[4] = { 0xffef, 0xffd7, 0x111, 0x131, };
+
+static const uint16 kOwTileDistanceMovedAcross_049EA7[81] = { 0xf810, 0x10, 0xfc10, 0x10, 0xfc10, 0x10, 0xfc08, 0xf40c, 0x4fc, 0xfc04, 0x10f8, 0x1000, 0x8fc, 0x8fc, 0x10fc, 0x1000, 0x4f8, 0x10fc, 0x1000, 0x810, 0x410, 0x410, 0x408, 0xc0c, 0x404, 0x404, 0x1008, 0xf8fc, 0xf8fc, 0x1004, 0xfcf8, 0x1004, 0xf4f4, 0xf40c, 0x10, 0x1000, 0x1000, 0x10, 0x10, 0x8fc, 0x8fc, 0x1000, 0xfc10, 0xfc10, 0x4fc, 0xfc04, 0x10f8, 0x1000, 0x10fc, 0x410, 0x10, 0x1004, 0x404, 0xf8fc, 0x404, 0x810, 0xf40c, 0x1000, 0x10fc, 0x10, 0x1004, 0xf810, 0x1000, 0x1000, 0x10fc, 0x10, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xfc04, 0x404, 0x404, 0x1000, 0x1000, 0x10, 0x10, 0x10fc, 0x4fc, };
+static const uint16 kOwTilePathDirection_049F49[81] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x100, 0x100, 0x100, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x100, 0x1, 0x100, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x100, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x100, };
+static const uint8 kOwTilePose_049FEB[81] = { 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x4, 0x4, 0x8, 0x8, 0x8, 0xc, 0xc, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc, 0xc, 0x8, 0x8, 0x8, 0x8, 0xc, 0x8, 0x8, 0x8, 0xc, 0x8, 0xc, 0x14, 0x14, 0x14, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x8, 0 };
+
+static const uint8 kOwStarWarpAnimationOffset[4] = { 0x20, 0x60, 0x0, 0x40, };
+static const uint16 kOwSpriteTilemap[192] = { 0x240e, 0x240f, 0x241e, 0x241f, 0x2420, 0x2421, 0x2430, 0x2431, 0x240e, 0x240f, 0x241e, 0x241f, 0x2420, 0x2421, 0x6431, 0x6430, 0x240a, 0x240b, 0x241a, 0x241b, 0x240c, 0x240d, 0x241c, 0x241d, 0x240a, 0x240b, 0x241a, 0x241b, 0x240c, 0x240d, 0x641d, 0x641c, 0x2408, 0x2409, 0x2418, 0x2419, 0x2406, 0x2407, 0x2416, 0x2417, 0x2408, 0x2409, 0x2418, 0x2419, 0x2406, 0x2407, 0x2416, 0x2417, 0x6409, 0x6408, 0x6419, 0x6418, 0x6407, 0x6406, 0x6417, 0x6416, 0x6409, 0x6408, 0x6419, 0x6418, 0x6407, 0x6406, 0x6417, 0x6416, 0x240e, 0x240f, 0x2438, 0x6438, 0x2420, 0x2421, 0x2439, 0x6439, 0x240e, 0x240f, 0x2438, 0x6438, 0x2420, 0x2421, 0x2439, 0x6439, 0x240a, 0x240b, 0x2438, 0x6438, 0x240c, 0x240d, 0x2439, 0x6439, 0x240a, 0x240b, 0x2438, 0x6438, 0x240c, 0x240d, 0x2439, 0x6439, 0x2408, 0x2409, 0x2438, 0x6438, 0x2406, 0x2407, 0x2439, 0x6439, 0x2408, 0x2409, 0x2438, 0x6438, 0x2406, 0x2407, 0x2439, 0x6439, 0x6409, 0x6408, 0x2438, 0x6438, 0x6407, 0x6406, 0x2439, 0x6439, 0x6409, 0x6408, 0x2438, 0x6438, 0x6407, 0x6406, 0x2439, 0x6439, 0x2424, 0x2425, 0x2434, 0x2435, 0x2424, 0x2425, 0x2434, 0x2435, 0x2424, 0x2425, 0x2434, 0x2435, 0x2424, 0x2425, 0x2434, 0x2435, 0x2424, 0x2425, 0x2438, 0x6438, 0x2424, 0x2425, 0x2438, 0x6438, 0x2424, 0x2425, 0x2438, 0x6438, 0x2424, 0x2425, 0x2438, 0x6438, 0x2446, 0x2447, 0x2456, 0x2457, 0x6447, 0x6446, 0x6457, 0x6456, 0x2446, 0x2447, 0x2456, 0x2457, 0x6447, 0x6446, 0x6457, 0x6456, 0x2446, 0x2447, 0x2456, 0x2457, 0x6447, 0x6446, 0x6457, 0x6456, 0x2446, 0x2447, 0x2456, 0x2457, 0x6447, 0x6446, 0x6457, 0x6456, };
+static const uint8 kOwSpriteTilemapYoshi[384] = { 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0xa, 0x24, 0xb, 0x24, 0x1a, 0x24, 0x1b, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0xa, 0x24, 0xb, 0x24, 0x1a, 0x24, 0x1b, 0x24, 0x64, 0x24, 0x65, 0x24, 0x74, 0x24, 0x75, 0x24, 0x40, 0x22, 0x41, 0x22, 0x50, 0x22, 0x51, 0x22, 0x64, 0x24, 0x65, 0x24, 0x74, 0x24, 0x75, 0x24, 0x42, 0x22, 0x43, 0x24, 0x52, 0x24, 0x53, 0x24, 0x65, 0x64, 0x64, 0x64, 0x75, 0x64, 0x74, 0x64, 0x41, 0x62, 0x40, 0x62, 0x51, 0x62, 0x50, 0x62, 0x65, 0x64, 0x64, 0x64, 0x75, 0x64, 0x74, 0x64, 0x43, 0x62, 0x42, 0x62, 0x53, 0x62, 0x52, 0x62, 0x38, 0x24, 0x38, 0x64, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0xff, 0xff, 0xff, 0xff, 0x39, 0x24, 0x39, 0x64, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0xff, 0xff, 0xff, 0xff, 0x38, 0x24, 0x38, 0x64, 0x2f, 0x62, 0x2e, 0x62, 0xa, 0x24, 0xb, 0x24, 0x1a, 0x24, 0x1b, 0x24, 0x39, 0x24, 0x39, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0xa, 0x24, 0xb, 0x24, 0x1a, 0x24, 0x1b, 0x24, 0x38, 0x24, 0x38, 0x64, 0x64, 0x24, 0x65, 0x24, 0x74, 0x24, 0x75, 0x24, 0x40, 0x22, 0x41, 0x22, 0x39, 0x24, 0x39, 0x64, 0x64, 0x24, 0x65, 0x24, 0x74, 0x24, 0x75, 0x24, 0x42, 0x22, 0x42, 0x22, 0x38, 0x24, 0x38, 0x64, 0x65, 0x64, 0x64, 0x64, 0x75, 0x64, 0x74, 0x64, 0x41, 0x62, 0x40, 0x62, 0x39, 0x24, 0x39, 0x64, 0x65, 0x64, 0x64, 0x64, 0x75, 0x64, 0x74, 0x64, 0x43, 0x62, 0x42, 0x62, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x24, 0x24, 0x25, 0x24, 0x34, 0x24, 0x35, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x24, 0x24, 0x25, 0x24, 0x34, 0x24, 0x35, 0x24, 0x38, 0x24, 0x38, 0x64, 0x2f, 0x62, 0x2e, 0x62, 0x24, 0x24, 0x25, 0x24, 0x34, 0x24, 0x35, 0x24, 0x39, 0x24, 0x39, 0x64, 0x2e, 0x22, 0x2f, 0x22, 0x24, 0x24, 0x25, 0x24, 0x34, 0x24, 0x35, 0x24, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2f, 0x62, 0x2e, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x66, 0x24, 0x67, 0x24, 0x76, 0x24, 0x77, 0x24, 0x2e, 0x22, 0x2f, 0x22, 0x3e, 0x22, 0x3f, 0x22, };
+static const uint8 kOwPlayerAndYoshiXDisp[192] = { 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x7, 0xf, 0x7, 0xf, 0x0, 0x8, 0x0, 0x8, 0x7, 0xf, 0x7, 0xf, 0x0, 0x8, 0x0, 0x8, 0xf9, 0x1, 0xf9, 0x1, 0x0, 0x8, 0x0, 0x8, 0xf9, 0x1, 0xf9, 0x1, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x7, 0xf, 0x7, 0xf, 0x0, 0x8, 0x0, 0x8, 0x7, 0xf, 0x7, 0xf, 0x0, 0x8, 0x0, 0x8, 0xf9, 0x1, 0xf9, 0x1, 0x0, 0x8, 0x0, 0x8, 0xf9, 0x1, 0xf9, 0x1, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, };
+static const uint8 kOwPlayerAndYoshiYDisp[192] = { 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfa, 0xfa, 0x2, 0x2, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0x8, 0x8, 0xf8, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0xf9, 0xf9, 0x1, 0x1, 0xfc, 0xfc, 0x4, 0x4, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfc, 0xfc, 0x4, 0x4, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfa, 0xfa, 0x2, 0x2, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0xf8, 0xf8, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0xf9, 0xf9, 0x1, 0x1, 0x8, 0x8, 0xfc, 0xfc, 0x4, 0x4, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfc, 0xfc, 0x4, 0x4, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0xf8, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0xf8, 0xf8, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0xf8, 0xf8, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0xf8, 0xf8, 0x0, 0x0, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfa, 0xfa, 0x2, 0x2, 0x0, 0x0, 0x8, 0x8, 0xfb, 0xfb, 0x3, 0x3, 0x0, 0x0, 0x8, 0x8, 0xfa, 0xfa, 0x2, 0x2, 0x0, 0x0, 0x8, 0x8, };
+static const uint16 kOwYoshiPalette[4] = { 0x0, 0x200, 0x400, 0x600, };
+
+static const uint8 kOverworldProcess04_PlayerIsMoving_OWPlayerPathSpeedOffset[2] = { 0xd, 0x8, };
+
+static const uint16 kOwOffsetsFreeScrolling_048211[8] = { 0x0, 0x2, 0xfffe, 0x2, 0x0, 0x2, 0xfffe, 0x2, };
+static const uint16 kOwOffsetsFreeScrollMax_048221[8] = { 0x0, 0x111, 0xffef, 0x111, 0x0, 0x132, 0xffd7, 0x132, };
+
+static const uint8 kOwEarthquakeFrameMask_048231[16] = { 0xf, 0xf, 0x7, 0x7, 0x7, 0x3, 0x3, 0x3, 0x1, 0x1, 0x3, 0x3, 0x3, 0x7, 0x7, 0x7, };
+static const uint8 kOwDestroyTileAnimation_X_04EB56[44] = { 0xf5, 0x11, 0xf2, 0x15, 0xf5, 0x11, 0xf3, 0x14, 0xf5, 0x11, 0xf3, 0x14, 0xf6, 0x10, 0xf4, 0x13, 0xf7, 0xf, 0xf5, 0x12, 0xf8, 0xe, 0xf7, 0x11, 0xfa, 0xd, 0xf9, 0x10, 0xfc, 0xc, 0xfb, 0xd, 0xff, 0xa, 0xfe, 0xb, 0x1, 0x7, 0x1, 0x7, 0x0, 0x8, 0x0, 0x8, };
+static const uint8 kOwDestroyTileAnimation_Y_04EB82[44] = { 0xf8, 0xf8, 0x11, 0x12, 0xf8, 0xf8, 0x10, 0x11, 0xf8, 0xf8, 0x10, 0x11, 0xf9, 0xf9, 0xf, 0x10, 0xfa, 0xfa, 0xe, 0xf, 0xfb, 0xfb, 0xc, 0xd, 0xfc, 0xfc, 0xb, 0xb, 0xfe, 0xfe, 0xa, 0xa, 0x0, 0x0, 0x8, 0x8, 0x1, 0x1, 0x7, 0x7, 0x0, 0x0, 0x8, 0x8, };
+static const uint8 kOwDestroyTileAnimation_Flags_04EBAE[44] = { 0xf6, 0xb6, 0x76, 0x36, 0xf6, 0xb6, 0x76, 0x36, 0x36, 0x76, 0xb6, 0xf6, 0x36, 0x76, 0xb6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x70, 0xb0, 0xf0, };
+static const uint8 kOwDestroyTileAnimation_Char_04EBDA[7] = { 0x22, 0x23, 0x32, 0x33, 0x32, 0x23, 0x22, };
+static const uint8 kOwDestroyTileAnimation_Char2_04EBE1[10] = { 0x73, 0x73, 0x72, 0x72, 0x5f, 0x5f, 0x28, 0x28, 0x28, 0x28, };
+
static const uint8 kDrawFlyingSwitchBlocks_XSpeed[8] = { 0x0, 0xd8, 0x28, 0xd0, 0x30, 0xd8, 0x28, 0x0, };
static const uint8 kDrawFlyingSwitchBlocks_YSpeed[8] = { 0xd0, 0xd8, 0xd8, 0x0, 0x0, 0x28, 0x28, 0x30, };
static const uint8 kOwPrompt02_ExpandPromptWindow_DATA_04F411[2] = { 0x4, 0xfc, };
static const uint8 kOwPrompt02_ExpandPromptWindow_DATA_04F413[2] = { 0x68, 0x0, };
-static const uint8 kLifeExchangeText_Mario[14] = { 0x52, 0x49, 0x0, 0x9, 0x16, 0x28, 0xa, 0x28, 0x1b, 0x28, 0x12, 0x28, 0x18, 0x28, };
+static const uint8 kOwLifeExchangeTextTiles[81] = { 82, 73, 0, 9, 22, 40, 10, 40, 27, 40, 18, 40, 24, 40, 82, 82, 0, 9, 21, 40, 30, 40, 18, 40, 16, 40, 18, 40, 82, 11, 0, 5, 38, 40, 0, 40, 0, 40, 82, 20, 0, 5, 38, 40, 0, 40, 0, 40, 82, 15, 0, 3, 252, 56, 252, 56, 82, 47, 0, 3, 252, 56, 252, 56, 81, 201, 0, 3, 133, 41, 133, 105, 81, 210, 0, 3, 133, 41, 133, 105, 255, };
static const uint16 kOwPrompt03_OverworldLifeExchanger_DATA_04F503[2] = { 0x387d, 0x787e, };
static const uint16 kOwPrompt03_OverworldLifeExchanger_DATA_04F507[2] = { 0x387e, 0x787d, };
static const uint16 kOwPrompt03_OverworldLifeExchanger_DATA_04F50B[2] = { 0xb87d, 0xf87e, };
static const uint16 kOwPrompt03_OverworldLifeExchanger_DATA_04F50F[2] = { 0xb87e, 0xf87d, };
-static const uint8 kLoadOverworldSprites_SubmapBooXPosOffset[6] = { 0x30, 0x0, 0x0, 0x1, 0x10, 0xff, };
-static const uint8 kLoadOverworldSprites_SubmapBooYPosOffset[6] = { 0x20, 0x0, 0x70, 0xff, 0x10, 0x0, };
+
static const uint8 kLoadOverworldSprites_UNK_04F672[3] = { 0x1, 0x40, 0x80, };
static const uint8 kOverworldLightningAndRandomCloudSpawning_DATA_04F6D0[8] = { 0x70, 0x7f, 0x78, 0x7f, 0x70, 0x7f, 0x78, 0x7f, };
static const uint16 kOverworldLightningAndRandomCloudSpawning_DATA_04F6D8[8] = { 0xfff0, 0x20, 0xc0, 0xfff0, 0xfff0, 0x80, 0xfff0, 0x0, };
@@ -149,6 +177,7 @@ const uint8 kOverworldLightningAndRandomCloudSpawning_DATA_04F6F8[8] = { 0x20, 0
const uint8 kOverworldLightningAndRandomCloudSpawning_DATA_04F700[8] = { 0x7, 0x5, 0x6, 0x7, 0x4, 0x6, 0x7, 0x5, };
static const uint8 kCheckIfXIsAllowedOnYSubmap_DisableSpriteOnXSubmapFlags[10] = { 0x7f, 0x21, 0x7f, 0x7f, 0x7f, 0x77, 0x3f, 0xf7, 0xf7, 0x0, };
static const uint8 kSetOverworldSpriteFrameIndex_DATA_04F833[16] = { 0x0, 0x52, 0x31, 0x19, 0x45, 0x2a, 0x3, 0x8b, 0x94, 0x3c, 0x78, 0xd, 0x36, 0x5e, 0x87, 0x1f, };
+
static const uint8 kOverworldSpriteOAMIndexes[16] = { 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0x9c, 0x3c, 0x48, 0xc8, 0xcc, 0xa0, 0xa4, 0xd8, 0xdc, 0xe0, 0xe4, };
static const uint8 kCheckIfXIsAllowedOnYSubmap_ANDTable[7] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, };
static const uint8 kOWSpr01_Lakitu_DATA_04F8A6[8] = { 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, };
@@ -169,18 +198,20 @@ static const uint8 kOWSpr06_KoopaKid_InitialYLo[3] = { 0x7f, 0x7f, 0x8f, };
static const uint8 kOWSpr06_KoopaKid_InitialYHi[3] = { 0x1, 0x0, 0x1, };
static const uint8 kOWSpr06_KoopaKid_byte_4FB94[2] = { 0x8, 0x2, };
static const uint8 kOWSpr06_KoopaKid_byte_4FB96[2] = { 0xf, 0x0, };
-static const uint16 kOWSpr07_Smoke_DATA_04FC1E[2] = { 0x38, 0x68, };
-static const uint16 kOWSpr07_Smoke_DATA_04FC22[2] = { 0x18a, 0x6a, };
static const uint8 kOWSpr07_Smoke_DATA_04FC26[16] = { 0x1, 0x2, 0x3, 0x4, 0x3, 0x2, 0x1, 0x0, 0x1, 0x2, 0x3, 0x4, 0x3, 0x2, 0x1, 0x0, };
static const uint8 kOWSpr07_Smoke_DATA_04FC36[16] = { 0xff, 0xff, 0xfe, 0xfd, 0xfd, 0xfc, 0xfb, 0xfb, 0xfa, 0xf9, 0xf9, 0xf8, 0xf7, 0xf7, 0xf6, 0xf5, };
static const uint8 kOWSpr09_Bowser_DATA_04FD0A[6] = { 0x7, 0x7, 0x3, 0x3, 0x5f, 0x5f, };
static const uint8 kOWSpr09_Bowser_DATA_04FD10[10] = { 0x1, 0xff, 0x1, 0xff, 0x1, 0xff, 0x1, 0xff, 0x1, 0xff, };
-// todo: why 10
-static const uint8 kOWSpr09_Bowser_DATA_04FD1A[10] = { 0x18, 0xe8, 0xa, 0xf6, 0x8, 0xf8, 0x3, 0xfd, 0x1, 0xff,};
+static const uint8 kOWSpr09_Bowser_DATA_04FD1A[10] = { 0x18, 0xe8, 0xa, 0xf6, 0x8, 0xf8, 0x3, 0xfd, 0x1, 0xff,}; // todo: why 10
static const uint8 kOWSpr09_Bowser_DATA_04FD22[2] = { 0x1, 0xff, };
static const uint8 kDrawOverworldSpriteShadow_LeftTileXDisp[16] = { 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x2, 0x2, 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, 0x3, 0x3, };
static const uint8 kDrawOverworldSpriteShadow_RightTileXDisp[16] = { 0x8, 0x8, 0x8, 0x8, 0x7, 0x6, 0x5, 0x5, 0x0, 0x0, 0xe, 0xe, 0xc, 0xc, 0xa, 0xa, };
+static const uint8 kSharedOverworldPathTables_DATA_049060[4] = { 0x5, 0x3, 0x1, 0x0, };
+static const uint16 kSharedOverworldPathTables_DATA_049064[4] = { 0x0, 0x2, 0x4, 0x6, };
+static const uint8 kBitTable_DATA_04E44B[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, };
+static const uint16 kBitTable_Bank04[4] = { 0x8, 0x4, 0x2, 0x1, };
+
void OwTileAnimations_ShiftWaterTiles() { // 048086
uint16 r3 = 0;
@@ -196,15 +227,17 @@ void OwTileAnimations_0480B9(uint16 k, const uint8 *p0) { // 0480b9
uint16 v1 = 0;
uint16 r7 = 8;
uint16 r9 = 8;
+ if (HAS_LM_FEATURE(kLmFeature_OverworldTiles4bpp))
+ r7 = 16, r9 = 0;
do {
*(uint16 *)&sprites_cutscene_sprite_table_0AF6[k] = WORD(p0[v1]);
v1 += 2;
k += 2;
} while (--r7);
- do {
+ for(; r9; r9--) {
*(uint16 *)&sprites_cutscene_sprite_table_0AF6[k] = p0[v1++];
k += 2;
- } while (--r9);
+ }
}
void OwTileAnimations() { // 0480e0
@@ -339,7 +372,7 @@ LABEL_52:
io_sound_ch1 = 33;
io_music_ch1 = 8;
}
- if ((kGameMode0E_ShowOverworld_DATA_048231[ow_active_earthquake_event >> 4] & counter_global_frames) == 0) {
+ if ((kOwEarthquakeFrameMask_048231[ow_active_earthquake_event >> 4] & counter_global_frames) == 0) {
LOBYTE(mirror_current_layer1_xpos) = mirror_current_layer1_xpos ^ 1;
LOBYTE(mirror_current_layer2_xpos) = mirror_current_layer1_xpos;
LOBYTE(mirror_current_layer1_ypos) = mirror_current_layer1_ypos ^ 1;
@@ -372,38 +405,43 @@ LABEL_53:
void GameMode0E_ShowOverworld_UpdateMainMapFreeScrollingPosition(uint8 k, uint8 a) { // 048415
int v2 = a >> 1;
- uint16 v3 = kGameMode0E_ShowOverworld_DATA_048211[v2] + *(uint16 *)((int8 *)&mirror_current_layer1_xpos + k);
- if (__CFSHL__uint16(kGameMode0E_ShowOverworld_DATA_048211[v2] ^ (v3 - kGameMode0E_ShowOverworld_DATA_048221[v2]))) {
+ uint16 v3 = kOwOffsetsFreeScrolling_048211[v2] + *(uint16 *)((int8 *)&mirror_current_layer1_xpos + k);
+ if (__CFSHL__uint16(kOwOffsetsFreeScrolling_048211[v2] ^ (v3 - kOwOffsetsFreeScrollMax_048221[v2]))) {
*(uint16 *)((int8 *)&mirror_current_layer1_xpos + k) = v3;
*(uint16 *)((int8 *)&mirror_current_layer2_xpos + k) = v3;
}
}
bool HandleOverworldStarPipeWarp_GetIndex() { // 048509
- uint8 result;
+ uint16 result;
uint16 r0w = ow_players_map[player_current_character] << 8;
- for (result = 52; (result & 0x80) == 0; result -= 2) {
+ for (result = kOwStarPipeWarp_SrcX_048431_SIZE - 2; (int16)result >= 0; result -= 2) {
int v1 = result >> 1;
- if ((uint16)(r0w ^ kHandleOverworldStarPipeWarp_DATA_048431[v1]) < 0x200) {
+ if ((uint16)(r0w ^ kOwStarPipeWarp_SrcX_048431[v1]) < 0x200) {
PointU16 *pt = get_PointU16(ow_players_grid_aligned_pos, player_current_characterx4);
- if ((r0w ^ kHandleOverworldStarPipeWarp_DATA_048431[v1]) == pt->x && pt->y == kHandleOverworldStarPipeWarp_DATA_048467[v1]) {
+ if ((r0w ^ kOwStarPipeWarp_SrcX_048431[v1]) == pt->x && pt->y == kOwStarPipeWarp_SrcY_048467[v1]) {
break;
}
}
}
- ow_star_pipe_index = result;
- return result != 0xff;
+ if (g_lunar_magic) {
+ if ((int16)result >= 0)
+ ow_star_pipe_index = result >> 1;
+ } else {
+ ow_star_pipe_index = result;
+ }
+ return (int16)result >= 0;
}
void HandleOverworldStarPipeWarp_SetPlayerDestination() { // 04853b
uint8 v0 = player_current_characterx4;
- int v1 = ow_star_pipe_index >> 1;
- uint16 v5 = kHandleOverworldStarPipeWarp_DATA_04849D[v1];
+ int v1 = g_lunar_magic ? ow_star_pipe_index : (ow_star_pipe_index >> 1);
+ uint16 v5 = kOwStarPipeWarp_DstX_04849D[v1];
PointU16 *pt = get_PointU16(ow_players_pos, player_current_characterx4);
pt->x = v5 & 0x1FF;
PointU16 *v3 = get_PointU16(ow_players_grid_aligned_pos, v0);
v3->x = (uint16)(v5 & 0x1FF) >> 4;
- uint16 v4 = kHandleOverworldStarPipeWarp_DATA_0484D3[v1];
+ uint16 v4 = kOwStarPipeWarp_DstY_0484D3[v1];
pt->y = v4;
v3->y = v4 >> 4;
ow_currently_loaded_submap = ((uint16)(v5 >> 1) >> 8) & 0xF;
@@ -559,20 +597,20 @@ uint8 DrawOverworldPlayer_DrawCurrentPlayer(uint8 k_in, uint8 j, PointU8 pt, uin
uint16 r0w = 16 * ow_players_animation[v3 >> 1];
uint16 v7 = r0w + 2 * (counter_global_frames & 8);
if (!k && *(uint16 *)&pointer_current_overworld_process == 11)
- v7 = kDrawOverworldPlayer_StarWarpAnimationOffset[(uint8)(counter_global_frames & 0xC) >> 2];
+ v7 = kOwStarWarpAnimationOffset[(uint8)(counter_global_frames & 0xC) >> 2];
do {
uint16 v12 = v7;
uint16 v8 = v7 >> 1;
OamEnt *oam = get_OamEnt(oam_buf, k);
- oam[39].xpos = pt.x + kDrawOverworldPlayer_PlayerAndYoshiXDisp[v8];
- oam[39].ypos = pt.y + kDrawOverworldPlayer_PlayerAndYoshiYDisp[v8];
+ oam[39].xpos = pt.x + kOwPlayerAndYoshiXDisp[v8];
+ oam[39].ypos = pt.y + kOwPlayerAndYoshiYDisp[v8];
uint16 v10 = v12;
- uint16 v11 = *(uint16 *)&kDrawOverworldPlayer_PlayerRidingYoshiTilesAndProp[v12];
+ uint16 v11 = *(uint16 *)&kOwSpriteTilemapYoshi[v12];
if (v11 != 0xffff) {
- uint16 v13 = *(uint16 *)&kDrawOverworldPlayer_PlayerRidingYoshiTilesAndProp[v12];
+ uint16 v13 = *(uint16 *)&kOwSpriteTilemapYoshi[v12];
uint16 v14;
if ((v11 & 0xF00) == 512) {
- v14 = kDrawOverworldPlayer_YoshiPalette[(yoshi - 4) >> 1] | v13 & 0xF0FF;
+ v14 = kOwYoshiPalette[(yoshi - 4) >> 1] | v13 & 0xF0FF;
} else {
v14 = r4w + v13;
}
@@ -588,7 +626,7 @@ uint8 DrawOverworldPlayer_DrawCurrentPlayer(uint8 k_in, uint8 j, PointU8 pt, uin
v5 = swap16(r4w);
if (*(int16 *)(&player_current_character + (v5 >> 1)) >= 0) {
if (!k && *(uint16 *)&pointer_current_overworld_process == 11)
- v4 = kDrawOverworldPlayer_StarWarpAnimationOffset[(uint8)(counter_global_frames & 0xC) >> 2];
+ v4 = kOwStarWarpAnimationOffset[(uint8)(counter_global_frames & 0xC) >> 2];
} else {
v4 = r0w;
}
@@ -596,7 +634,7 @@ uint8 DrawOverworldPlayer_DrawCurrentPlayer(uint8 k_in, uint8 j, PointU8 pt, uin
OamEnt *v6 = get_OamEnt(oam_buf, k);
v6[39].xpos = pt.x;
v6[39].ypos = pt.y;
- *(uint16 *)&v6[39].charnum = r4w + kDrawOverworldPlayer_PlayerTilesAndProp[v4 >> 1];
+ *(uint16 *)&v6[39].charnum = r4w + kOwSpriteTilemap[v4 >> 1];
k = k + 4;
v4 += 2;
pt.x += 8;
@@ -630,14 +668,14 @@ void GameMode0C_LoadOverworld_048D91() { // 048d91
uint16 r4w = CalculateOverworldPlayerPosition((uint8)player_current_characterx4 >> 2, r0w, r2w);
if ((ow_level_tile_settings[ow_level_number_of_each_tiletbl[r4w]] & 0x80) == 0) {
uint16 v3 = 20;
- while (ow_level_number_lo != kGameMode0C_LoadOverworld_DATA_048D74[v3 >> 1]) {
+ while (ow_level_number_lo != kOwLevelsForcedMusicChange_048D74[v3 >> 1]) {
v3 -= 2;
if ((v3 & 0x8000) != 0)
return;
}
}
}
- io_music_ch1 = kGameMode0C_LoadOverworld_DATA_048D8A[ow_players_map[player_current_character]];
+ io_music_ch1 = kOwSubmapMusic_048D8A[ow_players_map[player_current_character]];
}
}
@@ -647,8 +685,11 @@ void GameMode0C_LoadOverworld_048E55() { // 048e55
uint16 r0w = pt->x;
uint16 r2w = pt->y;
uint16 r4w = CalculateOverworldPlayerPosition((uint16)(4 * player_current_character) >> 2, r0w, r2w);
- r0w = kLevelNames[(uint16)(2 * ow_level_number_of_each_tiletbl[r4w]) >> 1];
- UpdateLevelName(r0w);
+ if (HAS_LM_FEATURE(kLmFeature_LevelNamesPatch)) {
+ LmHook_LevelNamesPatch(ow_level_number_of_each_tiletbl[r4w]);
+ } else {
+ UpdateLevelName(kLevelNames[(uint16)(2 * ow_level_number_of_each_tiletbl[r4w]) >> 1]);
+ }
if (r4w <= 0x7FF)
ow_tile_player_is_standing_on = blocks_map16_table_lo[r4w];
if (ow_enter_level_flag) {
@@ -662,8 +703,8 @@ void GameMode0C_LoadOverworld_048E55() { // 048e55
} else {
int v1 = (uint8)(2 * owspr06_koopa_kid_tile_index) >> 1;
PointU16 *v2 = get_PointU16(ow_players_pos, player_current_characterx4);
- v2->x = kGameMode0C_LoadOverworld_KoopaKidTeleportXPos[v1];
- v2->y = kGameMode0C_LoadOverworld_KoopaKidTeleportYPos[v1];
+ v2->x = kOw_KoopaKidTeleportXYPos_048E49[v1];
+ v2->y = kOw_KoopaKidTeleportXYPos_048E49[v1 + 3];;
}
}
}
@@ -702,7 +743,7 @@ LABEL_11:
void OwProcess02_HandleLevelBeaten() { // 048f87
UnlockOverworldPathBasedOnExit();
uint8 v0 = 7;
- while ((uint8)ow_tile_player_is_standing_on != kOverworldProcess02_HandleLevelBeaten_DATA_048F7F[v0]) {
+ while ((uint8)ow_tile_player_is_standing_on != kOwTriggerSaveTiles_048F7F[v0]) {
if ((--v0 & 0x80) != 0)
goto LABEL_10;
}
@@ -746,6 +787,8 @@ void UpdateSaveBuffer() { // 049037
}
}
+static const uint16 kSharedOverworldPathTables_DATA_049058[4] = { 0xffff, 0x1, 0xffff, 0x1, };
+
void OwProcess03_StandingStill() { // 049120
uint16 v10;
uint8 v0 = 0x91; // note: undefined
@@ -813,7 +856,7 @@ LABEL_18:;
if (misc_exit_level_action) {
r8 = kSharedOverworldPathTables_DATA_049060[(uint8)(misc_exit_level_action - 1)];
for (uint16 i = 10; (i & 0x8000) == 0; i -= 2) {
- if (ow_level_number_of_each_tiletbl[r4w] == kSharedOverworldPathTables_NoAutoMoveLevels[i >> 1]) {
+ if (ow_level_number_of_each_tiletbl[r4w] == kOwNoAutoMoveLevels_04906C[i >> 1]) {
*(uint16 *)&pointer_current_overworld_process = 5;
UpdateSaveBuffer();
goto LABEL_63;
@@ -859,6 +902,7 @@ LABEL_18:;
if (j < 4)
v14 = 2;
r8 = r4w;
+
*(uint16 *)(v14 ? &r2w : &r0w) += kSharedOverworldPathTables_DATA_049058[j >> 1];
int16 v22;
r4w = CalculateOverworldPlayerPosition(player_current_characterx4 >> 2, r0w, r2w);
@@ -872,11 +916,11 @@ LABEL_53:
r0w = v16;
r2w = 0;
for (uint16 k = 23; (k & 0x8000) == 0; --k) {
- if (kSharedOverworldPathTables_DATA_04A03C[k] == r0w) {
- int16 v29 = player_current_characterx4 + WORD(kSharedOverworldPathTables_DATA_04A0E4[k]);
+ if (kOwUnknownTableA_From_04A03C[k] == r0w) {
+ int16 v29 = player_current_characterx4 + WORD(kOwUnknownTableA_Direction_04A0E4[k]);
int v21 = (uint16)(4 * k) >> 1;
- r0w = kSharedOverworldPathTables_DATA_04A084[v21];
- r2w = kSharedOverworldPathTables_DATA_04A084[v21 + 1];
+ r0w = kOwUnknownTableA_XY_04A084[v21];
+ r2w = kOwUnknownTableA_XY_04A084[v21 + 1];
v22 = (uint8)v29;
goto LABEL_62;
}
@@ -909,26 +953,26 @@ LABEL_62:;
ow_hardcoded_path_index = 0;
r0w = ow_level_number_of_each_tiletbl[r8];
uint16 v17 = 9;
- while (kSharedOverworldPathTables_HardCodedOWPaths_LevelNums[v17] != 255) {
- if (kSharedOverworldPathTables_HardCodedOWPaths_LevelNums[v17] == r0w)
+ while (kOwHardcodedPathLevel_049078[v17] != 255) {
+ if (kOwHardcodedPathLevel_049078[v17] == r0w)
goto LABEL_49;
LABEL_51:
if ((--v17 & 0x8000) != 0)
goto LABEL_52;
}
PointU16 *v18 = get_PointU16(ow_players_pos, player_current_characterx4);
- if (v18->y != kSharedOverworldPathTables_DATA_049082[0] || v18->x != kSharedOverworldPathTables_DATA_049084[0] ||
+ if (v18->y != kOwHardcodedPathChocolateIsland2_049082[0] || v18->x != kOwHardcodedPathChocolateIsland2_049082[1] ||
ow_players_map[player_current_character]) {
goto LABEL_51;
}
LABEL_49:
r0w = v17;
- uint16 v19 = kSharedOverworldPathTables_HardCodedOWPaths_Layer1AndMovementTableIndex[v17];
+ uint16 v19 = kOwHardcodedPathStartIndex_04910E[v17];
ow_hardcoded_path_index = v19 - 1;
r2w = j;
- if (kSharedOverworldPathTables_HardCodedOWPaths_MovementDirection[v19] == j) {
+ if (kOwHardcodedPathDirs_0490CA[v19] == j) {
ow_process_hardcoded_path_flag = 1;
- v16 = kSharedOverworldPathTables_HardCodedOWPaths_Layer1Tiles[v19];
+ v16 = kOwHardcodedPathTiles_049086[v19];
goto LABEL_53;
}
LABEL_52:
@@ -1006,8 +1050,11 @@ void OwProcess04_PlayerIsMoving() { // 04945d
uint16 r0w = pt->x;
uint16 r2w = pt->y;
uint16 r4w = CalculateOverworldPlayerPosition(player_current_characterx4 >> 2, r0w, r2w);
- r0w = kLevelNames[(uint16)(2 * ow_level_number_of_each_tiletbl[r4w]) >> 1];
- UpdateLevelName(r0w);
+ if (HAS_LM_FEATURE(kLmFeature_LevelNamesPatch)) {
+ LmHook_LevelNamesPatch(ow_level_number_of_each_tiletbl[r4w]);
+ } else {
+ UpdateLevelName(kLevelNames[(uint16)(2 * ow_level_number_of_each_tiletbl[r4w]) >> 1]);
+ }
++*(uint16 *)&pointer_current_overworld_process;
UpdateSaveBuffer();
OwProcess04_PlayerIsMoving_049831();
@@ -1032,9 +1079,9 @@ void OwProcess04_PlayerIsMoving() { // 04945d
break;
// r6w = v11;
uint16 v16 = ow_hardcoded_path_index + 1;
- if (kSharedOverworldPathTables_HardCodedOWPaths_MovementDirection[(uint16)(ow_hardcoded_path_index + 1)] == v11) {
+ if (kOwHardcodedPathDirs_0490CA[(uint16)(ow_hardcoded_path_index + 1)] == v11) {
++ow_hardcoded_path_index;
- v15 = kSharedOverworldPathTables_HardCodedOWPaths_Layer1Tiles[v16];
+ v15 = kOwHardcodedPathTiles_049086[v16];
if (v15 != 88)
goto LABEL_34;
break;
@@ -1056,14 +1103,14 @@ LABEL_34:
goto LABEL_24;
v42 = v15;
int16 v41 = v11;
- r14w = kSharedOverworldPathTables_DATA_049FEB[v15 - 1];
+ r14w = kOwTilePose_049FEB[v15 - 1];
ow_player_on_climbing_tile = (r14w == 20);
PointU16 *v18 = get_PointU16(ow_players_grid_aligned_pos, player_current_characterx4);
v18->x = r0w;
v18->y = r2w;
v19 = v41;
uint8 v20 = 9;
- while ((uint8)v15 != *((uint8 *)kOverworldProcess04_PlayerIsMoving_DATA_049426 + v20)) {
+ while ((uint8)v15 != *((uint8 *)kOwExitLevelTiles_049426 + v20)) {
if ((--v20 & 0x80) != 0)
goto LABEL_42;
}
@@ -1080,8 +1127,8 @@ LABEL_42:
if (v42 < 0x56) {
v25 = 2 * (v42 - 1);
int v26 = v25 >> 1;
- r4w = kSharedOverworldPathTables_DATA_049F49[v26];
- v24 = kSharedOverworldPathTables_DATA_049EA7[v26];
+ r4w = kOwTilePathDirection_049F49[v26];
+ v24 = kOwTileDistanceMovedAcross_049EA7[v26];
} else {
if (v42 == 128 || v42 >= 0x6A && v42 < 0x6E) {
int v21 = (uint16)((player_current_characterx4 >> 1) & 2) >> 1;
@@ -1102,8 +1149,8 @@ LABEL_42:
r4w = 1;
r0w = (uint8)copy_of_tile_player_is_standingd_on;
for (int16 k = 23; k >= 0; --k) {
- if (kSharedOverworldPathTables_DATA_04A03C[(uint16)k] == r0w) {
- v24 = kSharedOverworldPathTables_DATA_04A054[(uint16)(2 * k) >> 1];
+ if (kOwUnknownTableA_From_04A03C[(uint16)k] == r0w) {
+ v24 = kOwUnknownTableA_Alpha_04A054[(uint16)(2 * k) >> 1];
goto LABEL_60;
}
}
@@ -1121,9 +1168,7 @@ LABEL_60:
goto LABEL_68;
}
if ((uint8)v19 != HIBYTE(kOverworldProcess04_PlayerIsMoving_DATA_049430[v28])) {
- LOBYTE(v27) = (uint8)(v28 * 2) >> 1;
- LOBYTE(v27) = kOverworldProcess04_PlayerIsMoving_DATA_04944E[v27];
- v29 = v27;
+ v29 = kOverworldProcess04_PlayerIsMoving_DATA_04944E[v28];
goto LABEL_69;
}
LABEL_68:
@@ -1194,12 +1239,12 @@ void OwProcess04_PlayerIsMoving_04983F() { // 04983f
uint16 v3 = (v1 ? r2w : r0w) - 128;
if ((v3 & 0x8000) == 0) {
int v5 = v2 >> 1;
- if (v3 >= kOverworldProcess04_PlayerIsMoving_MaxOverworlCameraPosition_RightAndBottom[v5])
- v3 = kOverworldProcess04_PlayerIsMoving_MaxOverworlCameraPosition_RightAndBottom[v5];
+ if (v3 >= kOw_MaxRangeForScrollWalking_049416[v5 + 2])
+ v3 = kOw_MaxRangeForScrollWalking_049416[v5 + 2];
} else {
int v4 = v2 >> 1;
- if (v3 < kOverworldProcess04_PlayerIsMoving_MaxOverworlCameraPosition[v4])
- v3 = kOverworldProcess04_PlayerIsMoving_MaxOverworlCameraPosition[v4];
+ if (v3 < kOw_MaxRangeForScrollWalking_049416[v4])
+ v3 = kOw_MaxRangeForScrollWalking_049416[v4];
}
*(uint16 *)((int8 *)&mirror_current_layer1_xpos + v1) = v3;
*(uint16 *)((int8 *)&mirror_current_layer2_xpos + v1) = v3;
@@ -1257,50 +1302,17 @@ void UnlockOverworldPathBasedOnExit() { // 049903
}
}
-static const OwExits kHandleOverworldPathExits_DATA_049964[] = {
- {0x0140, 0x0028, 0},
- {0x0150, 0x0058, 0},
- {0x0010, 0x0048, 1},
- {0x0010, 0x0098, 1},
- {0x00a0, 0x00d8, 0},
- {0x0140, 0x0058, 2},
- {0x0090, 0x01e8, 4},
- {0x0160, 0x00e8, 0},
- {0x00a0, 0x01c8, 0},
- {0x0160, 0x0088, 3},
- {0x0108, 0x0190, 0},
- {0x01e8, 0x0010, 3},
- {0x0110, 0x01c8, 0},
- {0x01f0, 0x0088, 3},
-};
-
-static const OwExits kHandleOverworldPathExits_DATA_0499AA[] = {
- {0x0000, 0x0048, 1},
- {0x0000, 0x0098, 1},
- {0x0150, 0x0028, 0},
- {0x0160, 0x0058, 0},
- {0x0150, 0x0058, 2},
- {0x0090, 0x00d8, 0},
- {0x0150, 0x00e8, 0},
- {0x00a0, 0x01e8, 4},
- {0x0150, 0x0088, 3},
- {0x00b0, 0x01c8, 0},
- {0x01e8, 0x0000, 3},
- {0x0108, 0x01a0, 0},
- {0x0200, 0x0088, 3},
- {0x0100, 0x01c8, 0},
-};
-
void HandleOverworldPathExits() { // 049a24
PointU16 *pt;
ow_currently_loaded_submap = ow_players_map[(uint8)(player_current_characterx4 >> 2)];
uint16 r2w = 26;
uint8 v0 = 13;
uint8 v1 = player_current_characterx4;
+ const OwExits *src = (OwExits*)kOwExitSource_049964;
while (1) {
pt = get_PointU16(ow_players_pos, player_current_characterx4);
- if (pt->y == kHandleOverworldPathExits_DATA_049964[v0].field_0 && pt->x == kHandleOverworldPathExits_DATA_049964[v0].field_2 &&
- kHandleOverworldPathExits_DATA_049964[v0].field_4 == ow_currently_loaded_submap) {
+ if (pt->y == src[v0].field_0 && pt->x == src[v0].field_2 &&
+ src[v0].field_4 == ow_currently_loaded_submap) {
break;
}
--r2w;
@@ -1308,12 +1320,13 @@ void HandleOverworldPathExits() { // 049a24
if ((--v0 & 0x80) != 0)
return;
}
- pt->y = kHandleOverworldPathExits_DATA_0499AA[v0].field_0;
- pt->x = kHandleOverworldPathExits_DATA_0499AA[v0].field_2;
- ow_currently_loaded_submap = kHandleOverworldPathExits_DATA_0499AA[v0].field_4;
+ const OwExits *dst = (OwExits*)kOwExitDest_0499AA;
+ pt->y = dst[v0].field_0;
+ pt->x = dst[v0].field_2;
+ ow_currently_loaded_submap = dst[v0].field_4;
PointU16 *v4 = get_PointU16(ow_players_grid_aligned_pos, v1);
- v4->y = kHandleOverworldPathExits_DATA_0499F0[r2w];
- v4->x = kHandleOverworldPathExits_DATA_0499F0[r2w + 1];
+ v4->y = kOwExitExtra_0499F0[r2w];
+ v4->x = kOwExitExtra_0499F0[r2w + 1];
}
void HandleOverworldPathExits_SetLayerPositions() { // 049a93
@@ -1322,32 +1335,15 @@ void HandleOverworldPathExits_SetLayerPositions() { // 049a93
*(uint16 *)&ow_players_map[v0] = v1;
if ((uint8)v1) {
int v2 = (uint16)(4 * ((uint8)v1 - 1)) >> 1;
- mirror_current_layer1_xpos = kHandleOverworldPathExits_DATA_049A0C[v2];
+ mirror_current_layer1_xpos = kOwExitLayerPosition_049A0C[v2];
mirror_current_layer2_xpos = mirror_current_layer1_xpos;
- mirror_current_layer1_ypos = kHandleOverworldPathExits_DATA_049A0C[v2 + 1];
+ mirror_current_layer1_ypos = kOwExitLayerPosition_049A0C[v2 + 1];
mirror_current_layer2_ypos = mirror_current_layer1_ypos;
} else {
OwProcess04_PlayerIsMoving_04983F();
}
}
-
-static const SpriteSlotData kLoadOverworldSprites_SpriteSlotData[] = {
- {0, 0x100, 0xe0},
- {0, 0x100, 0x60},
- {6, 0x170, 0x20},
- {7, 0x38, 0x18a},
- {0, 0x58, 0x7a},
- {8, 0x188, 0x18},
- {9, 0x148, 0xfffc},
- {0, 0x80, 0x100},
- {0, 0x50, 0x140},
- {3, 0x0, 0x0},
- {10, 0x40, 0x98},
- {10, 0x60, 0xf8},
- {10, 0x140, 0x158},
-};
-
void UpdateLevelName(uint16 r0w) { // 049d07
uint16 v0 = stripe_image_upload;
uint16 r2w = stripe_image_upload + 38;
@@ -1514,24 +1510,31 @@ uint16 LoadOverworldLayer1AndEvents_InitializedOverworldLayer1Tilemap(uint16 k,
}
void LoadOverworldLayer1AndEvents_04D7F2() { // 04d7f2
- uint8 *r13 = g_ram + 0xd000;
- uint8 *r10 = g_ram + 0xd800;
- uint8 *r4 = g_ram + 0xc800;
+ if (kOwLayer1AndEvents_SIZE) {
+ int len = DecompressTo(kOwLayer1AndEvents, g_ram + 0xd000); // 0x1000 bytes
+ if (kOwLayer1AndEvents2_SIZE)
+ DecompressTo(kOwLayer1AndEvents2, g_ram + 0x1c800);
+ } else {
+ uint8 *r13 = g_ram + 0xd000;
+ uint8 *r10 = g_ram + 0xd800;
+ uint8 *r4 = g_ram + 0xc800;
- uint8 r0 = 1;
- for (int16 i = 0x7ff; i >= 0; --i) {
- r10[i] = 0;
- r13[i] = 0;
- }
- for (uint16 j = 0; j != 0x800; ++j) {
- uint8 v3 = r4[j];
- if (v3 >= 0x56 && v3 < 0x81) {
- uint8 v0 = r0;
- r13[j] = r0;
- r10[j] = kLoadOverworldLayer1AndEvents_DATA_04D678[v0];
- ++r0;
+ uint8 r0 = 1;
+ for (int16 i = 0x7ff; i >= 0; --i) {
+ r10[i] = 0;
+ r13[i] = 0;
+ }
+ for (uint16 j = 0; j != 0x800; ++j) {
+ uint8 v3 = r4[j];
+ if (v3 >= 0x56 && v3 < 0x81) {
+ uint8 v0 = r0;
+ r13[j] = r0;
+ r10[j] = kOwDirectionAfterBeatingLevel_04D678[v0];
+ ++r0;
+ }
}
}
+
uint8 r15 = 0;
do {
LoadOverworldLayer1AndEvents_04DA49(r15);
@@ -1551,12 +1554,14 @@ void LoadOverworldLayer1AndEvents_04DA49(uint8 r15) { // 04da49
}
uint8 v3 = kChangingLayer1OverworldTiles_TilesToBecome[v1];
p4[v0] = v3;
- if (v1 == 21)
- p4[v0 + 1] = v3;
+ if (!HAS_LM_FEATURE(kLmFeature_EventStuff)) {
+ if (v1 == 21)
+ p4[v0 + 1] = v3;
+ }
LABEL_8:
CheckIfDestroyTileEventIsActive(r15);
pointer_overworld_event_process = 0;
- OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(r15);
+ OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(r15, true);
}
}
@@ -1591,19 +1596,24 @@ void OwProcess0A_SwitchBetweenSubmaps() { // 04daef
void SubmapSwitchProcess06_EndWindowHDMA() { // 04db18
int16 v1;
+ static const uint16 kInitializeWindowHDMA_DATA_04DB08[2] = { 0xf900, 0x700, };
+ static const uint8 kInitializeWindowHDMA_DATA_04DB0C[4] = { 0x0, 0x0, 0x0, 0x70, };
+ static const uint16 kInitializeWindowHDMA_DATA_04DB10[2] = { 0xfac0, 0x540, };
+ static const uint8 kInitializeWindowHDMA_DATA_04DB14[4] = { 0x0, 0x0, 0x0, 0x54, };
+
int v0 = ow_hdmatransition_effect_flag >> 1;
- ow_hdmatransition_effect_xpos += kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB08[v0];
- if (((kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB08[v0] ^
+ ow_hdmatransition_effect_xpos += kInitializeWindowHDMA_DATA_04DB08[v0];
+ if (((kInitializeWindowHDMA_DATA_04DB08[v0] ^
(ow_hdmatransition_effect_xpos -
- *(uint16 *)&kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB0C[ow_hdmatransition_effect_flag])) &
+ *(uint16 *)&kInitializeWindowHDMA_DATA_04DB0C[ow_hdmatransition_effect_flag])) &
0x8000) == 0 ||
- (ow_hdmatransition_effect_ypos += kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB10[v0],
- ((kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB10[v0] ^
+ (ow_hdmatransition_effect_ypos += kInitializeWindowHDMA_DATA_04DB10[v0],
+ ((kInitializeWindowHDMA_DATA_04DB10[v0] ^
(ow_hdmatransition_effect_ypos -
- *(uint16 *)&kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB14[ow_hdmatransition_effect_flag])) &
+ *(uint16 *)&kInitializeWindowHDMA_DATA_04DB14[ow_hdmatransition_effect_flag])) &
0x8000) == 0)) {
- ow_hdmatransition_effect_xpos = *(uint16 *)&kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB0C[ow_hdmatransition_effect_flag];
- ow_hdmatransition_effect_ypos = *(uint16 *)&kSubmapSwitchProcess00_InitializeWindowHDMA_DATA_04DB14[ow_hdmatransition_effect_flag];
+ ow_hdmatransition_effect_xpos = *(uint16 *)&kInitializeWindowHDMA_DATA_04DB0C[ow_hdmatransition_effect_flag];
+ ow_hdmatransition_effect_ypos = *(uint16 *)&kInitializeWindowHDMA_DATA_04DB14[ow_hdmatransition_effect_flag];
++*(uint16 *)&ow_submap_switch_process;
ow_hdmatransition_effect_flag ^= 2;
if (ow_hdmatransition_effect_flag)
@@ -1628,7 +1638,7 @@ void SubmapSwitchProcess06_EndWindowHDMA() { // 04db18
}
void SubmapSwitchProcess05_UpdatePalette() { // 04db9d
- misc_level_tileset_setting = kLoadOverworldLayer1AndEvents_DATA_04DC02[ow_players_map[(uint8)player_current_characterx4 >> 2]];
+ misc_level_tileset_setting = kOwSubmapTileset_04DC02[ow_players_map[(uint8)player_current_characterx4 >> 2]];
BufferPalettesRoutines_Overworld();
palettes_palette_mirror[0] = 510;
LOBYTE(palettes_palette_mirror[128]) = 0;
@@ -1641,13 +1651,13 @@ void SubmapSwitchProcess07_EndSubmapSwitch() { // 04dbcf
pointer_current_overworld_process = 4;
uint8 v0 = (uint8)player_current_characterx4 >> 2;
if (!flag_two_player_game || flag_change_submap_music_on_player_switch || ow_players_map[v0] != ow_players_map[v0 ^ 1]) {
- io_music_ch1 = kSubmapSwitchProcess07_EndSubmapSwitch_DATA_04DBC8[ow_players_map[v0]];
+ io_music_ch1 = kOwSubmapMusic_048D8A[ow_players_map[v0]];
flag_change_submap_music_on_player_switch = 0;
}
}
void LoadOverworldLayer1AndEvents() { // 04dc09
- misc_level_tileset_setting = kLoadOverworldLayer1AndEvents_DATA_04DC02[ow_players_map[(uint8)player_current_characterx4 >> 2]];
+ misc_level_tileset_setting = kOwSubmapTileset_04DC02[ow_players_map[(uint8)player_current_characterx4 >> 2]];
graphics_level_sprite_graphics_setting = 17;
misc_level_mode_setting = 7;
misc_level_layout_flags = 3;
@@ -1671,11 +1681,12 @@ void LoadOverworldLayer2AndEventsTilemaps_Sub() { // 04dc6a
LoadOverworldLayer2AndEventsTilemaps_04DD40();
BufferOverworldLayer2Tilemap(0, 0, 0x4000, kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap);
BufferOverworldLayer2Tilemap(1, 0, 0x4000, kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop);
- uint8 r15 = 0;
+ uint8 r15 = 0, r15_end = g_lunar_magic ? 120 : 111;
do {
+ // lm hook moved into function
LoadOverworldLayer2AndEventsTilemaps_04E453(r15);
++r15;
- } while (r15 != 111);
+ } while (r15 != r15_end);
}
void SubmapSwitchProcess01_UpdateLayer1() { // 04dcb6
@@ -1701,7 +1712,7 @@ void SubmapSwitchProcess01_UpdateLayer1() { // 04dcb6
}
void LoadOverworldLayer2AndEventsTilemaps_04DD40() { // 04dd40
- LoadOverworldLayer2AndEventsTilemaps_04DD57(0, 0, kkOverworldLayer2EventTilemap_Prop);
+ LoadOverworldLayer2AndEventsTilemaps_04DD57(0, 0, kOverworldLayer2EventTilemap_Prop);
}
void LoadOverworldLayer2AndEventsTilemaps_04DD57(uint16 k, uint16 j, const uint8 *p2) { // 04dd57
@@ -1728,9 +1739,11 @@ void LoadOverworldLayer2AndEventsTilemaps_04DD57(uint16 k, uint16 j, const uint8
void LoadOverworldLayer2AndEventsTilemaps_04E453(uint8 r15) { // 04e453
if ((kBitTable_DATA_04E44B[r15 & 7] & ow_event_flags[r15 >> 3]) != 0) {
int v0 = (uint8)(2 * r15) >> 1;
- ow_starting_event_tile = kLayer2EventData_Ptrs[v0];
- for (ow_final_event_tile = kLayer2EventData_Ptrs[v0 + 1]; ow_starting_event_tile != ow_final_event_tile; ++ow_starting_event_tile) {
+ ow_starting_event_tile = kLayer2EventData_Ptrs_04E359[v0];
+ for (ow_final_event_tile = kLayer2EventData_Ptrs_04E359[v0 + 1]; ow_starting_event_tile != ow_final_event_tile; ++ow_starting_event_tile) {
BufferEventTileToLayer2Tilemap();
+ if (HAS_LM_FEATURE(kLmFeature_EventStuff))
+ LmHook_EventStuff(r15, false);
}
}
}
@@ -1796,7 +1809,7 @@ void OwEventProcess00_CheckIfEventShouldRun() { // 04e5ee
if (!counter_enemy_rollcall_screen || ow_current_event_number == 0xFF ||
((kBitTable_DATA_04E44B[ow_current_event_number & 7] & ow_event_flags[ow_current_event_number >> 3]) != 0)) {
for (int8 i = 7; i >= 0; --i) {
- if (*((uint8 *)kOwEventProcess00_CheckIfEventShouldRun_DATA_04E5E6 + (uint8)i) == (uint8)ow_tile_player_is_standing_on) {
+ if (kOwTriggerSaveTiles_048F7F[i] == (uint8)ow_tile_player_is_standing_on) { // merged tables
++pointer_current_overworld_process;
misc_exit_level_action = -32;
timer_keep_game_mode_active = 15;
@@ -1819,8 +1832,8 @@ void OwEventProcess00_CheckIfEventShouldRun() { // 04e5ee
}
uint16 CheckIfDestroyTileEventIsActive(uint8 a) { // 04e677
- uint8 v1 = 23;
- while (a != kCheckIfDestroyTileEventIsActive_EventNums[v1]) {
+ uint8 v1 = kOwDestruction_TriggerEvent_04E5D6_SIZE - 1; // bug fix
+ while (a != kOwDestruction_TriggerEvent_04E5D6[v1]) {
if ((--v1 & 0x80) != 0) {
LABEL_4:
pointer_overworld_event_process = 2;
@@ -1832,27 +1845,26 @@ LABEL_4:
uint16 v2 = kCheckIfDestroyTileEventIsActive_DATA_04E5B6[v1];
uint16 v3 = 4;
uint8 v4 = p[v2];
- while (v4 != kCheckIfDestroyTileEventIsActive_DATA_04E5A7[v3]) {
+ while (v4 != kOwDestruction_TileToIdx_04E5A7[v3]) {
if ((--v3 & 0x8000) != 0)
goto LABEL_4;
}
ow_destroy_tile_event_tile_index = v3;
if ((int16)(v3 - 3) >= 0) {
- p[v2] = kCheckIfDestroyTileEventIsActive_DATA_04E5AC[v3];
- v2 += 16;
+ p[v2] = kOwDestruction_TopTile_04E5AC[v3];
+ v2 = HAS_LM_FEATURE(kLmFeature_DestroyTileAnims) ? LmHook_RemapDestroyTile(v2) : v2 + 16;
}
- p[v2] = kCheckIfDestroyTileEventIsActive_DATA_04E5B1[v3];
+ p[v2] = kOwDestruction_BottomTile_04E5B1[v3];
return v2;
}
void OwEventProcess02_SetEventTileIndexes() { // 04e6d3
++pointer_overworld_event_process;
int v0 = (uint8)(2 * ow_current_event_number) >> 1;
- ow_starting_event_tile = kLayer2EventData_Ptrs[v0];
- ow_final_event_tile = kLayer2EventData_Ptrs[v0 + 1];
+ ow_starting_event_tile = kLayer2EventData_Ptrs_04E359[v0];
+ ow_final_event_tile = kLayer2EventData_Ptrs_04E359[v0 + 1];
if (ow_final_event_tile == ow_starting_event_tile) {
- ++pointer_overworld_event_process;
- ++pointer_overworld_event_process;
+ pointer_overworld_event_process += 2;
}
}
@@ -2024,23 +2036,27 @@ uint16 BufferEventTileToStripeImageTable_Buffer6x6Tile(uint16 r0w, uint16 r2w, u
}
void OwEventProcess07_SilentEventsAndEndOfEvent() { // 04e9ec
- OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(ow_current_event_number);
+ OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(ow_current_event_number, false);
}
-void OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(uint8 a) { // 04e9f1
- for (uint8 i = 43; (i & 0x80) == 0; --i) {
- if (a == kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles[i]) {
- uint8 v4 = i;
- uint8 r2 = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileLayer[i];
- uint16 v2 = (uint8)(2 * i);
- int v3 = (uint8)v2 >> 1;
- uint16 r0w = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileNum[v3];
- uint16 r4w = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TilemapLocation[v3];
- if ((r2 & 1) != 0)
- BufferEventTileToLayer2Tilemap_Entry2(v2, r0w, r4w);
- else
- blocks_map16_table_lo[r4w] = r0w;
- i = v4;
+void OwEventProcess07_SilentEventsAndEndOfEvent_Entry2(uint8 a, bool from_where) { // 04e9f1
+ if (HAS_LM_FEATURE(kLmFeature_EventStuff)) {
+ LmHook_EventStuff(a, from_where);
+ } else {
+ for (uint8 i = 43; (i & 0x80) == 0; --i) {
+ if (a == kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles[i]) {
+ uint8 v4 = i;
+ uint8 r2 = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileLayer[i];
+ uint16 v2 = (uint8)(2 * i);
+ int v3 = (uint8)v2 >> 1;
+ uint16 r0w = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TileNum[v3];
+ uint16 r4w = kOwEventProcess07_SilentEventsAndEndOfEvent_SilentEventTiles_TilemapLocation[v3];
+ if ((r2 & 1) != 0)
+ BufferEventTileToLayer2Tilemap_Entry2(v2, r0w, r4w);
+ else
+ blocks_map16_table_lo[r4w] = r0w;
+ i = v4;
+ }
}
}
if (pointer_overworld_event_process) {
@@ -2138,14 +2154,14 @@ void OwEventProcess06_FadeInLayer1Tile() { // 04ebeb
v0 = 24;
}
v1 = v0 & 0xFC;
- r2 = kOwEventProcess01_DestroyTileAnimation_DATA_04EBE1[(uint8)(v0 & 0xFC) >> 2];
+ r2 = kOwDestroyTileAnimation_Char2_04EBE1[(v0 & 0xFC) >> 2];
pt = GetXAndYDispOfCurrentEventTileSprite();
} else {
if (timer_destroy_tile_event_unknown == 16) {
OwEventProcess01_DestroyTileAnimation_04ED83();
v0 = 16;
}
- r2 = kOwEventProcess01_DestroyTileAnimation_DATA_04EBDA[v0 >> 2];
+ r2 = kOwDestroyTileAnimation_Char_04EBDA[v0 >> 2];
pt = GetXAndYDispOfCurrentEventTileSprite();
v1 = 40;
}
@@ -2153,10 +2169,10 @@ void OwEventProcess06_FadeInLayer1Tile() { // 04ebeb
uint8 v2 = 0;
do {
OamEnt *oam = get_OamEnt(oam_buf, v2);
- oam[32].xpos = kOwEventProcess01_DestroyTileAnimation_DATA_04EB56[v1] + pt.x;
- oam[32].ypos = kOwEventProcess01_DestroyTileAnimation_DATA_04EB82[v1] + pt.y;
+ oam[32].xpos = kOwDestroyTileAnimation_X_04EB56[v1] + pt.x;
+ oam[32].ypos = kOwDestroyTileAnimation_Y_04EB82[v1] + pt.y;
oam[32].charnum = r2;
- oam[32].flags = kOwEventProcess01_DestroyTileAnimation_DATA_04EBAE[v1];
+ oam[32].flags = kOwDestroyTileAnimation_Flags_04EBAE[v1];
v2 += 4;
++v1;
--r3;
@@ -2193,8 +2209,6 @@ void OwEventProcess05_GetLayer1Tile() { // 04ec78
timer_destroy_tile_event_unknown = 28;
}
-static const uint8 kOverworldEventProcess01_DestroyTileAnimation_DATA_04ECD3[176] = { 134, 153, 134, 25, 134, 217, 134, 89, 150, 153, 150, 25, 150, 217, 150, 89, 134, 157, 134, 29, 134, 221, 134, 93, 150, 157, 150, 29, 150, 221, 150, 93, 134, 153, 134, 25, 134, 217, 134, 89, 150, 153, 150, 25, 150, 217, 150, 89, 134, 157, 134, 29, 134, 221, 134, 93, 150, 157, 150, 29, 150, 221, 150, 93, 136, 21, 152, 21, 137, 21, 153, 21, 164, 17, 180, 17, 165, 17, 181, 17, 34, 17, 144, 17, 34, 17, 145, 17, 194, 17, 210, 17, 195, 17, 211, 17, 166, 17, 182, 17, 167, 17, 183, 17, 130, 25, 146, 25, 131, 25, 147, 25, 200, 25, 248, 25, 201, 25, 249, 25, 128, 28, 144, 28, 129, 28, 144, 92, 128, 20, 144, 20, 129, 20, 144, 84, 162, 17, 178, 17, 163, 17, 179, 17, 130, 29, 146, 29, 131, 29, 147, 29, 134, 153, 134, 25, 134, 217, 134, 89, 134, 153, 134, 25, 134, 217, 134, 89, 168, 17, 184, 17, 169, 17, 185, 17, };
-
void OwEventProcess01_DestroyTileAnimation_04ED83() { // 04ed83
uint16 v0 = 21;
uint8 v1 = g_ram[0xc800 + kChangingLayer1OverworldTiles_Layer1TileLocation[ow_current_event_number]];
@@ -2206,20 +2220,29 @@ void OwEventProcess01_DestroyTileAnimation_04ED83() { // 04ed83
// r14w = v0;
int v2 = ow_current_event_number;
uint16 r0w = kOwEventProcess01_DestroyTileAnimation_DATA_04D93D[v2];
- blocks_map16_table_lo[kChangingLayer1OverworldTiles_Layer1TileLocation[v2]] = kChangingLayer1OverworldTiles_TilesToBecome[v0];
- OwEventProcess01_DestroyTileAnimation_04EDE6(stripe_image_upload, 8 * v0, r0w, kOverworldEventProcess01_DestroyTileAnimation_DATA_04ECD3);
+
+ uint16 k = kChangingLayer1OverworldTiles_Layer1TileLocation[v2];
+ blocks_map16_table_lo[k] = kChangingLayer1OverworldTiles_TilesToBecome[v0];
+
+ const uint8 *p;
+ if (HAS_LM_FEATURE(kLmFeature_DestroyTileAnims))
+ p = LmHook_DestroyTileAnimation3(k);
+ else
+ p = kOverworldEventProcess01_DestroyTileAnimation_DATA_04ECD3 + 8 * v0;
+
+ OwEventProcess01_DestroyTileAnimation_04EDE6(stripe_image_upload, r0w, p);
}
-void OwEventProcess01_DestroyTileAnimation_04EDE6(uint16 k, uint16 j, uint16 r0w, const uint8 *p) { // 04ede6
+void OwEventProcess01_DestroyTileAnimation_04EDE6(uint16 k, uint16 r0w, const uint8 *p) { // 04ede6
uint16 v2 = r0w;
*(uint16 *)&stripe_image_upload_data[k] = r0w;
*(uint16 *)&stripe_image_upload_data[k + 8] = v2 + 0x2000;
*(uint16 *)&stripe_image_upload_data[k + 2] = 768;
*(uint16 *)&stripe_image_upload_data[k + 10] = 768;
- *(uint16 *)&stripe_image_upload_data[k + 4] = *(uint16 *)(p + j);
- *(uint16 *)&stripe_image_upload_data[k + 12] = *(uint16 *)(p + j + 2);
- *(uint16 *)&stripe_image_upload_data[k + 6] = *(uint16 *)(p + j + 4);
- *(uint16 *)&stripe_image_upload_data[k + 14] = *(uint16 *)(p + j + 6);
+ *(uint16 *)&stripe_image_upload_data[k + 4] = *(uint16 *)p;
+ *(uint16 *)&stripe_image_upload_data[k + 12] = *(uint16 *)(p + 2);
+ *(uint16 *)&stripe_image_upload_data[k + 6] = *(uint16 *)(p + 4);
+ *(uint16 *)&stripe_image_upload_data[k + 14] = *(uint16 *)(p + 6);
*(uint16 *)&stripe_image_upload_data[k + 16] = 255;
stripe_image_upload = k + 16;
}
@@ -2242,38 +2265,42 @@ void OwEventProcess04_FadeInLayer2Tile_04EE30() { // 04ee30
stripe_image_upload = v0;
}
-static const uint8 kOverworldEventProcess01_DestroyTileAnimation_DATA_04EE7A[48] = { 34, 1, 130, 28, 34, 1, 131, 28, 34, 1, 130, 20, 34, 1, 131, 20, 234, 1, 234, 1, 234, 193, 234, 193, 234, 1, 234, 1, 234, 193, 234, 193, 34, 1, 34, 1, 34, 1, 34, 1, 138, 21, 154, 21, 139, 21, 155, 21, };
-
void OwEventProcess01_DestroyTileAnimation_04EEAA() { // 04eeaa
uint16 v2;
- const uint8 *p = kOverworldEventProcess01_DestroyTileAnimation_DATA_04EE7A;
+ const uint8 *p = kOverworldEventProcess01_DestroyTileAnimation_DATA_04EE7A + 8 * ow_destroy_tile_event_tile_index;
+ uint16 r0w = kOwEventProcess01_DestroyTileAnimation_DATA_04E587[ow_destroy_tile_event_vramindex];
+ uint16 r2 = 0;
+
+ if (HAS_LM_FEATURE(kLmFeature_DestroyTileAnims)) {
+ r2 = kCheckIfDestroyTileEventIsActive_DATA_04E5B6[ow_destroy_tile_event_vramindex];
+ p = LmHook_DestroyTileAnimation3(r2);
+ }
- uint16 r0w = kOwEventProcess01_DestroyTileAnimation_DATA_04E587[(uint16)(2 * ow_destroy_tile_event_vramindex) >> 1];
uint16 v0 = stripe_image_upload;
if (!sign16(ow_destroy_tile_event_tile_index - 3)) {
- uint16 v1 = 8 * ow_destroy_tile_event_tile_index;
v2 = r0w;
*(uint16 *)&stripe_image_upload_data[v0] = r0w;
v2 += 0x2000;
*(uint16 *)&stripe_image_upload_data[v0 + 8] = v2;
v2 = swap16(v2);
- v2 += 32;
+ v2 = HAS_LM_FEATURE(kLmFeature_DestroyTileAnims) ? LmHook_DestroyTileAnimation2(v2) : v2 + 32;
v2 = swap16(v2);
r0w = v2;
*(uint16 *)&stripe_image_upload_data[v0 + 2] = 768;
*(uint16 *)&stripe_image_upload_data[v0 + 10] = 768;
- *(uint16 *)&stripe_image_upload_data[v0 + 4] = *(uint16 *)(p + v1);
- *(uint16 *)&stripe_image_upload_data[v0 + 12] = *(uint16 *)(p + v1 + 2);
- *(uint16 *)&stripe_image_upload_data[v0 + 6] = *(uint16 *)(p + v1 + 4);
- *(uint16 *)&stripe_image_upload_data[v0 + 14] = *(uint16 *)(p + v1 + 6);
+ *(uint16 *)&stripe_image_upload_data[v0 + 4] = *(uint16 *)(p + 0);
+ *(uint16 *)&stripe_image_upload_data[v0 + 12] = *(uint16 *)(p + 2);
+ *(uint16 *)&stripe_image_upload_data[v0 + 6] = *(uint16 *)(p + 4);
+ *(uint16 *)&stripe_image_upload_data[v0 + 14] = *(uint16 *)(p + 6);
v0 += 16;
+ if (HAS_LM_FEATURE(kLmFeature_DestroyTileAnims))
+ p = LmHook_DestroyTileAnimation3(LmHook_RemapDestroyTile(r2));
}
- uint16 v5;
- if (sign16(ow_destroy_tile_event_tile_index - 2))
- v5 = 8 * ow_destroy_tile_event_tile_index;
- else
- v5 = 40;
- OwEventProcess01_DestroyTileAnimation_04EDE6(v0, v5, r0w, p);
+ if (!HAS_LM_FEATURE(kLmFeature_DestroyTileAnims)) {
+ p = kOverworldEventProcess01_DestroyTileAnimation_DATA_04EE7A +
+ (sign16(ow_destroy_tile_event_tile_index - 2) ? 8 * ow_destroy_tile_event_tile_index : 40);
+ }
+ OwEventProcess01_DestroyTileAnimation_04EDE6(v0, r0w, p);
}
void DrawFlyingSwitchBlocks() { // 04f290
@@ -2446,7 +2473,7 @@ LABEL_6:;
LOBYTE(stripe_image_upload) = stripe_image_upload + 80;
uint8 v5 = stripe_image_upload;
do
- stripe_image_upload_data[v5--] = kLifeExchangeText_Mario[(uint8)v4--];
+ stripe_image_upload_data[v5--] = kOwLifeExchangeTextTiles[(uint8)v4--];
while (v4 >= 0);
uint8 v6 = v5 + 1;
if ((players_lives[0] & 0x80) == 0) {
@@ -2482,15 +2509,16 @@ void OwPrompt03_OverworldLifeExchanger_04F60E(uint8 k, uint8 j, uint8 a) { // 0
void LoadOverworldSprites() { // 04f675
uint8 v0 = 12;
uint8 v1 = 15;
+ SpriteSlotData *ssd = (SpriteSlotData *)kLoadOverworldSprites_SpriteSlotData;
do {
- int8 v2 = kLoadOverworldSprites_SpriteSlotData[v1 - 3].field_0;
+ int8 v2 = ssd[v1 - 3].field_0;
owspr_spriteid[v0 + 3] = v2;
if (v2 == 1 || v2 == 2)
owspr_zpos_lo[v0 + 3] = 64;
- owspr_xpos_lo[v0 + 3] = kLoadOverworldSprites_SpriteSlotData[v1 - 3].field_1;
- owspr_xpos_hi[v0 + 3] = HIBYTE(kLoadOverworldSprites_SpriteSlotData[v1 - 3].field_1);
- owspr_ypos_lo[v0 + 3] = kLoadOverworldSprites_SpriteSlotData[v1 - 3].field_3;
- owspr_ypos_hi[v0 + 3] = HIBYTE(kLoadOverworldSprites_SpriteSlotData[v1 - 3].field_3);
+ owspr_xpos_lo[v0 + 3] = ssd[v1 - 3].field_1;
+ owspr_xpos_hi[v0 + 3] = HIBYTE(ssd[v1 - 3].field_1);
+ owspr_ypos_lo[v0 + 3] = ssd[v1 - 3].field_3;
+ owspr_ypos_hi[v0 + 3] = HIBYTE(ssd[v1 - 3].field_3);
--v1;
--v0;
} while ((v0 & 0x80) == 0);
@@ -2879,8 +2907,8 @@ void OWSpr07_Smoke(uint8 k) { // 04fc46
uint8 v1 = ow_players_map[(uint8)player_current_characterx4 >> 2];
owspr_xpos_lo[k] = kOWSpr07_Smoke_DATA_04FC1E[v1];
owspr_xpos_hi[k] = HIBYTE(kOWSpr07_Smoke_DATA_04FC1E[v1]);
- owspr_ypos_lo[k] = kOWSpr07_Smoke_DATA_04FC22[v1];
- owspr_ypos_hi[k] = HIBYTE(kOWSpr07_Smoke_DATA_04FC22[v1]);
+ owspr_ypos_lo[k] = kOWSpr07_Smoke_DATA_04FC1E[v1 + 2];
+ owspr_ypos_hi[k] = HIBYTE(kOWSpr07_Smoke_DATA_04FC1E[v1 + 2]);
if ((counter_global_frames & 0xF) == 0) {
uint8 v2 = owspr_table0df5[k] + 1;
if (v2 >= 0xC)
@@ -2965,14 +2993,15 @@ void OWSpr0A_Boo(uint8 k) { // 04fd70
if (ow_players_map[player_current_character]) {
if (k == 15 && (ow_event_flags[5] & 0x12) == 0)
HIBYTE(pt.y) = 15;
- pt.x += *(uint16 *)&kLoadOverworldSprites_SubmapBooXPosOffset[(uint8)(2 * k) - 26];
- pt.y += *(uint16 *)&kLoadOverworldSprites_SubmapBooYPosOffset[(uint8)(2 * k) - 26];
+ pt.x += kLoadOverworldSprites_SubmapBooXPosOffset[k - 13];
+ pt.y += kLoadOverworldSprites_SubmapBooYPosOffset[k - 13];
}
int8 v1 = 52;
if ((owspr_xspeed[k] & 0x80) == 0)
v1 = 68;
HIBYTE(v2) = v1;
LOBYTE(v2) = 96;
+
OWSpr04_PiranhaPlant_GenericOverworldSpriteDraw(k, v2, pt);
uint8 r0 = owspr_table0e25[k]++;
OWSpr0A_Boo_04FDD2(k + 32, 8, r0);
@@ -3024,6 +3053,7 @@ uint16 GetOverworldSpriteOnScreenPosition_Y(uint8 k, uint8 j) { // 04fe7d
int16 v2;
HIBYTE(v2) = owspr_xpos_hi[k];
LOBYTE(v2) = owspr_xpos_lo[k];
+
return v2 - *(uint16 *)((int8 *)&mirror_current_layer1_xpos + j);
}
diff --git a/src/smw_05.c b/src/smw_05.c
index 5ffe557..b2c5495 100644
--- a/src/smw_05.c
+++ b/src/smw_05.c
@@ -214,16 +214,18 @@ static const uint8 kLoadLevelHeader_LevCGADSUBtable[32] = { 0x24, 0x24, 0x24, 0x
static const uint8 kLoadLevelHeader_SpecialLevTable[32] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, };
static const uint8 kLoadLevelHeader_LevXYPPCCCTtbl[32] = { 0x20, 0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, };
static const uint8 kLoadLevelHeader_TimerTable[4] = { 0x0, 0x2, 0x3, 0x4, };
-static const uint8 kLoadLevelHeader_LevelMusicTable[8] = { 0x2, 0x6, 0x1, 0x8, 0x7, 0x3, 0x5, 0x12, };
-static const uint16 kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[4] = { 0x8ab0, 0x84e0, 0x8af0, 0x8b30, };
+
+const uint16 kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[4] = { 0x8ab0, 0x84e0, 0x8af0, 0x8b30, };
+
static const uint16 kDisplayMessage_DATA_05A580[8] = { 0xa751, 0x8751, 0x6751, 0x4751, 0x2751, 0x751, 0xe750, 0xc750, };
static const uint8 kDisplayMessage_DATA_05A590[23] = { 0x14, 0x45, 0x3f, 0x8, 0x0, 0x29, 0xaa, 0x27, 0x26, 0x84, 0x95, 0xa9, 0x15, 0x13, 0xce, 0xa7, 0xa4, 0x25, 0xa5, 0x5, 0xa6, 0x2a, 0x28, };
static const uint16 kDisplayMessage_DATA_05A5A7[25] = { 0x8d, 0x8d, 0x8d, 0x8d, 0x0, 0x291, 0x41d, 0x518, 0x61d, 0x8b7, 0x7b2, 0x30b, 0x83c, 0x99d, 0xa9e, 0x4a0, 0xa2c, 0x6a6, 0x730, 0x911, 0x5a4, 0x38f, 0x109, 0x20a, 0x191, };
static const uint8 kDisplayMessage_DATA_05B106[2] = { 0x4c, 0x50, };
static const uint8 kDisplayMessage_DATA_05B108[2] = { 0x50, 0x0, };
static const uint8 kDisplayMessage_DATA_05B10A[2] = { 0x4, 0xfc, };
-static const uint16 kDisplayMessage_SwitchBlockTileAndProperties[32] = { 0x35ad, 0x75ad, 0xb5ad, 0xf5ad, 0x35a7, 0x75a7, 0x35b7, 0x75b7, 0x37bd, 0x77bd, 0xb7bd, 0xf7bd, 0x37a7, 0x77a7, 0x37b7, 0x77b7, 0x39ad, 0x79ad, 0xb9ad, 0xf9ad, 0x39a7, 0x79a7, 0x39b7, 0x79b7, 0x3bbd, 0x7bbd, 0xbbbd, 0xfbbd, 0x3ba7, 0x7ba7, 0x3bb7, 0x7bb7, };
-static const uint8 kDisplayMessage_SwitchBlockXAndYDisp[16] = { 0x50, 0x4f, 0x58, 0x4f, 0x50, 0x57, 0x58, 0x57, 0x92, 0x4f, 0x9a, 0x4f, 0x92, 0x57, 0x9a, 0x57, };
+
+const uint16 kDisplayMessage_SwitchBlockTileAndProperties[32] = { 0x35ad, 0x75ad, 0xb5ad, 0xf5ad, 0x35a7, 0x75a7, 0x35b7, 0x75b7, 0x37bd, 0x77bd, 0xb7bd, 0xf7bd, 0x37a7, 0x77a7, 0x37b7, 0x77b7, 0x39ad, 0x79ad, 0xb9ad, 0xf9ad, 0x39a7, 0x79a7, 0x39b7, 0x79b7, 0x3bbd, 0x7bbd, 0xbbbd, 0xfbbd, 0x3ba7, 0x7ba7, 0x3bb7, 0x7bb7, };
+const uint8 kDisplayMessage_SwitchBlockXAndYDisp[16] = { 0x50, 0x4f, 0x58, 0x4f, 0x50, 0x57, 0x58, 0x57, 0x92, 0x4f, 0x9a, 0x4f, 0x92, 0x57, 0x9a, 0x57, };
const uint8 kBitTable_Bank05[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, };
// todo: oob read
static const uint8 kLevelTileAnimations_DATA_05B96B[24] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 2, 0, 0, 0, 0, 0, };
@@ -319,11 +321,12 @@ void LoadSublevel() { // 05801e
blocks_layer2_tiles_lo[i + 512] = 37;
}
blocks_screen_to_place_current_object = 0;
+ lm_varB = ptr_layer2_is_bg;
if (ptr_layer2_is_bg & 2) {
- uint8 v1 = ptr_layer2_is_bg >> 4;
- for (uint16 j = 0; j != 512; ++j) {
- blocks_layer2_tiles_hi[j] = v1;
- blocks_layer2_tiles_hi[j + 512] = v1;
+ if (!(ptr_layer2_is_bg & 4)) {
+ uint8 v1 = ptr_layer2_is_bg >> 4;
+ for (uint16 j = 0; j != 1024; ++j)
+ blocks_layer2_tiles_hi[j] = v1;
}
unusedram_copy_of_level_tileset_setting = 0;
misc_level_tileset_setting = 0;
@@ -343,24 +346,34 @@ void InitializeLevelLayer1And2Tilemaps() { // 05809e
blocks_screen_to_place_current_object = 0;
camera_xy_layer1_vramupd_left_up = -1;
camera_xy_layer1_vramupd_right_down = -1;
+ if (g_lunar_magic)
+ LmHook_InitializeLevelLayer1And2Tilemaps();
CalculateRowOrColumnOfTilemapToUpdate();
camera_layer1_row_column_to_update_right_down = camera_layer1_row_column_to_update_left_up;
camera_layer2_row_column_to_update_right_down = camera_layer2_row_column_to_update_left_up;
*(uint16 *)&camera_layer1_scrolling_direction = 514;
do {
- BufferScrollingTiles_Layer1_Init();
- BufferScrollingTiles_Layer2_Init();
- UploadLevelLayer1And2Tilemaps();
- ++camera_layer1_row_column_to_update_right_down;
- ++camera_layer2_row_column_to_update_right_down;
- uint16 v0 = 614;
- uint16 R0_W = 7;
- uint16 v1 = kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[(camera_layer1_row_column_to_update_right_down >> 4) & 3];
- do {
- pointer_map16_tiles[v0 >> 1] = v1;
- v0 += 2;
- v1 += 8;
- } while ((--R0_W & 0x8000) == 0);
+ if (g_lunar_magic) {
+ LmHook_BufferTilemap_L1();
+ LmHook_BufferTilemap_L2();
+ LmHook_UploadLevelLayer1And2Tilemaps();
+ ++camera_layer1_row_column_to_update_right_down;
+ ++camera_layer2_row_column_to_update_right_down;
+ } else {
+ BufferScrollingTiles_Layer1_Init();
+ BufferScrollingTiles_Layer2_Init();
+ UploadLevelLayer1And2Tilemaps();
+ ++camera_layer1_row_column_to_update_right_down;
+ ++camera_layer2_row_column_to_update_right_down;
+ uint16 v0 = 614;
+ uint16 R0_W = 7;
+ uint16 v1 = kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[(camera_layer1_row_column_to_update_right_down >> 4) & 3];
+ do {
+ pointer_map16_tiles[v0 >> 1] = v1;
+ v0 += 2;
+ v1 += 8;
+ } while ((--R0_W & 0x8000) == 0);
+ }
++blocks_screen_to_place_current_object;
} while (blocks_screen_to_place_current_object != 32);
uint8 v2 = mirror_main_screen_layers;
@@ -518,10 +531,17 @@ uint16 InitializeLevelData_Hi(uint16 k, uint8 a) { // 05833a
extern Snes *g_snes;
void BeginLoadingLevelData() { // 0583ac
+ if (g_lunar_magic)
+ LmHook_InitExanimForLevel();
+
LOBYTE(misc_current_layer_being_processed) = 0;
LoadLevelHeader();
InitializeMap16Pointers();
- while (misc_level_mode_setting != 9 && misc_level_mode_setting != 11 && misc_level_mode_setting != 16) {
+ for(;;) {
+ if (g_lunar_magic)
+ LmHook_BeginLoadingLevelDataB();
+ if (misc_level_mode_setting == 9 || misc_level_mode_setting == 11 || misc_level_mode_setting == 16)
+ break;
if (*ptr_layer1_data != 0xFF)
LoadLevelDataObject();
if (misc_level_mode_setting == 0 || misc_level_mode_setting == 10 || misc_level_mode_setting == 12 ||
@@ -560,11 +580,16 @@ void LoadLevelHeader() { // 0584e3
uint8 r0 = hdr[2];
graphics_level_sprite_graphics_setting = r0 & 0xF;
uint8 v3 = kLoadLevelHeader_LevelMusicTable[(r0 >> 4) & 7];
- if ((misc_music_register_backup & 0x80) != 0)
- v3 |= 0x80;
- if (v3 == misc_music_register_backup)
- v3 |= 0x40;
- misc_music_register_backup = v3;
+ if (HAS_LM_FEATURE(kLmFeature_MusicRegTweak)) {
+ if (misc_game_mode >= 7)
+ misc_music_register_backup = v3;
+ } else {
+ if ((misc_music_register_backup & 0x80) != 0)
+ v3 |= 0x80;
+ if (v3 == misc_music_register_backup)
+ v3 |= 0x40;
+ misc_music_register_backup = v3;
+ }
mirror_bgmode_and_tile_size_setting = ((uint8)(r0 & 0x80) >> 4) | 1;
r0 = hdr[3];
if (!counter_sublevels_entered) {
@@ -632,6 +657,11 @@ void LoadLevelDataObject() { // 0585ff
void CheckIfLevelTilemapsNeedScrollUpdate() { // 0586f1
uint16 v0, v1, v2, v3;
CalculateRowOrColumnOfTilemapToUpdate();
+ if (g_lunar_magic) {
+ LmHook_CheckIfLevelTilemapsNeedScrollUpdate();
+ return;
+ }
+
if ((misc_level_layout_flags & 1) != 0) {
v0 = camera_layer1_scrolling_direction;
v1 = mirror_current_layer1_ypos & 0xFFF0;
@@ -675,15 +705,18 @@ void CalculateRowOrColumnOfTilemapToUpdate() { // 05877e
} else {
camera_layer1_row_column_to_update_left_up = (mirror_current_layer1_xpos >> 4) - 8;
camera_layer1_row_column_to_update_right_down = (mirror_current_layer1_xpos >> 4) + 23;
- uint16 v0 = (*((uint8 *)&camera_layer1_row_column_to_update_left_up + camera_layer1_scrolling_direction) >> 3) & 6;
- uint16 v1 = 614;
- uint16 R0_W = 7;
- uint16 v2 = kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[v0 >> 1];
- do {
- pointer_map16_tiles[v1 >> 1] = v2;
- v1 += 2;
- v2 += 8;
- } while ((--R0_W & 0x8000) == 0);
+
+ if (!g_lunar_magic) {
+ uint16 v0 = (*((uint8 *)&camera_layer1_row_column_to_update_left_up + camera_layer1_scrolling_direction) >> 3) & 6;
+ uint16 v1 = 614;
+ uint16 R0_W = 7;
+ uint16 v2 = kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[v0 >> 1];
+ do {
+ pointer_map16_tiles[v1 >> 1] = v2;
+ v1 += 2;
+ v2 += 8;
+ } while ((--R0_W & 0x8000) == 0);
+ }
}
if ((misc_level_layout_flags & 2) != 0) {
camera_layer2_row_column_to_update_left_up = (mirror_current_layer2_ypos >> 4) - 8;
@@ -730,7 +763,7 @@ static const uint16 kLevelDataLayout_StdVert[] = {
0xe400, 0xe600, 0xe800, 0xea00, 0xec00, 0xee00, 0xf000, 0xf200, 0xf400, 0xf600, 0xf800, 0xfa00, 0xfc00, 0xfe00,
};
-static const uint16 *const kLevelDataLayoutTables_Layer1LoPtrs[32] = {
+const uint16 *const kLevelDataLayoutTables_Layer1LoPtrs[32] = {
kLevelDataLayout_StdHoriz,
kLevelDataLayout_StdHoriz,
kLevelDataLayout_StdHoriz,
@@ -804,23 +837,6 @@ const uint16 *GetLayerLayoutPtr(int layer, int top) {
return layer ? kLevelDataLayoutTables_Layer2LoPtrs[top] : kLevelDataLayoutTables_Layer1LoPtrs[top];
}
-const uint16 *GetMap16RomAddr(uint8 bank, uint16_t addr) {
- if (bank == 13) {
- if (addr >= 0xe300)
- return (uint16 *)((const uint8 *)kMap16Data_GhostHouse + addr - 0xe300);
- else if (addr >= 0xd400)
- return (uint16 *)((const uint8 *)kMap16Data_Underground + addr - 0xd400);
- else if (addr >= 0xc800)
- return (uint16 *)((const uint8 *)kMap16Data_Rope + addr - 0xc800);
- else if (addr >= 0xbc00)
- return (uint16 *)((const uint8 *)kMap16Data_Castle + addr - 0xbc00);
- else
- return (uint16 *)((const uint8 *)kMap16Data + addr - 0x8000);
- }
- assert(addr >= 0xd000 && addr < 0xd608);
- return (uint16*)((const uint8 *)kMap16Data_OverworldLayer1 + addr - 0xd000);
-}
-
void BufferScrollingTiles_Layer1() { // 0589ce
uint16 v0 = camera_layer1_scrolling_direction;
HIBYTE(blocks_layer1_vramupload_address) = 2 * (*((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0xF);
@@ -828,7 +844,8 @@ void BufferScrollingTiles_Layer1() { // 0589ce
if ((*((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0x10) != 0)
v1 = 36;
LOBYTE(blocks_layer1_vramupload_address) = v1;
- uint16 R0_W = (uint16)(*(uint16 *)((int8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0x1F0) >> 4;
+ uint16 lm_mask = g_lunar_magic ? 0x3ff0 : 0x1f0;
+ uint16 R0_W = (uint16)(*(uint16 *)((int8 *)&camera_layer1_row_column_to_update_left_up + v0) & lm_mask) >> 4;
const uint8 *plo = g_ram + kLevelDataLayoutTables_Layer1LoPtrs[misc_level_mode_setting][R0_W];
uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5;
uint16 r8 = *((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0xF;
@@ -836,7 +853,7 @@ void BufferScrollingTiles_Layer1() { // 0589ce
do {
uint16 v5 = r8;
R0_W = plo[v5] | plo[v5 + 0x10000] << 8;
- const uint16 *r10t = GetMap16RomAddr(bank, pointer_map16_tiles[R0_W]);
+ const uint16 *r10t = Lm_GetMap16RomAddr(R0_W);
int v6 = v4 >> 1;
blocks_layer1_tiles_to_upload_buffer[v6] = r10t[0];
blocks_layer1_tiles_to_upload_buffer[v6 + 1] = r10t[1];
@@ -863,7 +880,8 @@ void BufferScrollingTiles_Layer1_VerticalLevel() { // 058a9b
v1 = 40;
LOBYTE(blocks_layer1_vramupload_address) = v1 | (*((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) >> 2) & 3;
HIBYTE(blocks_layer1_vramupload_address) = (*((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) & 3) << 6;
- uint16 R0_W = (uint16)(*(uint16 *)((int8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0x1F0) >> 4;
+ uint16 lm_mask = g_lunar_magic ? 0x3ff0 : 0x1f0;
+ uint16 R0_W = (uint16)(*(uint16 *)((int8 *)&camera_layer1_row_column_to_update_left_up + v0) & lm_mask) >> 4;
uint16 v2 = (R0_W < max_n) ? R0_W : 0;
const uint8 *plo = g_ram + r10[v2];
uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5;
@@ -873,7 +891,7 @@ void BufferScrollingTiles_Layer1_VerticalLevel() { // 058a9b
uint16 v5 = r8;
R0_W = plo[r8] | plo[v5 + 0x10000] << 8;
- const uint16 *r10p = GetMap16RomAddr(bank, pointer_map16_tiles[R0_W]);
+ const uint16 *r10p = Lm_GetMap16RomAddr(R0_W);
int v6 = v4 >> 1;
blocks_layer1_tiles_to_upload_buffer[v6] = r10p[0];
blocks_layer1_tiles_to_upload_buffer[v6 + 64] = r10p[1];
@@ -902,7 +920,8 @@ void BufferScrollingTiles_Layer2() { // 058b8d
if ((*((uint8 *)&camera_layer2_row_column_to_update_left_up + v0) & 0x10) != 0)
v2 = 52;
LOBYTE(blocks_layer2_vramupload_address) = v2;
- uint16 R0_W = (uint16)(*(uint16 *)((int8 *)&camera_layer2_row_column_to_update_left_up + v0) & 0x1F0) >> 4;
+ uint16 lm_mask = g_lunar_magic ? 0x3ff0 : 0x1f0;
+ uint16 R0_W = (uint16)(*(uint16 *)((int8 *)&camera_layer2_row_column_to_update_left_up + v0) & lm_mask) >> 4;
const uint8 *plo = g_ram + r10[R0_W];
uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5;
@@ -911,7 +930,7 @@ void BufferScrollingTiles_Layer2() { // 058b8d
do {
uint16 v6 = r8;
R0_W = plo[r8] | plo[v6 + 0x10000] << 8;
- const uint16 *r10w = GetMap16RomAddr(bank, pointer_map16_tiles[R0_W]);
+ const uint16 *r10w = Lm_GetMap16RomAddr(R0_W);
int v7 = v5 >> 1;
blocks_layer2_tiles_to_upload_buffer[v7] = R3_W | r10w[0];
blocks_layer2_tiles_to_upload_buffer[v7 + 1] = R3_W | r10w[1];
@@ -943,7 +962,8 @@ void BufferScrollingTiles_Layer2_VerticalLevel() { // 058c71
v3 = 56;
LOBYTE(blocks_layer2_vramupload_address) = v3 | (*((uint8 *)&camera_layer2_row_column_to_update_left_up + v1) >> 2) & 3;
HIBYTE(blocks_layer2_vramupload_address) = (*((uint8 *)&camera_layer2_row_column_to_update_left_up + v1) & 3) << 6;
- uint16 R0_W = (uint16)(*(uint16 *)((int8 *)&camera_layer2_row_column_to_update_left_up + v1) & 0x1F0) >> 4;
+ uint16 lm_mask = g_lunar_magic ? 0x3ff0 : 0x1f0;
+ uint16 R0_W = (uint16)(*(uint16 *)((int8 *)&camera_layer2_row_column_to_update_left_up + v1) & lm_mask) >> 4;
uint16 v4 = (R0_W < max_n) ? R0_W : 0;
const uint8 *plo = g_ram + r10[v4];
uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5;
@@ -952,7 +972,7 @@ void BufferScrollingTiles_Layer2_VerticalLevel() { // 058c71
do {
uint16 v7 = r8;
R0_W = plo[r8] | plo[r8 + 0x10000] << 8;
- const uint16 *r10w = GetMap16RomAddr(bank, pointer_map16_tiles[R0_W]);
+ const uint16 *r10w = Lm_GetMap16RomAddr(R0_W);
int v8 = v6 >> 1;
blocks_layer2_tiles_to_upload_buffer[v8] = R3_W | r10w[0];
blocks_layer2_tiles_to_upload_buffer[v8 + 64] = R3_W | r10w[1];
@@ -975,11 +995,16 @@ void BufferScrollingTiles_Layer2_Background() { // 058d7a
LOBYTE(blocks_layer2_vramupload_address) = v0;
const uint8 *phi = g_ram + 0xbd00, *plo = g_ram + 0xb900;
+ //; // kMap16Data_Backgrounds
+ const uint8 *r10 = (const uint8 *)kMap16Data + 0x1100;
+ if (g_lunar_magic)
+ r10 = (uint8*)LmHook_CustomBgMap16();
+
if ((blocks_screen_to_place_current_object & 0xF0) != 0) {
plo += 432;
phi += 432;
}
- const uint8 *r10 = (const uint8 *)kMap16Data + 0x1100; // kMap16Data_Backgrounds
+
uint16 r8 = blocks_screen_to_place_current_object & 0xF;
uint16 v1 = 0;
do {
@@ -1013,7 +1038,7 @@ void DisplayMessage() { // 05b10c
mirror_color_math_initial_settings = 2;
return;
}
- if (misc_color_of_palace_switch_pressed1 | misc_intro_level_flag && timer_title_screen_input_timer) {
+ if ((misc_color_of_palace_switch_pressed1 | misc_intro_level_flag) && timer_title_screen_input_timer) {
if ((counter_global_frames & 3) != 0)
return;
if (--timer_title_screen_input_timer)
@@ -1029,7 +1054,8 @@ void DisplayMessage() { // 05b10c
(((io_controller_press1 ^ io_controller_hold1 & 0xF0) & 0xF0) == 0 ||
(io_controller_hold2 & 0xC0) != 0 && ((io_controller_press2 ^ io_controller_hold2 & 0xC0) & 0xC0) == 0)) {
if (misc_intro_level_flag) {
- LOBYTE(get_PointU16(ow_players_pos, 0)->y) = -114;
+ if (!HAS_LM_FEATURE(kLmFeature_DontSetYposForIntroMarch))
+ LOBYTE(get_PointU16(ow_players_pos, 0)->y) = -114;
DisplayMessage_ExitToOverworldNoEvent();
} else {
++flag_message_window_size_change_direction;
@@ -1040,6 +1066,8 @@ void DisplayMessage() { // 05b10c
if (flag_message_window_size_change_direction) {
DisplayMessage_RemoveSwitchBlocks();
graphics_stripe_image_to_upload = 9;
+ } else if (HAS_LM_FEATURE(kLmFeature_CustomDisplayMessage)) {
+ LmHook_DisplayMessage();
} else {
uint8 v0 = 22;
do {
@@ -1093,6 +1121,7 @@ void DisplayMessage() { // 05b10c
mirror_layer3_ypos = 0;
}
}
+
timer_wait_before_message_window_size_change += kDisplayMessage_DATA_05B10A[flag_message_window_size_change_direction];
HIBYTE(v7) = timer_wait_before_message_window_size_change + 0x80;
LOBYTE(v7) = 0x80 - timer_wait_before_message_window_size_change;
@@ -1166,7 +1195,7 @@ uint8 UnusedOverworldEventPassedCheck(uint8 j) { // 05b363
return kBitTable_Bank05[j & 7] & ow_event_flags[j >> 3];
}
-static const kLevelTileAnimationsAddrs[] = {
+static const uint16 kLevelTileAnimationsAddrs[] = {
0x600, 0x640, 0x680,
0x740, 0xEA0, 0x800,
0x500, 0x540, 0x580,
@@ -2299,72 +2328,27 @@ void GiveTimeBonusAndBonusStars_Return() { // 05cfe9
;
}
-// If we don't use the exact right id for the sprite list the snapshot load will fail.
-#define E(a, b) (a) | (b) << 20
-static const uint32 kSpriteListPtrToIndex[] = {
- E(0x7c340, 0x9b), E(0x7c345, 0x9a), E(0x7c34a, 0x99), E(0x7c34f, 0x98), E(0x7c354, 0x97), E(0x7c359, 0x96), E(0x7c367, 0x95), E(0x7c3db, 0x93),
- E(0x7c3e3, 0x94), E(0x7c3ee, 0xbd), E(0x7c3f0, 0xc6), E(0x7c3f5, 0xc4), E(0x7c407, 0x0), E(0x7c40c, 0xeb), E(0x7c414, 0xd5), E(0x7c422, 0x10d),
- E(0x7c427, 0xc7), E(0x7c441, 0xc5), E(0x7c446, 0x14), E(0x7c44b, 0xca), E(0x7c450, 0x11b), E(0x7c473, 0x1d8), E(0x7c478, 0x121), E(0x7c498, 0x1d7),
- E(0x7c49d, 0x8), E(0x7c4c0, 0xc9), E(0x7c4c5, 0x3), E(0x7c4ca, 0x105), E(0x7c532, 0x106), E(0x7c57f, 0x1ca), E(0x7c593, 0x103), E(0x7c5ef, 0x1fd),
- E(0x7c5f4, 0x102), E(0x7c659, 0x1ff), E(0x7c661, 0x1be), E(0x7c66f, 0x101), E(0x7c6bf, 0x1fc), E(0x7c6d0, 0x1f6), E(0x7c6d5, 0x15), E(0x7c749, 0xe3),
- E(0x7c751, 0x9), E(0x7c7a7, 0xe9), E(0x7c7b5, 0x4), E(0x7c7bd, 0xde), E(0x7c7cb, 0xfe), E(0x7c7d9, 0x5), E(0x7c844, 0x6), E(0x7c8cd, 0xd2),
- E(0x7c8ea, 0xc3), E(0x7c904, 0x7), E(0x7c915, 0xe8), E(0x7c926, 0xe7), E(0x7c943, 0xe5), E(0x7c948, 0xa), E(0x7c9aa, 0xc2), E(0x7c9ca, 0x13),
- E(0x7c9db, 0xed), E(0x7c9f2, 0xf1), E(0x7ca0c, 0xe4), E(0x7ca17, 0x10b), E(0x7ca6d, 0x1c6), E(0x7ca87, 0x11a), E(0x7cb01, 0x1ef), E(0x7cb2a, 0x118),
- E(0x7cbc5, 0x1c3), E(0x7cbdc, 0x107), E(0x7cc11, 0x1ea), E(0x7cc25, 0x10a), E(0x7ccba, 0x1c2), E(0x7ccd4, 0x119), E(0x7cd63, 0x1f5), E(0x7cd68, 0x11c),
- E(0x7cd94, 0x1f3), E(0x7cdc0, 0x1f2), E(0x7cdc8, 0x109), E(0x7ce0c, 0x1f1), E(0x7ce14, 0x1f0), E(0x7ce1c, 0x1), E(0x7ceba, 0xd8), E(0x7cebf, 0x2),
- E(0x7cf06, 0xb), E(0x7cf4d, 0xe0), E(0x7cfaf, 0xf), E(0x7d02f, 0xbf), E(0x7d043, 0x10), E(0x7d0cf, 0xc1), E(0x7d0d7, 0xe), E(0x7d0f4, 0xdc),
- E(0x7d111, 0xdb), E(0x7d152, 0xd9), E(0x7d157, 0x11), E(0x7d1f5, 0xc), E(0x7d25a, 0xd), E(0x7d304, 0xdd), E(0x7d30c, 0x11e), E(0x7d380, 0x120),
- E(0x7d445, 0x123), E(0x7d4c5, 0x1f8), E(0x7d4cd, 0x20), E(0x7d51d, 0xcc), E(0x7d522, 0x11d), E(0x7d56c, 0x1fa), E(0x7d577, 0x11f), E(0x7d5c7, 0x1df),
- E(0x7d5cf, 0x1c1), E(0x7d5f5, 0x122), E(0x7d648, 0x1f), E(0x7d668, 0xd6), E(0x7d6d9, 0x22), E(0x7d741, 0xbe), E(0x7d74c, 0x21), E(0x7d799, 0xfc),
- E(0x7d7bf, 0x24), E(0x7d7e5, 0xcf), E(0x7d7ea, 0x205), E(0x7d825, 0x206), E(0x7d84b, 0xce), E(0x7d86e, 0x208), E(0x7d888, 0x209), E(0x7d899, 0xcd),
- E(0x7d8a1, 0x202), E(0x7d8be, 0x23), E(0x7d956, 0xd7), E(0x7d95e, 0x1b), E(0x7d9b1, 0xef), E(0x7d9ef, 0x117), E(0x7da12, 0x1ed), E(0x7da44, 0x1ec),
- E(0x7da7f, 0x1c0), E(0x7da93, 0x1d), E(0x7dadd, 0xea), E(0x7db0f, 0x1c), E(0x7db95, 0xc0), E(0x7dbbb, 0x1a), E(0x7dbf9, 0xd4), E(0x7dc22, 0xd3),
- E(0x7dc2d, 0x18), E(0x7dc3b, 0xf8), E(0x7dc61, 0xf7), E(0x7dd14, 0x116), E(0x7dd76, 0x1e5), E(0x7dd7b, 0x115), E(0x7ddb3, 0x1e3), E(0x7ddb8, 0x1e2),
- E(0x7ddcf, 0xc8), E(0x7de01, 0x114), E(0x7de0f, 0x1dd), E(0x7de3b, 0x1db), E(0x7de4f, 0x113), E(0x7df08, 0x10f), E(0x7df94, 0x1bf), E(0x7dfb1, 0x110),
- E(0x7dfe0, 0x1fe), E(0x7e024, 0x1eb), E(0x7e032, 0x111), E(0x7e067, 0x1d4), E(0x7e08d, 0x1d3), E(0x7e0c5, 0x1d2), E(0x7e0e8, 0x1d1), E(0x7e114, 0x1cf),
- E(0x7e131, 0x1ce), E(0x7e160, 0x1cd), E(0x7e183, 0x1cc), E(0x7e19d, 0x10e), E(0x7e1c0, 0x1c7), E(0x7e1c5, 0x134), E(0x7e221, 0x130), E(0x7e29e, 0x132),
- E(0x7e2af, 0x135), E(0x7e335, 0x136), E(0x7e3dc, 0x12a), E(0x7e402, 0x1c4), E(0x7e428, 0x12b), E(0x7e466, 0x12c), E(0x7e4ec, 0x1c8), E(0x7e4f1, 0x12d),
- E(0x7e574, 0x128), E(0x7e5df, 0x127), E(0x7e650, 0x126), E(0x7e6f4, 0x125), E(0x7e759, 0x104), E(0x7e76d, 0x12),
-};
-#undef E
-
-size_t FindWithBinarySearch(const uint32 *sorted_values, size_t values_size, uint32 value_to_find) {
- size_t low = 0, high = values_size - 1;
- while (low < high) {
- size_t mid = (low + high) >> 1;
- bool pred = (sorted_values[mid] & 0xfffff) < value_to_find;
- low = pred ? mid + 1 : low;
- high = pred ? high : mid;
- }
- if (low == high && (sorted_values[low] & 0xfffff) == value_to_find)
- return sorted_values[low] >> 20;
- return -1;
-}
-
const uint8 *GetSpriteListPtr() {
- uint32 v = Load24(ptr_sprite_list_data);
- int idx = (int)FindWithBinarySearch(kSpriteListPtrToIndex, arraysize(kSpriteListPtrToIndex), v);
- assert(idx != -1);
- const uint8 *bb = kLoadLevelSpriteList(idx).ptr;
- return bb;
+ return kLvlSprBlob(Load24(ptr_sprite_list_data));
}
-void LoadLevel() { // 05d796
+bool LoadLevel() { // 05d796
uint16 v1;
int16 v5;
uint16 v10;
uint16 r14w;
- uint8 R1_ = 0;
+ uint8 r1 = 0;
+ uint8 r2 = 0; // todo: what is R2 here?
flag_override_no_yoshi_intro_for_midway_entrance = 0;
if (in_yoshi_wings_bonus_area || flag_active_bonus_game)
LoadLevel_05DBAC();
if (counter_sublevels_entered) {
- uint8 v0 = HIBYTE(player_xpos);
- if ((misc_level_layout_flags & 1) != 0)
- v0 = HIBYTE(player_ypos);
+ uint8 v0 = ((misc_level_layout_flags & 1) != 0) ? HIBYTE(player_ypos) : HIBYTE(player_xpos);
r14w = (ow_players_map[(uint8)player_current_characterx4 >> 2] != 0) << 8 | misc_subscreen_exit_entrance_number_lo[v0];
+ r14w = LmHook_LoadLevelInfo_A(r14w, v0);
+
if (flag_use_secondary_entrance) {
uint16 j = r14w;
r14w = (r14w & ~0xff) | kLevelInfo_05F800[j];
@@ -2373,10 +2357,17 @@ void LoadLevel() { // 05d796
HIBYTE(player_ypos) = kLoadLevel_DATA_05D740[r0 & 0xF];
LOBYTE(mirror_current_layer1_ypos) = kLoadLevel_DATA_05D708[(r0 & 0x30) >> 4];
LOBYTE(mirror_current_layer2_ypos) = kLoadLevel_DATA_05D70C[r0 >> 6];
- R1_ = kLevelInfo_05FC00[j];
- LOBYTE(player_xpos) = kLoadLevel_DATA_05D750[R1_ >> 5];
- HIBYTE(player_xpos) = kLoadLevel_DATA_05D758[R1_ >> 5];
- misc_level_header_entrance_settings = kLevelInfo_05FE00[j] & 7;
+ r1 = kLevelInfo_05FC00[j];
+ LOBYTE(player_xpos) = kLoadLevel_DATA_05D750[r1 >> 5];
+ HIBYTE(player_xpos) = kLoadLevel_DATA_05D758[r1 >> 5];
+ if (HAS_LM_FEATURE(kLmFeature_LoadLevel)) {
+ int tt = LmHook_LoadLevelInfo_E(j, r14w, r0, r1);
+ if (tt < 0)
+ return true;
+ r2 = tt;
+ } else {
+ misc_level_header_entrance_settings = kLm5FE00[j] & 7;
+ }
}
} else {
v1 = 0;
@@ -2396,17 +2387,25 @@ void LoadLevel() { // 05d796
ow_level_number_lo = v2;
}
if (v2 >= 0x25)
- v2 -= 36;
+ v2 -= 0x24;
r14w = (ow_players_map[(uint8)v1] != 0) << 8 | v2;
+ r14w = LmHook_LoadLevelInfo_C(r14w);
}
+
ptr_layer1_data = kLevelData_Layer1(r14w).ptr;
ptr_layer2_data = kLevelData_Layer2(r14w).ptr;
ptr_layer2_is_bg = kLevelData_Layer2_IsBg[r14w];
+ if (g_lunar_magic)
+ lunar_magic_FE = r14w + 1;
+
HIBYTE(v5) = 0;
- ptr_sprite_list_data = (LongPtr){ .bank = 7, .addr = kLoadLevel_SpriteDataPtrs[r14w] };
+ ptr_sprite_list_data = (LongPtr){
+ .bank = kLmSpritePtrBankByte[r14w],
+ .addr = kLoadLevel_SpriteDataPtrs[r14w]
+ };
uint8 sprite_hdr = *GetSpriteListPtr();
- sprites_sprite_memory_setting = sprite_hdr & 0x3F;
+ sprites_sprite_memory_setting = sprite_hdr & 0x1F;
sprites_sprite_buoyancy_settings = sprite_hdr & 0xC0;
uint8 v6 = kLevelInfo_05F000[r14w] >> 4;
flag_layer2_horiz_scroll_level_setting = kLoadLevel_L2HorzScrollSettings[v6];
@@ -2417,44 +2416,49 @@ void LoadLevel() { // 05d796
HIBYTE(mirror_current_layer2_ypos) = 0;
flag_disable_no_yoshi_intro = kLevelInfo_05F600[r14w] & 0x80;
misc_level_layout_flags = (uint8)(kLevelInfo_05F600[r14w] & 0x60) >> 5;
- uint8 R2_ = 0; // todo: what is R2 here?
if (!flag_use_secondary_entrance) {
v10 = kLevelInfo_05F000[r14w] & 0xF;
player_ypos = PAIR16(kLoadLevel_DATA_05D740[v10], kLoadLevel_DATA_05D730[v10]);
- R2_ = kLevelInfo_05F200[r14w];
- v10 = R2_ & 7;
+ r2 = kLevelInfo_05F200[r14w];
+ v10 = r2 & 7;
player_xpos = PAIR16(kLoadLevel_DATA_05D758[v10], kLoadLevel_DATA_05D750[v10]);
- misc_level_header_entrance_settings = (uint8)(R2_ & 0x38) >> 3;
- R2_ = kLevelInfo_05F400[r14w];
- v10 = R2_ & 3;
+ misc_level_header_entrance_settings = (uint8)(r2 & 0x38) >> 3;
+ LmHook_ExpandLvlHdr(r14w);
+ r2 = kLevelInfo_05F400[r14w];
+ v10 = r2 & 3;
mirror_current_layer2_ypos = kLoadLevel_DATA_05D70C[v10];
- LOBYTE(v10) = (uint8)(R2_ & 0xC) >> 2;
+ LOBYTE(v10) = (uint8)(r2 & 0xC) >> 2;
mirror_current_layer1_ypos = kLoadLevel_DATA_05D708[v10];
- R1_ = kLevelInfo_05F600[r14w];
+ r1 = kLevelInfo_05F600[r14w];
}
+ LmHook_LoadLevel(r14w);
if ((misc_level_layout_flags & 1) != 0) {
HIBYTE(player_ypos) = *ptr_layer1_data & 0x1F;
camera_last_screen_vert = HIBYTE(player_ypos) + 1;
flag_layer1_vert_scroll_level_setting = 1;
}
- if (counter_sublevels_entered || (unusedram_disable_midpoint = R2_ >> 4, flag_got_midpoint = 0,
+ // disable the write to var13CD if LM
+ if (counter_sublevels_entered || ((g_lunar_magic || (lm_var13CD = r2 >> 4)), flag_got_midpoint = 0,
ow_current_event_number = kLoadLevel_DATA_05D608[ow_level_number_lo],
(ow_level_tile_settings[ow_level_number_lo] & 0x40) == 0)) {
- R1_ &= 0x1F;
+ r1 &= 0x1F;
if ((misc_level_layout_flags & 1) != 0) {
- HIBYTE(player_ypos) = R1_;
- HIBYTE(mirror_current_layer1_ypos) = R1_;
+ HIBYTE(player_ypos) = r1;
+ HIBYTE(mirror_current_layer1_ypos) = r1;
if (flag_layer2_vert_scroll_level_setting != 3)
- HIBYTE(mirror_current_layer2_ypos) = R1_;
+ HIBYTE(mirror_current_layer2_ypos) = r1;
flag_layer1_vert_scroll_level_setting = 1;
} else {
- HIBYTE(player_xpos) = R1_;
+ HIBYTE(player_xpos) = r1;
}
} else {
flag_override_no_yoshi_intro_for_midway_entrance = ow_level_tile_settings[ow_level_number_lo] & 0x40;
- HIBYTE(player_xpos) = R2_ >> 4;
+ HIBYTE(player_xpos) = r2 >> 4;
}
uint8 v11;
+
+ LmHook_LoadLevelB(ptr_layer1_data, r2, r14w);
+
if (ow_level_number_lo < 0x52) {
v11 = 4;
uint8 v12 = ptr_layer1_data[4] & 0xF;
@@ -2478,8 +2482,9 @@ void LoadLevel() { // 05d796
LOBYTE(mirror_current_layer2_ypos) = -64;
misc_level_header_entrance_settings = 0;
ptr_sprite_list_data = (LongPtr){ .bank = 7, .addr = 0xc3ee };
+ LmHook_LoadLevelInfo();
uint8 sprite_hdr = *GetSpriteListPtr();
- sprites_sprite_memory_setting = sprite_hdr & 0x3F;
+ sprites_sprite_memory_setting = sprite_hdr & 0x1F;
sprites_sprite_buoyancy_settings = sprite_hdr & 0xC0;
flag_layer2_horiz_scroll_level_setting = 0;
flag_layer2_vert_scroll_level_setting = 0;
@@ -2495,6 +2500,8 @@ void LoadLevel() { // 05d796
LABEL_47:
if (counter_sublevels_entered && !flag_active_bonus_game && ow_level_number_lo == 36)
LoadLevel_HandleChocolateIsland2Gimmick();
+
+ return false;
}
void LoadLevel_HandleChocolateIsland2Gimmick() { // 05daef
@@ -2530,9 +2537,9 @@ void LoadLevel_HandleChocolateIsland2Gimmick() { // 05daef
ptr_sprite_list_data.addr = kChoclateIsland2_SpritePtrs[v3];
ptr_layer2_data = kChoclateIsland2_Layer2(v3).ptr;
ptr_layer2_is_bg = kChoclateIsland2_Layer2_IsBg[v3];
-
+ LmHook_LoadLevelInfo();
uint8 sprite_hdr = *GetSpriteListPtr();
- sprites_sprite_memory_setting = sprite_hdr & 0x7F;
+ sprites_sprite_memory_setting = sprite_hdr & 0x1F;
sprites_sprite_buoyancy_settings = sprite_hdr & 0x80;
}
@@ -2602,3 +2609,4 @@ void Spr07B_GoalTape_GiveBonusStars(uint8 k) { // 07f252
if (counter_bonus_stars_earned == 80)
GivePoints(k, 0xA);
}
+
diff --git a/src/smw_0c.c b/src/smw_0c.c
index 0ec3187..87f0b27 100644
--- a/src/smw_0c.c
+++ b/src/smw_0c.c
@@ -72,8 +72,6 @@ void (*kGameMode19_Cutscene_Ptrs0CCA79[5])(void) = {
};
static const uint16 kBufferCreditsBackgrounds_TilePageModifier[7] = { 0xffff, 0xfeff, 0xfeff, 0xfeff, 0xffff, 0xfeff, 0xfeff, };
-static const uint8 kUpdateCreditsBackground_PARAMS_0C9559[7] = { 0x1, 0x18, 0x0, 0x40, 0x7f, 0x0, 0x4, };
-static const uint8 kUpdateCreditsBackground_PARAMS_0C9560[7] = { 0x1, 0x18, 0x0, 0x44, 0x7f, 0x0, 0x4, };
static const uint8 kGameMode1B_EndingCinema_DATA_0C9EAC[5] = { 0x40, 0x3e, 0xfc, 0x0, 0xff, };
static const uint16 kGameMode1B_EndingCinema_BackgroundChangeHeight[7] = { 0xc0, 0x180, 0x240, 0x300, 0x3c0, 0x480, 0x559, };
static const uint8 kGameMode1B_EndingCinema_PeachOnYoshiOffset[3] = { 0x0, 0xff, 0x0, };
@@ -194,6 +192,7 @@ void BufferCreditsBackgrounds() { // 0c93dd
++*(uint16 *)&blocks_screen_to_place_current_object;
} while (*(uint16 *)&blocks_screen_to_place_current_object != 7);
credits_var65 = 0x5840;
+ LmHook_BufferCreditsBackgrounds();
credits_index = 0;
blocks_screen_to_place_current_object = 0;
UpdateCreditsBackground();
diff --git a/src/smw_0d.c b/src/smw_0d.c
index 16ab91e..d8b4901 100644
--- a/src/smw_0d.c
+++ b/src/smw_0d.c
@@ -302,14 +302,14 @@ void (*kProcessGrasslandObjects_GrasslandPtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
+ &LmStdObj22_DirectMap16,
+ &LmStdObj23,
+ &LmStdObj24,
+ &LmStdObj25,
+ &LmStdObj26_MusicBypass,
+ &LmStdObj27,
+ &LmStdObj28,
+ &LmStdObj29,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
@@ -374,14 +374,14 @@ void (*kProcessCastleObjects_CastlePtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
+ &LmStdObj22_DirectMap16,
+ &LmStdObj23,
+ &LmStdObj24,
+ &LmStdObj25,
+ &LmStdObj26_MusicBypass,
+ &LmStdObj27,
+ &LmStdObj28,
+ &LmStdObj29,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
@@ -443,14 +443,14 @@ void (*kProcessRopeObjects_RopePtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
+ &LmStdObj22_DirectMap16,
+ &LmStdObj23,
+ &LmStdObj24,
+ &LmStdObj25,
+ &LmStdObj26_MusicBypass,
+ &LmStdObj27,
+ &LmStdObj28,
+ &LmStdObj29,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
@@ -516,14 +516,14 @@ void (*kProcessUndergroundObjects_UndergroundPtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
+ &LmStdObj22_DirectMap16,
+ &LmStdObj23,
+ &LmStdObj24,
+ &LmStdObj25,
+ &LmStdObj26_MusicBypass,
+ &LmStdObj27,
+ &LmStdObj28,
+ &LmStdObj29,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
@@ -591,14 +591,14 @@ void (*kProcessGhostHouseObjects_GhostHousePtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
- &RopeObj2E_Unused,
+ &LmStdObj22_DirectMap16,
+ &LmStdObj23,
+ &LmStdObj24,
+ &LmStdObj25,
+ &LmStdObj26_MusicBypass,
+ &LmStdObj27,
+ &LmStdObj28,
+ &LmStdObj29,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
&RopeObj2E_Unused,
@@ -774,8 +774,13 @@ void ExtObj00_ScreenExit(uint8 k) { // 0da512
blocks_object_number = *ptr_layer1_data++;
uint8 v2 = loadlvl_R10 & 0x1F;
misc_subscreen_exit_entrance_number_lo[v2] = blocks_object_number;
- misc_subscreen_exit_properties[v2] = loadlvl_R11 & 1;
- flag_use_secondary_entrance = loadlvl_R11 >> 1;
+ if (g_lunar_magic) {
+ misc_subscreen_exit_properties[v2] = loadlvl_R11 & 0xf;
+ flag_use_secondary_entrance = (loadlvl_R11 >> 1) & 1;
+ } else {
+ misc_subscreen_exit_properties[v2] = loadlvl_R11 & 1;
+ flag_use_secondary_entrance = loadlvl_R11 >> 1;
+ }
}
void ExtObj01_ScreenJump(uint8 k) { // 0da53d
@@ -1049,7 +1054,7 @@ uint8 HandleHorizontalSubScreenCrossingForCurrentObject(uint8 j, uint8 a) { //
uint8 HandleHorizontalSubScreenCrossingForCurrentObject_Entry2(uint8 j) { // 0da95d
uint8 result = j + 1;
if ((result & 0xF) == 0) {
- ptr_lo_map16_data += 0x1b0;
+ ptr_lo_map16_data += (g_lunar_magic ? lm_level_height : 0x1b0);
++blocks_screen_to_place_next_object;
result = blocks_sub_scr_pos & 0xF0;
}
@@ -1098,13 +1103,13 @@ uint8 GoDownRightAndUpdateLevelDataPointerInObjects() { // 0da9b4
}
void GoBackOneScreenAndUpdateLevelDataPointerInObjects() { // 0da9d6
- ptr_lo_map16_data -= 0x1b0;
+ ptr_lo_map16_data -= (g_lunar_magic ? lm_level_height : 0x1b0);
ptr_lo_map16_data_bak = ptr_lo_map16_data;
--blocks_screen_to_place_next_object;
}
void GoForwardOneScreenAndUpdateLevelDataPointerInObjects() { // 0da9ef
- ptr_lo_map16_data += 0x1b0;
+ ptr_lo_map16_data += (g_lunar_magic ? lm_level_height : 0x1b0);
ptr_lo_map16_data_bak = ptr_lo_map16_data;
++blocks_screen_to_place_next_object;
}
diff --git a/src/smw_cpu_infra.c b/src/smw_cpu_infra.c
index bf5ffa2..76a9503 100644
--- a/src/smw_cpu_infra.c
+++ b/src/smw_cpu_infra.c
@@ -3,6 +3,9 @@
#include "snes/snes.h"
#include "variables.h"
#include "funcs.h"
+#include "assets/smw_assets.h"
+
+extern bool g_custom_music;
static const uint32 kPatchedCarrys_SMW[] = {
0xFE1F,
@@ -61,6 +64,10 @@ static const uint32 kPatchedCarrys_SMW[] = {
static uint8 preserved_db;
+static uint32 get_24(uint32 a) {
+ return *(uint32*)SnesRomPtr(a) & 0xffffff;
+}
+
uint32 PatchBugs_SMW1(void) {
if (FixBugHook(0xA33C) || FixBugHook(0xa358) || FixBugHook(0xA378)) {
if (g_cpu->a == 0x0)
@@ -142,15 +149,102 @@ uint32 PatchBugs_SMW1(void) {
} else if (FixBugHook(0x817e)) {
g_cpu->y = g_ram[kSmwRam_APUI02];
return 0x8181;
+ } else if (g_lunar_magic) {
+
+ static uint32 LmFunc_UpdateTilemapC_0, buffer_tilemap_L1_0, buffer_tilemap_L1_1, LmFunc_UpdateTilemapD_1, LmHook_BufferScrollingTiles_L2_1;
+ static uint32 LmHook_HandleStandardLevelCameraScrollD;
+
+ if (!LmFunc_UpdateTilemapC_0) {
+ uint32 LmHook_BufferTilemap_L1 = get_24(0x580BF+1);
+ buffer_tilemap_L1_0 = get_24(LmHook_BufferTilemap_L1 + 0xAB29 - 0xAB15);
+ buffer_tilemap_L1_1 = get_24(LmHook_BufferTilemap_L1 + 0xAB29 - 0xAB15 + 3 * 7);
+
+ uint32 LmHook_CheckIfLevelTilemapsNeedScrollUpdate = get_24(0x586F7 + 1);
+ uint32 LmFunc_UpdateTilemapD = get_24(LmHook_CheckIfLevelTilemapsNeedScrollUpdate + 0xB5D0 - 0xB538);
+ LmFunc_UpdateTilemapD_1 = get_24(LmFunc_UpdateTilemapD + 0xAD41 - 0xAD38 + 3 * 1);
+
+ uint32 LmHook_BufferTilemap_L2 = get_24(0x580C3+1);
+ LmHook_BufferScrollingTiles_L2_1 = get_24(LmHook_BufferTilemap_L2 + 0xAB9D - 0xAB89 + 3 * 1);
+
+ uint32 LmFunc_UpdateTilemapC = get_24(LmHook_CheckIfLevelTilemapsNeedScrollUpdate + 0xB5A9 + 1 - 0xB538);
+ LmFunc_UpdateTilemapC_0 = get_24(LmFunc_UpdateTilemapC + 0xACD8 - 0xACCF + 3 * 1);
+
+ LmHook_HandleStandardLevelCameraScrollD = get_24(0xF70D + 1);
+ }
+
+ if (FixBugHook(LmFunc_UpdateTilemapC_0 + 0xAE7B - 0xAE28)) {
+ g_cpu->a &= 0xf;
+ } else if (FixBugHook(LmHook_HandleStandardLevelCameraScrollD + 0xBB7C - 0xBB6B)) {
+ if (sign16(g_cpu->a))
+ g_cpu->a = 0;
+ } else if (FixBugHook(buffer_tilemap_L1_0 + 0xAFEE - 0xAFCF) ||
+ FixBugHook(buffer_tilemap_L1_1 + 0xB099 - 0xB07A) ||
+ FixBugHook(LmHook_BufferScrollingTiles_L2_1 + 0xB11E - 0xB0EE)) {
+ if (sign16(g_cpu->a))
+ return buffer_tilemap_L1_1 + 0xB0EB - 0xB07A;
+ } else if (FixBugHook(LmFunc_UpdateTilemapD_1 + 0xB2B4 - 0xB28B)) {
+ static const uint16 kLm10B483[2] = {0, 14};
+ g_cpu->a = kLm10B483[lm_arr1831b[3] >> 1] + ((int16)mirror_current_layer2_ypos >> 4);
+ if (sign16(g_cpu->a))
+ return LmFunc_UpdateTilemapD_1 + 0xB33E - 0xB28B;
+ }
}
return 0;
}
void SmwCpuInitialize(void) {
+ g_lunar_magic = HAS_LM_FEATURE(kLmFeature_LmEnabled);
if (g_rom) {
*SnesRomPtr(0x843B) = 0x60; // remove WaitForHBlank_Entry2
*SnesRomPtr(0x2DDA2) = 5;
*SnesRomPtr(0xCA5AC) = 7;
+
+ uint8 *music = SnesRomPtr(0x8052);
+ g_custom_music = music[1] != 0xE8;
+ if (g_custom_music) {
+ music[0] = 0xea;
+ music[1] = 0xea;
+ music[2] = 0xea;
+
+ *SnesRomPtr(0x8079) = 0x60; // HandleSPCUploads_SPC700UploadLoop ret
+
+ uint8* p = SnesRomPtr(0x8075);
+ p[0] = 0x64;
+ p[1] = 0x10;
+ p[2] = 0x80;
+ p[3] = 0xF2;
+
+ printf("Custom music not supported!\n");
+
+ static const uint8 kRevertProcessNormalSprites[] = { 0xda, 0x8a, 0xae, 0x92, 0x16, 0x18, 0x7f, 0xb4, 0xf0, 0x07, 0xaa, 0xbf, 0x00, 0xf0, 0x07, 0xfa, 0x9d, 0xea, 0x15 };
+ memcpy(SnesRomPtr(0x180d2), kRevertProcessNormalSprites, sizeof(kRevertProcessNormalSprites));
+ static const uint8 kRevertStatusBar[] = { 0xad, 0x22, 0x14, 0xc9 };
+ memcpy(SnesRomPtr(0x8FD8), kRevertStatusBar, sizeof(kRevertStatusBar));
+
+ if (HAS_HACK(kHack_Walljump)) {
+ uint8 *wallhack = SnesRomPtr(0xa2a1);
+ wallhack[3] &= 0x7f;
+ wallhack = SnesRomPtr(get_24(0xa2a2));
+ wallhack[3] &= 0x7f;
+ }
+
+ // Reznor platform fix
+ static const uint8 kRevert_0x39890[] = { 0xee, 0x0f, 0x14 };
+ memcpy(SnesRomPtr(0x39890), kRevert_0x39890, sizeof(kRevert_0x39890));
+
+ static const uint8 kRevert_0x2907a[] = { 0xbd, 0x9d, 0x16, 0xd0 };
+ memcpy(SnesRomPtr(0x2907a), kRevert_0x2907a, sizeof(kRevert_0x2907a));
+ static const uint8 kRevert_0xf5f3[] = { 0xa0, 0x04, 0x8c, 0xf9, 0x1d };
+ memcpy(SnesRomPtr(0xf5f3), kRevert_0xf5f3, sizeof(kRevert_0xf5f3));
+ static const uint8 kRevert_0x1bb33[] = { 0xa9, 0x30, 0x9d, 0xea, 0x15 };
+ memcpy(SnesRomPtr(0x1bb33), kRevert_0x1bb33, sizeof(kRevert_0x1bb33));
+ static const uint8 kRevert_0x2a129[] = { 0xa9, 0x21, 0x95, 0x9e, 0xa9, 0x08, 0x9d, 0xc8, 0x14, 0x22, 0xd2, 0xf7, 0x07 };
+ memcpy(SnesRomPtr(0x2a129), kRevert_0x2a129, sizeof(kRevert_0x2a129));
+ static const uint8 kRevert_0x2db82[] = { 0xbd, 0xe0, 0x14, 0x99, 0xe0, 0x14 };
+ memcpy(SnesRomPtr(0x2db82), kRevert_0x2db82, sizeof(kRevert_0x2db82));
+ static const uint8 kRevert_0x2e6ec[] = { 0xa9, 0x38, 0x9d, 0xea, 0x15 };
+ memcpy(SnesRomPtr(0x2e6ec), kRevert_0x2e6ec, sizeof(kRevert_0x2e6ec));
+ }
}
}
@@ -166,6 +260,13 @@ static void SmwFixSnapshotForCompare(Snapshot *b, Snapshot *a) {
memcpy(&b->ram[0x14B0], &a->ram[0x14B0], 0x11); // temp14b0 etc
memcpy(&b->ram[0x1436], &a->ram[0x1436], 4); // temp14b0 etc
+
+ memcpy(&b->ram[0x1C00B], &a->ram[0x1C00B], 1); // lm_varB
+
+ if (g_custom_music) {
+ memcpy(&b->ram[0x1DF9], &a->ram[0x1DF9], 8); // sound io
+ }
+
}
static uint32 RunCpuUntilPC(uint32 pc1, uint32 pc2) {
@@ -174,7 +275,7 @@ static uint32 RunCpuUntilPC(uint32 pc1, uint32 pc2) {
for(;;) {
snes_runCpu(g_snes);
// snes_runCycle(g_snes);
- uint32 addr = g_snes->cpu->k << 16 | g_snes->cpu->pc;
+ uint32 addr = (g_snes->cpu->k << 16 | g_snes->cpu->pc) & 0x7fffff;
if (addr != addr_last && (addr == pc1 || addr == pc2)) {
return addr;
}
diff --git a/src/smw_rtl.c b/src/smw_rtl.c
index ccd7958..fa4741f 100644
--- a/src/smw_rtl.c
+++ b/src/smw_rtl.c
@@ -3,6 +3,7 @@
#include
#include "common_cpu_infra.h"
#include "snes/snes.h"
+#include "src/funcs.h"
const uint8 *ptr_layer1_data;
const uint8 *ptr_layer2_data;
@@ -11,6 +12,9 @@ uint8 ptr_layer2_is_bg;
uint8 *ptr_lo_map16_data;
uint8 *ptr_lo_map16_data_bak;
+bool g_lunar_magic;
+
+
void AddSprXPos(uint8 k, uint16 x) {
AddHiLo(&spr_xpos_hi[k], &spr_xpos_lo[k], x);
}
@@ -91,4 +95,54 @@ void SmwRunOneFrameOfGame(void) {
SmwVectorReset();
SmwRunOneFrameOfGame_Internal();
SmwVectorNMI();
-}
\ No newline at end of file
+}
+
+
+void LoadStripeImage_UploadToVRAM(const uint8 *pp) { // 00871e
+ while (1) {
+ if ((*pp & 0x80) != 0)
+ break;
+ uint16 vram_addr = pp[0] << 8 | pp[1];
+ if (g_lunar_magic)
+ vram_addr = LmHook_LoadStripeImage(vram_addr);
+
+ uint8 vmain = __CFSHL__(pp[2], 1);
+ uint8 fixed_addr = (uint8)(pp[2] & 0x40) >> 3;
+ uint16 num = (swap16(WORD(pp[2])) & 0x3FFF) + 1;
+ pp += 4;
+
+ if (fixed_addr) {
+ if (vram_addr != 0xffff) {
+ uint16 *dst = g_ppu->vram + vram_addr;
+ uint16 src_data = WORD(*pp);
+ int ctr = (num + 1) >> 1;
+ if (vmain) {
+ for (int i = 0; i < ctr; i++)
+ dst[i * 32] = src_data;
+ } else {
+ // uhm...?
+ uint8 *dst_b = (uint8 *)dst;
+ for (int i = 0; i < num; i++)
+ dst_b[i + ((i & 1) << 1)] = src_data;
+ for (int i = 0; i < num; i += 2)
+ dst_b[i + 1] = src_data >> 8;
+ }
+ }
+ pp += 2;
+ } else {
+ if (vram_addr != 0xffff) {
+ uint16 *dst = g_ppu->vram + vram_addr;
+ uint16 *src = (uint16 *)pp;
+ if (vmain) {
+ for (int i = 0; i < (num >> 1); i++)
+ dst[i * 32] = src[i];
+ } else {
+ for (int i = 0; i < (num >> 1); i++)
+ dst[i] = src[i];
+ }
+ }
+ pp += num;
+ }
+ }
+}
+
diff --git a/src/smw_rtl.h b/src/smw_rtl.h
index 3369311..0301ea5 100644
--- a/src/smw_rtl.h
+++ b/src/smw_rtl.h
@@ -1,7 +1,11 @@
-#pragma once
+#ifndef SMW_SMW_RTL_H_
+#define SMW_SMW_RTL_H_
#include "common_rtl.h"
#include "snes/snes_regs.h"
+extern bool g_lunar_magic;
+extern int g_dbg_ctr_mine;
+
PointU16 *get_PointU16(PointU16 *pt, uint8 off);
static inline OamEnt *get_OamEnt(OamEnt *base, uint16 off) { return (OamEnt *)((uint8 *)base + off); }
@@ -15,6 +19,7 @@ void SmwCopyToVram(uint16 vram_addr, const uint8 *src, int n);
void SmwClearVram(uint16 vram_addr, uint16 value, int n);
void SmwCopyToVramPitch32(uint16 vram_addr, const uint8 *src, int n);
void SmwCopyToVramLow(uint16 vram_addr, const uint8 *src, int n);
+void SmwCopyFromVram(uint16 vram_addr, uint8 *dst, int n);
void SmwDrawPpuFrame(void);
void SmwRunOneFrameOfGame(void);
@@ -60,4 +65,6 @@ typedef struct GenTileArgs {
} GenTileArgs;
const uint8 *GetSpriteListPtr();
-uint8 GetCurrentSlope(int i);
\ No newline at end of file
+uint8 GetCurrentSlope(int i);
+
+#endif // SMW_SMW_RTL_H_
\ No newline at end of file
diff --git a/src/snes/cpu.c b/src/snes/cpu.c
index 837819b..9232683 100644
--- a/src/snes/cpu.c
+++ b/src/snes/cpu.c
@@ -735,34 +735,34 @@ int bp_cnt = 0;
extern bool g_debug_apu_cycles;
void DumpCpuHistory() {
- for (int i = 0; i < 8; i++) {
- printf("PC history: 0x%x\n", pc_hist[(pc_hist_ctr + i) & 7]);
+ for (int i = 0; i < 16; i++) {
+ printf("PC history: 0x%x\n", pc_hist[(pc_hist_ctr + i) & 15]);
}
}
+extern int g_dbg_ctr_theirs;
+
static void cpu_doOpcode(Cpu* cpu, uint8_t opcode) {
- uint32 cur_pc = ((cpu->k << 16) | cpu->pc - 1);
+ if (cpu->k & 0x80 || cpu->sp < 0x150 && cpu->sp != 0x100) {
+ DumpCpuHistory();
+ assert(0);
+ }
+ uint32 cur_pc = ((cpu->k << 16) | cpu->pc - 1) & 0x7fffff;
pc_hist[pc_hist_ctr] = cur_pc;
pc_hist_ctr = (pc_hist_ctr + 1) & 15;
+ if (0 && cur_pc == 0x5D83B) {
+ g_snes->debug_cycles = 0;
+ }
+
if (cur_pc == pc_bp) {
- printf("Reached BP 0x%x. A=0x%.2x, X=0x%.2x, Y=0x%.2x. C=%d. 0x%x\n",
- cur_pc, (uint8)cpu->a, cpu->x, cpu->y, cpu->c,
- 0);
+ printf("Reached BP 0x%x. A=0x%.2x, X=0x%.2x, Y=0x%.2x. C=%d. lm_var13CD=%x\n",
+ cur_pc, cpu->a, cpu->x, cpu->y, cpu->c,
+ *(uint16*)&g_ram[14]);
+// printf("T: 16 j=%d, %d\n", g_cpu->y, g_cpu->a);
bp_cnt += 1;
//g_snes->debug_cycles = 1;
}
- if (cur_pc == 0x85d2) {
-// printf("T: upl stripe %d\n", graphics_stripe_image_to_upload);
-// if (cur_pc == 0x29197 && g_cpu->x == 0x800&&0) {
-// printf("x=0x%x, y=0x%x, t4=0x%x\n", g_cpu->x, g_cpu->y, WORD(tempE4));
- //g_snes->debug_cycles = 1;
- uint16 t = g_ram[0xf3] | g_ram[0xf4] << 8;
-// printf("wr 0x%x = 0x%x\n", t + g_cpu->y, g_cpu->a & 0xff);
-
- }
-// if (cur_pc == 0x2A82E)
-// printf("T: Load sprites offs %d: 0x%x\n", g_cpu->y, WORD(g_ram[0]));
restart:
switch(opcode) {
diff --git a/src/snes/snes.c b/src/snes/snes.c
index d78e610..9f258ab 100644
--- a/src/snes/snes.c
+++ b/src/snes/snes.c
@@ -206,7 +206,7 @@ void snes_runCycle(Snes* snes) {
snes_handle_pos_stuff(snes);
}
-#define IS_ADR(x) (x == 0xffffff)
+#define IS_ADR(x) (x == 0xfffff)
void snes_runCpu(Snes *snes) {
uint32_t pc = snes->cpu->k << 16 | snes->cpu->pc;
diff --git a/src/snes/snes_regs.h b/src/snes/snes_regs.h
index 82305fb..86788e9 100644
--- a/src/snes/snes_regs.h
+++ b/src/snes/snes_regs.h
@@ -1,3 +1,5 @@
+#ifndef SNES_SNES_REGS_H_
+#define SNES_SNES_REGS_H_
#pragma once
typedef enum SnesRegs {
@@ -213,3 +215,5 @@ typedef enum SnesRegs {
UNUSED7 = 0x437B,
MIRR7 = 0x437F,
} SnesRegs;
+
+#endif // SNES_SNES_REGS_H_
\ No newline at end of file
diff --git a/src/types.h b/src/types.h
index 9da0300..0c024ae 100644
--- a/src/types.h
+++ b/src/types.h
@@ -157,6 +157,7 @@ typedef struct MemBlk {
size_t size;
} MemBlk;
MemBlk FindIndexInMemblk(MemBlk data, size_t i);
+const uint8 *FindAddrInMemblk(MemBlk data, uint32 addr);
#endif // SM_TYPES_H_
diff --git a/src/util.c b/src/util.c
index 50953df..358981c 100644
--- a/src/util.c
+++ b/src/util.c
@@ -208,3 +208,32 @@ MemBlk FindIndexInMemblk(MemBlk data, size_t i) {
return (MemBlk) { 0, 0 };
return (MemBlk) { data.ptr + left_off, right_off - left_off };
}
+
+const uint8 *FindAddrInMemblk(MemBlk data, uint32 addr) {
+ if (data.size < 2)
+ return 0; // sanity check
+ // std::lower_bound
+ int count = *(uint16 *)data.ptr, count_org = count;
+ if (data.size < 2 + count * 6)
+ return 0; // sanity check
+ const uint8 *first = data.ptr + 2;
+ while (count) {
+ const uint8 *it = first;
+ int step = count >> 1;
+ it += step * 3;
+ if ((*(uint32 *)it & 0xffffff) < addr) {
+ first = it + 3;
+ count -= step + 1;
+ } else {
+ count = step;
+ }
+ }
+ if (first >= data.ptr + 2 + count_org * 3 || (*(uint32 *)first & 0xffffff) != addr)
+ first -= 3;
+ uint32 src_off = *(uint32 *)first & 0xffffff;
+ uint32 offset = *(uint32 *)(first + count_org * 3) & 0xffffff;
+ offset += addr - src_off;
+ if (offset >= data.size)
+ return 0;
+ return data.ptr + offset;
+}
diff --git a/src/variables.h b/src/variables.h
index 8b04ed0..26fc236 100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -154,6 +154,13 @@ extern uint8 ptr_layer2_is_bg;
#define spr86_wiggler_segment_pos_ptr (*(LongPtr*)(g_ram+0xD5))
#define spr_ypos_lo ((uint8*)(g_ram+0xD8))
#define spr_xpos_lo ((uint8*)(g_ram+0xE4))
+
+#define lunar_magic_F9 (*(uint8*)(g_ram+0xf9))
+#define lunar_magic_FA (*(uint8*)(g_ram+0xfa))
+#define lunar_magic_FB (*(uint8*)(g_ram+0xfb))
+#define lunar_magic_FC (*(uint8*)(g_ram+0xfc))
+#define lunar_magic_FD (*(uint8*)(g_ram+0xfd))
+#define lunar_magic_FE (*(uint16*)(g_ram+0xfe))
#define misc_game_mode (*(uint8*)(g_ram+0x100))
#define misc_currently_loaded_sprite_graphics_files ((uint8*)(g_ram+0x101))
#define misc_intro_level_flag (*(uint8*)(g_ram+0x109))
@@ -309,7 +316,7 @@ extern uint8 ptr_layer2_is_bg;
#define flag_show_save_prompt (*(uint8*)(g_ram+0x13CA))
#define unusedram_got_invincible_star_from_goal (*(uint8*)(g_ram+0x13CB))
#define counter_coin_handler (*(uint8*)(g_ram+0x13CC))
-#define unusedram_disable_midpoint (*(uint8*)(g_ram+0x13CD))
+#define lm_var13CD (*(uint8*)(g_ram+0x13CD))
#define flag_got_midpoint (*(uint8*)(g_ram+0x13CE))
#define flag_override_no_yoshi_intro_for_midway_entrance (*(uint8*)(g_ram+0x13CF))
#define ow_destroy_tile_event_tile_index (*(uint8*)(g_ram+0x13D0))
@@ -415,6 +422,7 @@ extern uint8 ptr_layer2_is_bg;
#define misc_layer3_xspeed (*(uint16*)(g_ram+0x1458))
#define misc_layer3_yspeed (*(uint16*)(g_ram+0x145A))
#define misc_layer3_tide_sub_ypos (*(uint16*)(g_ram+0x145C))
+#define lm_word_7E145E (*(uint16*)(g_ram+0x145e))
#define flag_layer3_vert_scroll_direction (*(uint8*)(g_ram+0x1460))
#define unusedram_7e1461 (*(uint8*)(g_ram+0x1461))
#define misc_layer1_pos ((PointU16*)(g_ram+0x1462))
@@ -870,3 +878,174 @@ extern uint8 ptr_layer2_is_bg;
#define graphics_decompressed_loading_letters ((uint8*)(g_ram+0x1977B))
#define spr86_wiggler_segment_pos_table ((uint8*)(g_ram+0x19A7B))
#define blocks_map16_table_hi ((uint8*)(g_ram+0x1C800))
+
+#define lm_ptr0 (*(LongPtr*)(g_ram + 0x1c000))
+#define lm_var3 (*(uint8*)(g_ram + 0x1c003))
+#define lm_var4 (*(uint8*)(g_ram + 0x1c004))
+#define lm_level_info (*(LongPtr*)(g_ram + 0x1c006))
+#define lm_var9 (*(uint8*)(g_ram + 0x1c009))
+#define lm_varA (*(uint8*)(g_ram + 0x1c00a))
+#define lm_varB (*(uint8*)(g_ram + 0x1c00b))
+#define lm_varC (*(uint16*)(g_ram + 0x1c00c))
+#define lm_varE (*(uint16*)(g_ram + 0x1c00e))
+#define lm_ptr10 (*(LongPtr *)(g_ram + 0x1c010))
+#define lm_ptr16 (*(LongPtr*)(g_ram + 0x1c016))
+#define lm_var19 (*(uint8*)(g_ram + 0x1c019))
+
+#define lm_var1a (*(uint8*)(g_ram + 0x1c01a))
+#define lm_var1b (*(uint8*)(g_ram + 0x1c01b))
+#define lm_var1c (*(uint8*)(g_ram + 0x1c01c))
+
+#define lm_exanim_setting (*(uint8*)(g_ram + 0x1c00a))
+#define lm_custom_triggers (*(uint16*)(g_ram + 0x1c0fc))
+
+#define smart_spawn_horiz_collision (*(uint8*)(g_ram + 0xBEE))
+#define smart_spawn_vert_collision (*(uint8*)(g_ram + 0xBEF))
+#define min_y_offset_from_screen_to_spawn (*(uint16*)(g_ram + 0xBF0))
+#define max_y_offset_from_screen_to_spawn (*(uint16*)(g_ram + 0xBF2))
+#define extra_flags_for_sprites (*(uint8*)(g_ram + 0xBF4))
+#define extra_flags_and_horiz_level_mode (*(uint8*)(g_ram + 0xBF5))
+#define L1_Screen_Lo ((LongPtr*)(g_ram + 0xBF6))
+#define L2_Screen_Lo ((LongPtr*)(g_ram + 0xC26))
+#define L1_Screen_Hi ((LongPtr*)(g_ram + 0xC56))
+#define L2_Screen_Hi ((LongPtr*)(g_ram + 0xC86))
+#define lm_ptrs_to_sprites_per_screen ((uint16*)(g_ram + 0xCF6))
+#define lm_screen_sprite_data ((uint16*)(g_ram + 0xD36))
+
+#define lm_level_height (*(uint16*)(g_ram + 0x13D7))
+#define lm_level_height_minus_16 (*(uint16*)(g_ram + 0x1936))
+
+#define L1_Screen_8bit_Lo (g_ram + 0xcb6)
+#define L1_Screen_8bit_Hi (g_ram + 0xcd6)
+
+#define lm_var8325 (*(uint16*)(g_ram + 0x18325))
+#define lm_var8323 (*(uint16*)(g_ram + 0x18323))
+#define lm_var8321 (*(uint16*)(g_ram + 0x18321))
+#define lm_var831f (*(uint16*)(g_ram + 0x1831f))
+
+#pragma pack (push, 1)
+typedef struct ExAnimationInfo {
+ uint16 hdr_size;
+ uint16 dst;
+ LongPtr src;
+} ExAnimationInfo;
+#pragma pack (pop)
+
+#define lm_exanim_manual_triggers ((uint8*)(g_ram + 0x1c070))
+#define lm_exanim_frame_ctr ((uint16*)(g_ram + 0x1c080))
+#define ex_anim_info_0 (*(ExAnimationInfo*)(g_ram + 0x1c0c0))
+#define ex_anim_info_1 (*(ExAnimationInfo*)(g_ram + 0x1c0c7))
+#define ex_anim_info_2 (*(ExAnimationInfo*)(g_ram + 0x1c0ce))
+#define ex_anim_info_3 (*(ExAnimationInfo*)(g_ram + 0x1c0d5))
+#define ex_anim_info_4 (*(ExAnimationInfo*)(g_ram + 0x1c0dc))
+#define ex_anim_info_5 (*(ExAnimationInfo*)(g_ram + 0x1c0e3))
+#define ex_anim_info_6 (*(ExAnimationInfo*)(g_ram + 0x1c0ea))
+#define ex_anim_info_7 (*(ExAnimationInfo*)(g_ram + 0x1c0f1))
+
+#define lm_one_shot_triggers (*(uint32*)(g_ram + 0x1c0f8))
+
+#define lm_vram_dma_dst0 (*(uint16*)(g_ram + 0x695))
+#define lm_vram_dma_dst1 (*(uint16*)(g_ram + 0x697))
+#define lm_vram_dma_dst2 (*(uint16*)(g_ram + 0x699))
+#define lm_vram_dma_dst3 (*(uint16*)(g_ram + 0x69b))
+#define lm_vram_dma_dst4 (*(uint16*)(g_ram + 0x69d))
+#define lm_vram_dma_dst5 (*(uint16*)(g_ram + 0x69f))
+
+#define lm_vram_dma_size0 (*(uint8*)(g_ram + 0x6a1))
+#define lm_vram_dma_size1 (*(uint8*)(g_ram + 0x6a2))
+#define lm_vram_dma_size2 (*(uint8*)(g_ram + 0x6a3))
+#define lm_vram_dma_size3 (*(uint8*)(g_ram + 0x6a4))
+#define lm_vram_dma_size4 (*(uint8*)(g_ram + 0x6a5))
+#define lm_vram_dma_size5 (*(uint8*)(g_ram + 0x6a6))
+
+#define lm_vram_dma_src0 (*(uint16*)(g_ram + 0x6a7))
+#define lm_vram_dma_src1 (*(uint16*)(g_ram + 0x6a9))
+#define lm_vram_dma_src2 (*(uint16*)(g_ram + 0x6ab))
+#define lm_vram_dma_src3 (*(uint16*)(g_ram + 0x6ad))
+#define lm_vram_dma_src4 (*(uint16*)(g_ram + 0x6af))
+#define lm_vram_dma_src5 (*(uint16*)(g_ram + 0x6b1))
+
+#define lm_vram_dma_dst6 (*(uint16*)(g_ram + 0x6b3))
+#define lm_vram_dma_dst7 (*(uint16*)(g_ram + 0x6b5))
+#define lm_vram_dma_dst8 (*(uint16*)(g_ram + 0x6b7))
+#define lm_vram_dma_dst9 (*(uint16*)(g_ram + 0x6b9))
+#define lm_vram_dma_dst10 (*(uint16*)(g_ram + 0x6bb))
+#define lm_vram_dma_dst11 (*(uint16*)(g_ram + 0x6bd))
+
+#define lm_vram_dma_size6 (*(uint8*)(g_ram + 0x6bf))
+#define lm_vram_dma_size7 (*(uint8*)(g_ram + 0x6c0))
+#define lm_vram_dma_size8 (*(uint8*)(g_ram + 0x6c1))
+#define lm_vram_dma_size9 (*(uint8*)(g_ram + 0x6c2))
+#define lm_vram_dma_size10 (*(uint8*)(g_ram + 0x6c3))
+#define lm_vram_dma_size11 (*(uint8*)(g_ram + 0x6c4))
+
+#define lm_vram_dma_src6 (*(uint16*)(g_ram + 0x6c5))
+#define lm_vram_dma_src7 (*(uint16*)(g_ram + 0x6c7))
+#define lm_vram_dma_src8 (*(uint16*)(g_ram + 0x6c9))
+#define lm_vram_dma_src9 (*(uint16*)(g_ram + 0x6cb))
+#define lm_vram_dma_src10 (*(uint16*)(g_ram + 0x6cd))
+#define lm_vram_dma_src11 (*(uint16*)(g_ram + 0x6cf))
+
+#define lm_vram_dma_dst12 (*(uint16*)(g_ram + 0x6d1))
+#define lm_vram_dma_dst13 (*(uint16*)(g_ram + 0x6d3))
+#define lm_vram_dma_dst14 (*(uint16*)(g_ram + 0x6d5))
+#define lm_vram_dma_dst15 (*(uint16*)(g_ram + 0x6d7))
+
+#define lm_vram_dma_size12 (*(uint8*)(g_ram + 0x6d9))
+#define lm_vram_dma_size13 (*(uint8*)(g_ram + 0x6da))
+#define lm_vram_dma_size14 (*(uint8*)(g_ram + 0x6db))
+#define lm_vram_dma_size15 (*(uint8*)(g_ram + 0x6dc))
+
+#define lm_vram_dma_src12 (*(uint16*)(g_ram + 0x6dd))
+#define lm_vram_dma_src13 (*(uint16*)(g_ram + 0x6df))
+#define lm_vram_dma_src14 (*(uint16*)(g_ram + 0x6e1))
+#define lm_vram_dma_src15 (*(uint16*)(g_ram + 0x6e3))
+
+#define lm_vram_dma_dst16 (*(uint16*)(g_ram + 0x6e5))
+#define lm_vram_dma_dst17 (*(uint16*)(g_ram + 0x6e7))
+#define lm_vram_dma_dst18 (*(uint16*)(g_ram + 0x6e9))
+#define lm_vram_dma_dst19 (*(uint16*)(g_ram + 0x6eb))
+
+#define lm_vram_dma_size16 (*(uint8*)(g_ram + 0x6ed))
+#define lm_vram_dma_size17 (*(uint8*)(g_ram + 0x6ee))
+#define lm_vram_dma_size18 (*(uint8*)(g_ram + 0x6ef))
+#define lm_vram_dma_size19 (*(uint8*)(g_ram + 0x6f0))
+
+#define lm_vram_dma_src16 (*(uint16*)(g_ram + 0x6f1))
+#define lm_vram_dma_src17 (*(uint16*)(g_ram + 0x6f3))
+#define lm_vram_dma_src18 (*(uint16*)(g_ram + 0x6f5))
+#define lm_vram_dma_src19 (*(uint16*)(g_ram + 0x6f7))
+
+#define lm_vram_upload_enable_0 (*(uint16*)(g_ram + 0x18183))
+#define lm_vram_upload_enable_6 (*(uint16*)(g_ram + 0x18185))
+#define lm_vram_upload_enable_12 (*(uint16*)(g_ram + 0x18187))
+#define lm_vram_upload_enable_16 (*(uint16*)(g_ram + 0x18189))
+
+#define lm_L1_colbuf ((uint16*)(g_ram + 0x1818b))
+#define lm_L2_colbuf ((uint16*)(g_ram + 0x1820b))
+#define lm_tilebuf3 ((uint16*)(g_ram + 0x1828b))
+
+#define lm_arr1830b ((uint16*)(g_ram + 0x1830b))
+#define lm_arr1831b ((uint8*)(g_ram + 0x1831b))
+#define lm_arr1831f ((uint16*)(g_ram + 0x1831f))
+
+#define lm_arr_7FBC00 ((uint16*)(g_ram + 0x1BC00))
+#define lm_arr_7FC300 ((uint16*)(g_ram + 0x1C300))
+
+#define lm_var18327 (*(uint16*)(g_ram + 0x18327))
+
+#define lm_var_0045 (*(uint8 *)(g_ram + 0x45))
+#define lm_var_0046 (*(uint16 *)(g_ram + 0x46))
+#define lm_var_0048 (*(uint16 *)(g_ram + 0x48))
+#define lm_var_004A (*(uint16 *)(g_ram + 0x4A))
+#define lm_var_004C (*(uint16 *)(g_ram + 0x4C))
+#define lm_var_004E (*(uint16 *)(g_ram + 0x4E))
+#define lm_var_0050 (*(uint16 *)(g_ram + 0x50))
+#define lm_var_0052 (*(uint16 *)(g_ram + 0x52))
+#define lm_var_0054 (*(uint8 *)(g_ram + 0x54))
+
+#define lm_state_array ((uint8 *)(g_ram + 0x1c060))
+
+#define lm_title_screen_var (*(uint16 *)(g_ram + 0x1fffe))
+
+extern bool g_lunar_magic;
\ No newline at end of file