Basic support for Lunar Magic edited roms.

Mods that use ASM hooks will not work except for wall jump.

You might have to edit the ROM with the latest lunar magic (3.33) and
edit a level and save it, and edit a map16 tile and save it, just to
make sure Lunar Magic upgrades the code in the ROM to the latest version.

Run the asset tool like:
python3 assets/restool.py -f -r "enhanced/enhanced.sfc"
This commit is contained in:
Snesrev 2023-07-25 02:15:45 +02:00
parent 4424c32a98
commit b8096d4fcf
32 changed files with 5310 additions and 1387 deletions

2
.gitignore vendored
View File

@ -14,3 +14,5 @@ SDL2.dll
/work /work
smw_assets.dat smw_assets.dat
__pycache__ __pycache__
/enhanced/
*.sfc

View File

@ -1,6 +1,6 @@
import sys, array, hashlib, struct, argparse, os import sys, array, hashlib, struct, argparse, os
import util import util
from util import cache from util import cache, get_byte, get_word, get_24, get_bytes, get_words
def flatten(xss): def flatten(xss):
return [x for xs in xss for x in xs] 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 assert name not in assets
assets[name] = ('packed', pack_arrays(data)) 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 # Pack arrays and determine automatically the index size
def pack_arrays(arr): def pack_arrays(arr):
if len(arr) == 0: if len(arr) == 0:
@ -66,6 +74,24 @@ def pack_arrays(arr):
r.append(struct.pack('H', flags)) r.append(struct.pack('H', flags))
return b''.join(r) 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): def get_stripe_len(ea):
ea_org = ea ea_org = ea
while True: while True:
@ -81,6 +107,18 @@ def get_stripe_len(ea):
else: else:
ll = ((p2 << 8 | p3) & 0x3fff) + 1 ll = ((p2 << 8 | p3) & 0x3fff) + 1
ea += ll 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 @cache
def unpack_rle(ea): def unpack_rle(ea):
ea_org = ea ea_org = ea
@ -97,10 +135,34 @@ def unpack_rle(ea):
r.append(y) r.append(y)
return bytes(r), ea + 2 - ea_org 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 @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_org = ea
ea += 5 ea += 5
kObjNames = {
60 : 'StoneBlock',
13 : 'CementBlock',
0x22: 'LmMap16',
}
while True: while True:
b0 = util.get_byte(ea); ea += 1 b0 = util.get_byte(ea); ea += 1
if b0 == 0xff: if b0 == 0xff:
@ -108,29 +170,97 @@ def calc_level_len(ea):
b1 = util.get_byte(ea); ea += 1 b1 = util.get_byte(ea); ea += 1
b2 = 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 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 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 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): def print_all(args):
lm_feat = LmFeatures()
r = [] r = []
lo, hi, bank = util.get_bytes(0xB992, 50), util.get_bytes(0xB9c4, 50), util.get_bytes(0xB9f6, 50) lo, hi, bank = util.get_bytes(0xB992, 50), util.get_bytes(0xB9c4, 50), util.get_bytes(0xB9f6, 50)
for i in range(50): for i in range(50):
p = bank[i] << 16 | hi[i] << 8 | lo[i] p = bank[i] << 16 | hi[i] << 8 | lo[i]
data, comp_len = util.decomp(p, util.get_byte, return_length = True) r.append(get_comp_data(p))
#print('%d: %d: %d' % (i, comp_len, len(data)))
r.append(data)
add_asset_packed('kGraphicsPtrs', r) 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))) #print('%d: %d: %d' % (0x32, comp_len, len(data)))
add_asset_uint8('kGfx32', 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))) #print('%d: %d: %d' % (0x33, comp_len, len(data)))
add_asset_uint8('kGfx33', data) add_asset_uint8('kGfx33', data)
@ -150,8 +280,6 @@ def print_all(args):
r.append(util.get_bytes(p, pl)) r.append(util.get_bytes(p, pl))
add_asset_packed('kLayer3ImagePtrs', r) 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('kSpcCreditsMusicBank', util.get_bytes(0x3e400, 6624))
add_asset_uint8('kSpcLevelMusicBank', util.get_bytes(0xEAED6, 16899)) add_asset_uint8('kSpcLevelMusicBank', util.get_bytes(0xEAED6, 16899))
add_asset_uint8('kSpcEngine', util.get_bytes(0xe8000, 6321) + b'\x00\x00') 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_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', util.get_words(0xd8000, (0xA100 - 0x8000) // 2))
add_asset_uint16('kMap16Data_Castle', util.get_words(0xdbc00, 712)) add_asset_uint16('kMap16Data_Castle', util.get_words(0xdbc00, 712))
add_asset_uint16('kMap16Data_Rope', util.get_words(0xdc800, 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_Underground', util.get_words(0xdd400, 712))
add_asset_uint16('kMap16Data_GhostHouse', util.get_words(0xde300, 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_uint8('kGameMode1B_EndingCinema_Tilemaps', util.get_bytes(0xC95C7, 1873))
add_asset_uint16('kGameMode1B_EndingCinema_RowPointers', util.get_words(0xC9D18, 202)) 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_05F200', util.get_bytes(0x5f200, 0x200))
add_asset_uint8('kLevelInfo_05F400', util.get_bytes(0x5f400, 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_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)) 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_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)) add_asset_uint8('kLineGuideSpeedTableData', util.get_bytes(0x7F9DB, 536))
def add_packed_levels(name, addr, num, bank = None): def add_packed_levels(name, addr, num, bank = None):
r = [] r = []
for i in range(num): for i in range(num):
if bank == None: try:
ea = util.get_24(addr + i * 3) if bank == None:
else: ea = util.get_24(addr + i * 3)
ea = util.get_word(addr + i * 2) | bank << 16 else:
ln = calc_level_len(ea) ea = util.get_word(addr + i * 2) | bank << 16
r.append(util.get_bytes(ea, ln)) 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_asset_packed(name, r)
add_packed_levels('kLevelData_Layer1', 0x5E000, 0x200) add_packed_levels('kLevelData_Layer1', 0x5E000, 0x200)
@ -224,7 +367,7 @@ def print_all(args):
else: else:
assert 0 assert 0
fl = 0 fl = util.get_byte(0xEF310 + i) if num == 0x200 and LUNAR_MAGIC else 0
if (ea & 0xff0000) == 0xff0000: if (ea & 0xff0000) == 0xff0000:
ea = (ea & 0xffff) | 0xc0000 ea = (ea & 0xffff) | 0xc0000
fl = ((ea & 0xffff) >= 0xE8FE) << 4 | 2 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('kEntranceData_Layer2', 0x5d778, 6)
add_packed_level_bg('kChoclateIsland2_Layer2', 0x5DB2C, 9, mode = 'choc') add_packed_level_bg('kChoclateIsland2_Layer2', 0x5DB2C, 9, mode = 'choc')
add_packed_level_bg('kRollCallData_Layer2', 0xCAD72, 13, mode = 'end') add_packed_level_bg('kRollCallData_Layer2', 0xCAD72, 13, mode = 'end')
add_packed_level_bg('kBufferCreditsBackgrounds_Layer2', 0xc93c1, 7, mode = 'choc') add_packed_level_bg('kBufferCreditsBackgrounds_Layer2', 0xc93c1, 7, mode = 'choc')
def get_sprite_data_len(ea): def get_sprite_data_len(ea):
@ -253,22 +395,34 @@ def print_all(args):
ea += 3 ea += 3
return ea + 1 - ea_org 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(): def add_sprites():
r = [] spr_ranges = []
def touch(ea): def touch(ea):
lx = get_sprite_data_len(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): 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) touch(0x7c3ee)
for i in range(9): for i in range(9):
touch(util.get_word(0x5DB1A + i * 2) | 0x70000) 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() add_sprites()
@ -276,16 +430,405 @@ def print_all(args):
add_asset_uint8('kFileSelectText_EraseFile', util.get_bytes(0x5B6FE, 203 + 204)) add_asset_uint8('kFileSelectText_EraseFile', util.get_bytes(0x5B6FE, 203 + 204))
add_asset_uint8('kInitializeMode7TilemapsAndPalettes_TilemapData', util.get_bytes(0x3D9DE, 912)) add_asset_uint8('kInitializeMode7TilemapsAndPalettes_TilemapData', util.get_bytes(0x3D9DE, 912))
add_asset_uint16('kLayer2EventData_TileEntries', util.get_words(0x4DD8D, 742)) def do_u16(name, addr, org_addr, org_size, bank_addr = None):
add_asset_uint8('kUpdateLevelName_LevelNameStrings', util.get_bytes(0x49ac5, 460)) 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('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_uint16('', util.get_words(0x, ))
#add_asset_uint8('', util.get_bytes(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): def write_assets_to_file(print_header = False):
@ -293,7 +836,7 @@ def write_assets_to_file(print_header = False):
all_data = [] all_data = []
if print_header: if print_header:
print('''#pragma once print('''#pragma once
#include "types.h" #include "../src/types.h"
enum { enum {
kNumberOfAssets = %d kNumberOfAssets = %d
@ -301,14 +844,20 @@ enum {
extern const uint8 *g_asset_ptrs[kNumberOfAssets]; extern const uint8 *g_asset_ptrs[kNumberOfAssets];
extern uint32 g_asset_sizes[kNumberOfAssets]; extern uint32 g_asset_sizes[kNumberOfAssets];
extern MemBlk FindInAssetArray(int asset, int idx); extern MemBlk FindInAssetArray(int asset, int idx);
extern const uint8 *FindPtrInAsset(int asset, uint32 addr);
''' % len(assets)) ''' % len(assets))
for i, (k, (tp, data)) in enumerate(assets.items()): for i, (k, (tp, data)) in enumerate(assets.items()):
if print_header: if print_header:
if tp == 'packed': if tp == 'packed':
print('#define %s(idx) FindInAssetArray(%d, idx)' % (k, i)) print('#define %s(idx) FindInAssetArray(%d, idx)' % (k, i))
elif tp == 'blob':
print('#define %s(addr) FindPtrInAsset(%d, addr)' % (k, i))
else: 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)) print('#define %s_SIZE (g_asset_sizes[%d])' % (k, i))
key_sig += k.encode('utf8') + b'\0' key_sig += k.encode('utf8') + b'\0'
all_data.append(data) all_data.append(data)

View File

@ -5,8 +5,7 @@ import sys
parser = argparse.ArgumentParser(description='Resource tool used to build smw_assets.dat', allow_abbrev=False) 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('-r', '--rom', nargs='?', metavar='ROM')
parser.add_argument('--extract-from-rom', '-e', action='store_true', help='Extract assets from the 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') 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') optional = parser.add_argument_group('Debug things')
@ -14,9 +13,9 @@ optional.add_argument('--print-assets-header', action='store_true')
args = parser.parse_args() 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 import compile_resources
compile_resources.main(args) compile_resources.main(args)

View File

@ -1,114 +1,350 @@
#pragma once #pragma once
#include "src/types.h" #include "../src/types.h"
enum { enum {
kNumberOfAssets = 58 kNumberOfAssets = 178
}; };
extern const uint8 *g_asset_ptrs[kNumberOfAssets]; extern const uint8 *g_asset_ptrs[kNumberOfAssets];
extern uint32 g_asset_sizes[kNumberOfAssets]; extern uint32 g_asset_sizes[kNumberOfAssets];
extern MemBlk FindInAssetArray(int asset, int idx); extern MemBlk FindInAssetArray(int asset, int idx);
extern const uint8 *FindPtrInAsset(int asset, uint32 addr);
#define kGraphicsPtrs(idx) FindInAssetArray(0, idx) #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 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 kGfx33_SIZE (g_asset_sizes[2])
#define kLoadStripeImagePtrs(idx) FindInAssetArray(3, idx) #define kLoadStripeImagePtrs(idx) FindInAssetArray(3, idx)
#define kLayer3ImagePtrs(idx) FindInAssetArray(4, idx) #define kLayer3ImagePtrs(idx) FindInAssetArray(4, idx)
#define kOverworldLayer2EventTilemap_Tiles ((uint8*)g_asset_ptrs[5]) #define kSpcCreditsMusicBank g_asset_ptrs[5]
#define kOverworldLayer2EventTilemap_Tiles_SIZE (g_asset_sizes[5]) #define kSpcCreditsMusicBank_SIZE (g_asset_sizes[5])
#define kSpcCreditsMusicBank ((uint8*)g_asset_ptrs[6]) #define kSpcLevelMusicBank g_asset_ptrs[6]
#define kSpcCreditsMusicBank_SIZE (g_asset_sizes[6]) #define kSpcLevelMusicBank_SIZE (g_asset_sizes[6])
#define kSpcLevelMusicBank ((uint8*)g_asset_ptrs[7]) #define kSpcEngine g_asset_ptrs[7]
#define kSpcLevelMusicBank_SIZE (g_asset_sizes[7]) #define kSpcEngine_SIZE (g_asset_sizes[7])
#define kSpcEngine ((uint8*)g_asset_ptrs[8]) #define kSpcSamples g_asset_ptrs[8]
#define kSpcEngine_SIZE (g_asset_sizes[8]) #define kSpcSamples_SIZE (g_asset_sizes[8])
#define kSpcSamples ((uint8*)g_asset_ptrs[9]) #define kSpcOverworldMusicBank g_asset_ptrs[9]
#define kSpcSamples_SIZE (g_asset_sizes[9]) #define kSpcOverworldMusicBank_SIZE (g_asset_sizes[9])
#define kSpcOverworldMusicBank ((uint8*)g_asset_ptrs[10]) #define kMap16Data_OverworldLayer1 ((uint16*)g_asset_ptrs[10])
#define kSpcOverworldMusicBank_SIZE (g_asset_sizes[10]) #define kMap16Data_OverworldLayer1_SIZE (g_asset_sizes[10])
#define kMap16Data_OverworldLayer1 ((uint16*)g_asset_ptrs[11]) #define kMap16Data ((uint16*)g_asset_ptrs[11])
#define kMap16Data_OverworldLayer1_SIZE (g_asset_sizes[11]) #define kMap16Data_SIZE (g_asset_sizes[11])
#define kkOverworldLayer2EventTilemap_Prop ((uint8*)g_asset_ptrs[12]) #define kMap16Data_Castle ((uint16*)g_asset_ptrs[12])
#define kkOverworldLayer2EventTilemap_Prop_SIZE (g_asset_sizes[12]) #define kMap16Data_Castle_SIZE (g_asset_sizes[12])
#define kMap16Data ((uint16*)g_asset_ptrs[13]) #define kMap16Data_Rope ((uint16*)g_asset_ptrs[13])
#define kMap16Data_SIZE (g_asset_sizes[13]) #define kMap16Data_Rope_SIZE (g_asset_sizes[13])
#define kMap16Data_Castle ((uint16*)g_asset_ptrs[14]) #define kMap16Data_Underground ((uint16*)g_asset_ptrs[14])
#define kMap16Data_Castle_SIZE (g_asset_sizes[14]) #define kMap16Data_Underground_SIZE (g_asset_sizes[14])
#define kMap16Data_Rope ((uint16*)g_asset_ptrs[15]) #define kMap16Data_GhostHouse ((uint16*)g_asset_ptrs[15])
#define kMap16Data_Rope_SIZE (g_asset_sizes[15]) #define kMap16Data_GhostHouse_SIZE (g_asset_sizes[15])
#define kMap16Data_Underground ((uint16*)g_asset_ptrs[16]) #define kGlobalPalettes_Sky ((uint16*)g_asset_ptrs[16])
#define kMap16Data_Underground_SIZE (g_asset_sizes[16]) #define kGlobalPalettes_Sky_SIZE (g_asset_sizes[16])
#define kMap16Data_GhostHouse ((uint16*)g_asset_ptrs[17]) #define kGlobalPalettes_Background ((uint16*)g_asset_ptrs[17])
#define kMap16Data_GhostHouse_SIZE (g_asset_sizes[17]) #define kGlobalPalettes_Background_SIZE (g_asset_sizes[17])
#define kGameMode1B_EndingCinema_Tilemaps ((uint8*)g_asset_ptrs[18]) #define kGlobalPalettes_Layer3 ((uint16*)g_asset_ptrs[18])
#define kGameMode1B_EndingCinema_Tilemaps_SIZE (g_asset_sizes[18]) #define kGlobalPalettes_Layer3_SIZE (g_asset_sizes[18])
#define kGameMode1B_EndingCinema_RowPointers ((uint16*)g_asset_ptrs[19]) #define kGlobalPalettes_Foreground ((uint16*)g_asset_ptrs[19])
#define kGameMode1B_EndingCinema_RowPointers_SIZE (g_asset_sizes[19]) #define kGlobalPalettes_Foreground_SIZE (g_asset_sizes[19])
#define kLevelInfo_05F000 ((uint8*)g_asset_ptrs[20]) #define kGlobalPalettes_Objects ((uint16*)g_asset_ptrs[20])
#define kLevelInfo_05F000_SIZE (g_asset_sizes[20]) #define kGlobalPalettes_Objects_SIZE (g_asset_sizes[20])
#define kLevelInfo_05F200 ((uint8*)g_asset_ptrs[21]) #define kPlayerPalettes ((uint16*)g_asset_ptrs[21])
#define kLevelInfo_05F200_SIZE (g_asset_sizes[21]) #define kPlayerPalettes_SIZE (g_asset_sizes[21])
#define kLevelInfo_05F400 ((uint8*)g_asset_ptrs[22]) #define kGlobalPalettes_Sprites ((uint16*)g_asset_ptrs[22])
#define kLevelInfo_05F400_SIZE (g_asset_sizes[22]) #define kGlobalPalettes_Sprites_SIZE (g_asset_sizes[22])
#define kLevelInfo_05F600 ((uint8*)g_asset_ptrs[23]) #define kGlobalPalettes_YoshiBerry ((uint16*)g_asset_ptrs[23])
#define kLevelInfo_05F600_SIZE (g_asset_sizes[23]) #define kGlobalPalettes_YoshiBerry_SIZE (g_asset_sizes[23])
#define kLevelInfo_05F800 ((uint8*)g_asset_ptrs[24]) #define kGlobalPalettes_Flashing ((uint16*)g_asset_ptrs[24])
#define kLevelInfo_05F800_SIZE (g_asset_sizes[24]) #define kGlobalPalettes_Flashing_SIZE (g_asset_sizes[24])
#define kLevelInfo_05FA00 ((uint8*)g_asset_ptrs[25]) #define kGlobalPalettes_OW_Objects ((uint16*)g_asset_ptrs[25])
#define kLevelInfo_05FA00_SIZE (g_asset_sizes[25]) #define kGlobalPalettes_OW_Objects_SIZE (g_asset_sizes[25])
#define kLevelInfo_05FC00 ((uint8*)g_asset_ptrs[26]) #define kGlobalPalettes_OW_Sprites ((uint16*)g_asset_ptrs[26])
#define kLevelInfo_05FC00_SIZE (g_asset_sizes[26]) #define kGlobalPalettes_OW_Sprites_SIZE (g_asset_sizes[26])
#define kLevelInfo_05FE00 ((uint8*)g_asset_ptrs[27]) #define kGlobalPalettes_B5EC ((uint16*)g_asset_ptrs[27])
#define kLevelInfo_05FE00_SIZE (g_asset_sizes[27]) #define kGlobalPalettes_B5EC_SIZE (g_asset_sizes[27])
#define kLoadLevel_DATA_05D608 ((uint8*)g_asset_ptrs[28]) #define kGlobalPalettes_OW_Areas ((uint16*)g_asset_ptrs[28])
#define kLoadLevel_DATA_05D608_SIZE (g_asset_sizes[28]) #define kGlobalPalettes_OW_Areas_SIZE (g_asset_sizes[28])
#define kDisplayMessage_DATA_05A5D9 ((uint8*)g_asset_ptrs[29]) #define kGlobalPalettes_OW_AreasPassed ((uint16*)g_asset_ptrs[29])
#define kDisplayMessage_DATA_05A5D9_SIZE (g_asset_sizes[29]) #define kGlobalPalettes_OW_AreasPassed_SIZE (g_asset_sizes[29])
#define kOverworldLightningAndRandomCloudSpawning ((uint8*)g_asset_ptrs[30]) #define kGlobalPalettes_Bowser ((uint16*)g_asset_ptrs[30])
#define kOverworldLightningAndRandomCloudSpawning_SIZE (g_asset_sizes[30]) #define kGlobalPalettes_Bowser_SIZE (g_asset_sizes[30])
#define kLevelNames ((uint16*)g_asset_ptrs[31]) #define kGlobalPalettes_Layer3Smasher ((uint16*)g_asset_ptrs[31])
#define kLevelNames_SIZE (g_asset_sizes[31]) #define kGlobalPalettes_Layer3Smasher_SIZE (g_asset_sizes[31])
#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap ((uint8*)g_asset_ptrs[32]) #define kGameMode1B_EndingCinema_Tilemaps g_asset_ptrs[32]
#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_SIZE (g_asset_sizes[32]) #define kGameMode1B_EndingCinema_Tilemaps_SIZE (g_asset_sizes[32])
#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop ((uint8*)g_asset_ptrs[33]) #define kGameMode1B_EndingCinema_RowPointers ((uint16*)g_asset_ptrs[33])
#define kLoadOverworldLayer2AndEventsTilemaps_OverworldLayer2Tilemap_Prop_SIZE (g_asset_sizes[33]) #define kGameMode1B_EndingCinema_RowPointers_SIZE (g_asset_sizes[33])
#define kLoadOverworldLayer1AndEvents_DATA_0CF7DF ((uint8*)g_asset_ptrs[34]) #define kLevelInfo_05F000 g_asset_ptrs[34]
#define kLoadOverworldLayer1AndEvents_DATA_0CF7DF_SIZE (g_asset_sizes[34]) #define kLevelInfo_05F000_SIZE (g_asset_sizes[34])
#define kLineGuideSpeedTableData ((uint8*)g_asset_ptrs[35]) #define kLevelInfo_05F200 g_asset_ptrs[35]
#define kLineGuideSpeedTableData_SIZE (g_asset_sizes[35]) #define kLevelInfo_05F200_SIZE (g_asset_sizes[35])
#define kLevelData_Layer1(idx) FindInAssetArray(36, idx) #define kLevelInfo_05F400 g_asset_ptrs[36]
#define kEntranceData_Layer1(idx) FindInAssetArray(37, idx) #define kLevelInfo_05F400_SIZE (g_asset_sizes[36])
#define kChoclateIsland2_Layer1(idx) FindInAssetArray(38, idx) #define kLevelInfo_05F600 g_asset_ptrs[37]
#define kRollCallData_Layer1(idx) FindInAssetArray(39, idx) #define kLevelInfo_05F600_SIZE (g_asset_sizes[37])
#define kLevelData_Layer2(idx) FindInAssetArray(40, idx) #define kLoadLevel_DATA_05D608 g_asset_ptrs[38]
#define kLevelData_Layer2_IsBg ((uint8*)g_asset_ptrs[41]) #define kLoadLevel_DATA_05D608_SIZE (g_asset_sizes[38])
#define kLevelData_Layer2_IsBg_SIZE (g_asset_sizes[41]) #define kDisplayMessage_DATA_05A5D9 g_asset_ptrs[39]
#define kEntranceData_Layer2(idx) FindInAssetArray(42, idx) #define kDisplayMessage_DATA_05A5D9_SIZE (g_asset_sizes[39])
#define kEntranceData_Layer2_IsBg ((uint8*)g_asset_ptrs[43]) #define kOverworldLightningAndRandomCloudSpawning g_asset_ptrs[40]
#define kEntranceData_Layer2_IsBg_SIZE (g_asset_sizes[43]) #define kOverworldLightningAndRandomCloudSpawning_SIZE (g_asset_sizes[40])
#define kChoclateIsland2_Layer2(idx) FindInAssetArray(44, idx) #define kLevelNames ((uint16*)g_asset_ptrs[41])
#define kChoclateIsland2_Layer2_IsBg ((uint8*)g_asset_ptrs[45]) #define kLevelNames_SIZE (g_asset_sizes[41])
#define kChoclateIsland2_Layer2_IsBg_SIZE (g_asset_sizes[45]) #define kLineGuideSpeedTableData g_asset_ptrs[42]
#define kRollCallData_Layer2(idx) FindInAssetArray(46, idx) #define kLineGuideSpeedTableData_SIZE (g_asset_sizes[42])
#define kRollCallData_Layer2_IsBg ((uint8*)g_asset_ptrs[47]) #define kLevelData_Layer1(idx) FindInAssetArray(43, idx)
#define kRollCallData_Layer2_IsBg_SIZE (g_asset_sizes[47]) #define kEntranceData_Layer1(idx) FindInAssetArray(44, idx)
#define kBufferCreditsBackgrounds_Layer2(idx) FindInAssetArray(48, idx) #define kChoclateIsland2_Layer1(idx) FindInAssetArray(45, idx)
#define kBufferCreditsBackgrounds_Layer2_IsBg ((uint8*)g_asset_ptrs[49]) #define kRollCallData_Layer1(idx) FindInAssetArray(46, idx)
#define kBufferCreditsBackgrounds_Layer2_IsBg_SIZE (g_asset_sizes[49]) #define kLevelData_Layer2(idx) FindInAssetArray(47, idx)
#define kLoadLevelSpriteList(idx) FindInAssetArray(50, idx) #define kLevelData_Layer2_IsBg g_asset_ptrs[48]
#define kLoadLevel_SpriteDataPtrs ((uint16*)g_asset_ptrs[51]) #define kLevelData_Layer2_IsBg_SIZE (g_asset_sizes[48])
#define kLoadLevel_SpriteDataPtrs_SIZE (g_asset_sizes[51]) #define kEntranceData_Layer2(idx) FindInAssetArray(49, idx)
#define kFileSelectText_EraseFile ((uint8*)g_asset_ptrs[52]) #define kEntranceData_Layer2_IsBg g_asset_ptrs[50]
#define kFileSelectText_EraseFile_SIZE (g_asset_sizes[52]) #define kEntranceData_Layer2_IsBg_SIZE (g_asset_sizes[50])
#define kInitializeMode7TilemapsAndPalettes_TilemapData ((uint8*)g_asset_ptrs[53]) #define kChoclateIsland2_Layer2(idx) FindInAssetArray(51, idx)
#define kInitializeMode7TilemapsAndPalettes_TilemapData_SIZE (g_asset_sizes[53]) #define kChoclateIsland2_Layer2_IsBg g_asset_ptrs[52]
#define kLayer2EventData_TileEntries ((uint16*)g_asset_ptrs[54]) #define kChoclateIsland2_Layer2_IsBg_SIZE (g_asset_sizes[52])
#define kLayer2EventData_TileEntries_SIZE (g_asset_sizes[54]) #define kRollCallData_Layer2(idx) FindInAssetArray(53, idx)
#define kUpdateLevelName_LevelNameStrings ((uint8*)g_asset_ptrs[55]) #define kRollCallData_Layer2_IsBg g_asset_ptrs[54]
#define kUpdateLevelName_LevelNameStrings_SIZE (g_asset_sizes[55]) #define kRollCallData_Layer2_IsBg_SIZE (g_asset_sizes[54])
#define kGameMode25_ShowEnemyRollcallScreen_TileData ((uint8*)g_asset_ptrs[56]) #define kBufferCreditsBackgrounds_Layer2(idx) FindInAssetArray(55, idx)
#define kGameMode25_ShowEnemyRollcallScreen_TileData_SIZE (g_asset_sizes[56]) #define kBufferCreditsBackgrounds_Layer2_IsBg g_asset_ptrs[56]
#define kRom ((uint8*)g_asset_ptrs[57]) #define kBufferCreditsBackgrounds_Layer2_IsBg_SIZE (g_asset_sizes[56])
#define kRom_SIZE (g_asset_sizes[57]) #define kLvlSprBlob(addr) FindPtrInAsset(57, addr)
#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 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

View File

@ -16,9 +16,9 @@ SMW_SHA1 = {
SMW_SHA1_US : ('us', 'Super Mario World (USA)'), 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 global ROM
ROM = LoadedRom(filename, support_multilanguage) ROM = LoadedRom(filename, support_multilanguage, disable_hash_check)
return ROM return ROM
def get_byte(addr): def get_byte(addr):
@ -50,7 +50,7 @@ def get_word(addr):
class LoadedRom: 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) rom_path = self.__get_rom_path(path)
self.ROM = open(rom_path, 'rb').read() self.ROM = open(rom_path, 'rb').read()
@ -62,16 +62,8 @@ class LoadedRom:
entry = SMW_SHA1.get(hash) entry = SMW_SHA1.get(hash)
self.language = entry[0] if entry != None else None self.language = entry[0] if entry != None else None
if support_multilanguage: if not disable_hash_check and self.language != 'us':
if self.language == None: 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.");
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\"");
def get_byte(self, ea): def get_byte(self, ea):
assert (ea & 0x8000) assert (ea & 0x8000)

View File

@ -33,7 +33,7 @@ IF ERRORLEVEL 1 goto GETOUT
copy %SDL2%\lib\x64\SDL2.dll . copy %SDL2%\lib\x64\SDL2.dll .
echo Running... echo Running...
smw.exe smw.sfc smw.exe
:GETOUT :GETOUT
pause pause

View File

@ -106,6 +106,7 @@ int CpuOpcodeHook(uint32 addr) {
int i = RunPatchBugHook(addr); int i = RunPatchBugHook(addr);
if (i >= 0) return i; if (i >= 0) return i;
} }
printf("Bad hook at 0x%x!\n", addr);
assert(0); assert(0);
return 0; return 0;
} }
@ -126,7 +127,7 @@ static void VerifySnapshotsEq(Snapshot *b, Snapshot *a, Snapshot *prev) {
int j = 0; int j = 0;
for (size_t i = 0; i < 0x20000; i++) { for (size_t i = 0; i < 0x20000; i++) {
if (a->ram[i] != b->ram[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]) { if (((i & 1) == 0 || i < 0x10000) && a->ram[i + 1] != b->ram[i + 1]) {
fprintf(stderr, "0x%.6X: %.4X != %.4X (%.4X)\n", (int)i, fprintf(stderr, "0x%.6X: %.4X != %.4X (%.4X)\n", (int)i,
WORD(b->ram[i]), WORD(a->ram[i]), WORD(prev->ram[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); 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); bool loaded = snes_loadRom(g_snes, data, data_size);
if (!loaded) { if (!loaded) {
return NULL; 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]); printf("0x%x double patched!\n", g_rtl_game_info->patch_carrys[i]);
} }
} }
g_rtl_game_info->initialize();
PatchBugs(1, 0); PatchBugs(1, 0);
} else { } else {
g_runmode = RM_MINE; g_runmode = RM_MINE;
@ -291,7 +293,7 @@ Snes *SnesInit(const uint8 *data, int data_size) {
g_sram = g_snes->cart->ram; g_sram = g_snes->cart->ram;
g_sram_size = g_snes->cart->ramSize; g_sram_size = g_snes->cart->ramSize;
game_id = g_rtl_game_info->game_id; game_id = g_rtl_game_info->game_id;
g_rtl_game_info->initialize();
return g_snes; return g_snes;
} }
@ -305,12 +307,15 @@ void SaveBugSnapshot() {
g_got_mismatch_count = 5 * 60; g_got_mismatch_count = 5 * 60;
} }
int g_dbg_ctr_mine, g_dbg_ctr_theirs;
void RunOneFrameOfGame_Both(void) { void RunOneFrameOfGame_Both(void) {
g_ppu = g_snes->ppu; g_ppu = g_snes->ppu;
MakeSnapshot(&g_snapshot_before); MakeSnapshot(&g_snapshot_before);
// Run orig version then snapshot // Run orig version then snapshot
again_theirs: again_theirs:
g_dbg_ctr_mine = g_dbg_ctr_theirs = 0;
g_snes->runningWhichVersion = 1; g_snes->runningWhichVersion = 1;
g_rtl_game_info->run_frame_emulated(); g_rtl_game_info->run_frame_emulated();
MakeSnapshot(&g_snapshot_theirs); MakeSnapshot(&g_snapshot_theirs);

View File

@ -24,6 +24,7 @@ uint8 game_id;
bool g_playback_mode; bool g_playback_mode;
Ppu *g_ppu, *g_my_ppu; Ppu *g_ppu, *g_my_ppu;
Dma *g_dma; Dma *g_dma;
bool g_custom_music;
static uint8 *g_rtl_memory_ptr; static uint8 *g_rtl_memory_ptr;
static RunFrameFunc *g_rtl_runframe; static RunFrameFunc *g_rtl_runframe;
@ -708,8 +709,10 @@ static void RtlResetApuQueue_Locked(void) {
void RtlApuUpload(const uint8 *p) { void RtlApuUpload(const uint8 *p) {
RtlApuLock(); RtlApuLock();
g_spc_player->upload(g_spc_player, p); if (!g_custom_music) {
RtlResetApuQueue_Locked(); g_spc_player->upload(g_spc_player, p);
RtlResetApuQueue_Locked();
}
RtlApuUnlock(); 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]; 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) { void RtlUpdatePalette(const uint16 *src, int dst, int n) {
for(int i = 0; i < n; i++) for(int i = 0; i < n; i++)
g_ppu->cgram[dst + i] = src[i]; g_ppu->cgram[dst + i] = src[i];
@ -926,44 +935,3 @@ void SimpleHdma_DoLine(SimpleHdma *c) {
} }
c->rep_count--; 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;
}
}
}

View File

@ -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_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_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_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); } static inline const uint8 *RomPtrWithBank(uint8 bank, uint16_t addr) { return RomPtr((bank << 16) | addr); }
uint16 Mult8x8(uint8 a, uint8 b); uint16 Mult8x8(uint8 a, uint8 b);

View File

@ -1,14 +1,8 @@
#include "types.h" #include "types.h"
extern const uint16 kLevelTileAnimations_FrameData[208];
extern const uint8 kSlopeDataTables_SlopeType[33]; extern const uint8 kSlopeDataTables_SlopeType[33];
extern const uint8 kSlopeDataTables_ShapeOfSlope[512]; 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_Bowser[56];
extern const uint16 kGlobalPalettes_Background[]; 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_009F31[2];
extern const uint8 kGameModeXX_FadeInOrOut_DATA_009F33[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 kGameMode19_Cutscene_SkyColorSetting[8];
extern const uint8 kGenericSpriteToSpawnTable[19]; extern const uint8 kGenericSpriteToSpawnTable[19];
@ -30,4 +23,7 @@ extern const uint8 kBitTable_Bank05[8];
extern const uint8 kInitializeNormalSpriteRAMTables_Sprite190FVals[201]; extern const uint8 kInitializeNormalSpriteRAMTables_Sprite190FVals[201];
extern const uint16 kCircleCoordinates[256]; extern const uint16 kCircleCoordinates[256];
extern const uint16 kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[4];
extern const uint16 kDisplayMessage_SwitchBlockTileAndProperties[32];
extern const uint8 kDisplayMessage_SwitchBlockXAndYDisp[16];

View File

@ -1,3 +1,6 @@
#ifndef SMW_FUNCS_H_
#define SMW_FUNCS_H_
#include "smw_rtl.h" #include "smw_rtl.h"
typedef struct CollInfo { typedef struct CollInfo {
@ -29,6 +32,7 @@ typedef struct CheckPlatformCollRet {
const uint16 *GetLayerLayoutPtr(int layer, int top); const uint16 *GetLayerLayoutPtr(int layer, int top);
const uint16 *GetPlayerPalette(); const uint16 *GetPlayerPalette();
const uint16 *GetMap16RomAddr(uint8 bank, uint16_t addr); const uint16 *GetMap16RomAddr(uint8 bank, uint16_t addr);
const uint16 *Lm_GetMap16RomAddr(uint16 addr);
// Bank 0 // Bank 0
PairU16 BufferFileSelectText_009DB5(uint8 k); PairU16 BufferFileSelectText_009DB5(uint8 k);
@ -148,9 +152,9 @@ void GenericPage01Tile_00C0FB(GenTileArgs *gta, uint16 j);
void GenericPage01Tile(GenTileArgs *gta); void GenericPage01Tile(GenTileArgs *gta);
void GenericPage01Tile_Return00C1AB(void); void GenericPage01Tile_Return00C1AB(void);
void GenericPage01Tile_SetItemMemory(GenTileArgs *gta); void GenericPage01Tile_SetItemMemory(GenTileArgs *gta);
void GraphicsDecompressTo(const uint8 *src, uint8 *pdst); int DecompressTo(const uint8 *src, uint8 *pdst);
void GraphicsDecompressionRoutines_DecompressGFX32And33(void); void GraphicsDecompressionRoutines_DecompressGFX32And33(void);
const uint8 *GraphicsDecompress(uint8 j); uint8 *GraphicsDecompress(uint8 j);
void HandleMenuCursor_009E82(uint8 j); void HandleMenuCursor_009E82(uint8 j);
void HandleMenuCursor_009ED4(uint8 k); void HandleMenuCursor_009ED4(uint8 k);
void HandlePaletteFades_00AF35(bool run_code_at_end); void HandlePaletteFades_00AF35(bool run_code_at_end);
@ -326,7 +330,7 @@ void UploadBigLayer3LettersToVRAM(void);
void ConvertGFX27IntoNormallFormat(uint16 *dst); void ConvertGFX27IntoNormallFormat(uint16 *dst);
void UploadGraphicsFiles_Layer3(void); void UploadGraphicsFiles_Layer3(void);
void UploadGraphicsFiles(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 UploadLevelExAnimationData(void);
void UploadLevelAnimations_RedFlash(uint8 a, uint8 r0); void UploadLevelAnimations_RedFlash(uint8 a, uint8 r0);
void UploadLevelAnimations_YellowFlash(uint8 a); void UploadLevelAnimations_YellowFlash(uint8 a);
@ -685,7 +689,7 @@ void Spr0A5_Sparky(uint8 k);
void Spr0A7_IggyBall(uint8 k); void Spr0A7_IggyBall(uint8 k);
void Spr0A9_Reznor_Init(uint8 k); void Spr0A9_Reznor_Init(uint8 k);
void Spr0AA_Fishbone_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 Spr0AC_DownFirstWoodenSpike_Init(uint8 k);
void Spr0AD_UpDownFirstWoodenSpike_Init(uint8 k); void Spr0AD_UpDownFirstWoodenSpike_Init(uint8 k);
void Spr0B1_CreateEatBlock_Init(uint8 k); void Spr0B1_CreateEatBlock_Init(uint8 k);
@ -980,7 +984,8 @@ void MExtSpr0A_BooStream(uint8 k);
void MExtSpr0B_UnusedYoshiSmoke(uint8 k); void MExtSpr0B_UnusedYoshiSmoke(uint8 k);
void MExtSpr_Delete(uint8 k); void MExtSpr_Delete(uint8 k);
void ParseLevelSpriteList_Entry2(void); 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 ParseLevelSpriteList(void);
void ProcessBounceAndSmokeSprites_BounceSprites(uint8 k); void ProcessBounceAndSmokeSprites_BounceSprites(uint8 k);
void ProcessBounceAndSmokeSprites(void); void ProcessBounceAndSmokeSprites(void);
@ -1163,15 +1168,15 @@ void Spr09F_BanzaiBill_Draw(uint8 k);
void Spr09F_BanzaiBill_Sub(uint8 k); void Spr09F_BanzaiBill_Sub(uint8 k);
PointU8 Spr0A3_GreyChainedPlatform_02D813(uint8 k); PointU8 Spr0A3_GreyChainedPlatform_02D813(uint8 k);
PointU8 Spr0A3_GreyChainedPlatform_02D848(uint8 k); PointU8 Spr0A3_GreyChainedPlatform_02D848(uint8 k);
void Spr0DE_Load5Eeries(uint8 k, uint16 r0w, uint8 r2, const uint8 *edata); void Spr0DE_Load5Eeries(uint8 k, PointU16 pt, uint8 r2, const uint8 *edata);
void Spr0E0_Load3Platforms(uint16 r0w, uint8 r2, const uint8 *edata); void Spr0E0_Load3Platforms(PointU16 pt, uint8 r2, const uint8 *edata);
void Spr0E1_LoadBooCeiling(uint8 k, uint8 a, uint16 r0w, 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(uint8 k);
void SprXXX_Dolphins_Draw(uint8 k); void SprXXX_Dolphins_Draw(uint8 k);
void SprXXX_JumpingPiranhaPlant_02E17F(uint8 k); void SprXXX_JumpingPiranhaPlant_02E17F(uint8 k);
void SprXXX_JumpingPiranhaPlant_02E1C0(uint8 k, uint8 a); void SprXXX_JumpingPiranhaPlant_02E1C0(uint8 k, uint8 a);
void Spr04F_JumpingPiranhaPlant(uint8 k); 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_02EB3D(uint8 k, uint8 j);
void SprXXX_SuperKoopas_02EBB5(uint8 k, uint8 r0); void SprXXX_SuperKoopas_02EBB5(uint8 k, uint8 r0);
void SprXXX_SuperKoopas_02EBCA(uint8 k); 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_WaitAfterFall(uint8 k);
void Spr07C_PrincessPeach_WalkTowardsBro(uint8 k); void Spr07C_PrincessPeach_WalkTowardsBro(uint8 k);
void Spr0A0_ActivateBowserBattle_Init(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_03A4D2(uint8 k);
void Spr0A0_ActivateBowserBattle_03A4ED(uint8 k); void Spr0A0_ActivateBowserBattle_03A4ED(uint8 k);
void Spr0A0_ActivateBowserBattle_03A4FD(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 OWSpr0A_Boo(uint8 k);
void OwEventProcess00_CheckIfEventShouldRun(void); void OwEventProcess00_CheckIfEventShouldRun(void);
void OwEventProcess01_DestroyTileAnimation_04ED83(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 OwEventProcess01_DestroyTileAnimation_04EEAA(void);
void OwEventProcess02_SetEventTileIndexes(void); void OwEventProcess02_SetEventTileIndexes(void);
void OwEventProcess03_GetLayer2Tile_04EA62(void); void OwEventProcess03_GetLayer2Tile_04EA62(void);
@ -1496,7 +1501,7 @@ void OwEventProcess04_FadeInLayer2Tile_04EE30(void);
void OwEventProcess04_FadeInLayer2Tile(void); void OwEventProcess04_FadeInLayer2Tile(void);
void OwEventProcess05_GetLayer1Tile(void); void OwEventProcess05_GetLayer1Tile(void);
void OwEventProcess06_FadeInLayer1Tile(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 OwEventProcess07_SilentEventsAndEndOfEvent(void);
void OverworldLightningAndRandomCloudSpawning(void); void OverworldLightningAndRandomCloudSpawning(void);
void OverworldLightningAndRandomCloudSpawning_Return04F828(uint8 k); void OverworldLightningAndRandomCloudSpawning_Return04F828(uint8 k);
@ -1615,7 +1620,7 @@ void ScrollSecondInteractiveLayer(void);
void ShowCourseClearText(void); void ShowCourseClearText(void);
void LoadLevel_05DBAC(void); void LoadLevel_05DBAC(void);
void LoadLevel_HandleChocolateIsland2Gimmick(void); void LoadLevel_HandleChocolateIsland2Gimmick(void);
void LoadLevel(void); bool LoadLevel(void);
void Spr0E7_SpecialAutoScroll_Layer2(void); void Spr0E7_SpecialAutoScroll_Layer2(void);
void Spr0E7_SpecialAutoScroll(void); void Spr0E7_SpecialAutoScroll(void);
void Spr0E9_Layer2Smash(void); void Spr0E9_Layer2Smash(void);
@ -1956,4 +1961,177 @@ void UndergroundObj3C_VerySteepSlope_VerySteepLeftSlope(void);
void UndergroundObj3C_VerySteepSlope_VerySteepRightSlope(void); void UndergroundObj3C_VerySteepSlope_VerySteepRightSlope(void);
void UndergroundObj3D_CeilingLedge(uint8 k); void UndergroundObj3D_CeilingLedge(uint8 k);
void UndergroundObj3E_CeilingEdges(uint8 k); void UndergroundObj3E_CeilingEdges(uint8 k);
void UndergroundObj3F_SolidDirt(uint8 k); 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_

2513
src/lm.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -826,19 +826,41 @@ static void HandleGamepadAxisInput(int gamepad_id, int axis, int value) {
const uint8 *g_asset_ptrs[kNumberOfAssets]; const uint8 *g_asset_ptrs[kNumberOfAssets];
uint32 g_asset_sizes[kNumberOfAssets]; uint32 g_asset_sizes[kNumberOfAssets];
static void LoadAssets() { static bool VerifyAssetsFile(const uint8 *data, size_t length) {
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 const char kAssetsSig[] = { kAssets_Sig }; static const char kAssetsSig[] = { kAssets_Sig };
if (length < 16 + 32 + 32 + 8 + kNumberOfAssets * 4 || if (length < 16 + 32 + 32 + 8 + kNumberOfAssets * 4 ||
memcmp(data, kAssetsSig, 48) != 0 || memcmp(data, kAssetsSig, 48) != 0 ||
*(uint32*)(data + 80) != kNumberOfAssets) *(uint32 *)(data + 80) != kNumberOfAssets)
Die("Invalid assets file"); 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); 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); 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 // Go some steps up and find smw.ini
static void SwitchDirectory(void) { static void SwitchDirectory(void) {
char buf[4096]; char buf[4096];

View File

@ -38,7 +38,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
@ -164,6 +164,7 @@
<ClCompile Include="common_rtl.c" /> <ClCompile Include="common_rtl.c" />
<ClCompile Include="config.c" /> <ClCompile Include="config.c" />
<ClCompile Include="glsl_shader.c" /> <ClCompile Include="glsl_shader.c" />
<ClCompile Include="lm.c" />
<ClCompile Include="main.c" /> <ClCompile Include="main.c" />
<ClCompile Include="opengl.c" /> <ClCompile Include="opengl.c" />
<ClCompile Include="platform\win32\volume_control.c" /> <ClCompile Include="platform\win32\volume_control.c" />

View File

@ -10,9 +10,6 @@
<Filter Include="Common\Shader"> <Filter Include="Common\Shader">
<UniqueIdentifier>{2b72ed96-9194-4c2c-b1e5-15445f0a9550}</UniqueIdentifier> <UniqueIdentifier>{2b72ed96-9194-4c2c-b1e5-15445f0a9550}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Common\Snes">
<UniqueIdentifier>{e1763dbc-4fb3-417f-ad1a-8436411c3b7a}</UniqueIdentifier>
</Filter>
<Filter Include="Smw"> <Filter Include="Smw">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
@ -20,43 +17,46 @@
<Filter Include="Smb Lost Levels"> <Filter Include="Smb Lost Levels">
<UniqueIdentifier>{c20be95b-4f11-4834-a006-bfb273e4bc0b}</UniqueIdentifier> <UniqueIdentifier>{c20be95b-4f11-4834-a006-bfb273e4bc0b}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Snes">
<UniqueIdentifier>{e1763dbc-4fb3-417f-ad1a-8436411c3b7a}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="smw_spc_player.c"> <ClCompile Include="smw_spc_player.c">
<Filter>Smw</Filter> <Filter>Smw</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\apu.c"> <ClCompile Include="snes\apu.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\cart.c"> <ClCompile Include="snes\cart.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\cpu.c"> <ClCompile Include="snes\cpu.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\dma.c"> <ClCompile Include="snes\dma.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\dsp.c"> <ClCompile Include="snes\dsp.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\input.c"> <ClCompile Include="snes\input.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\ppu.c"> <ClCompile Include="snes\ppu.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\snes.c"> <ClCompile Include="snes\snes.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\snes_other.c"> <ClCompile Include="snes\snes_other.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\spc.c"> <ClCompile Include="snes\spc.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="tracing.c"> <ClCompile Include="tracing.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="glsl_shader.c"> <ClCompile Include="glsl_shader.c">
<Filter>Common\Shader</Filter> <Filter>Common\Shader</Filter>
@ -101,7 +101,7 @@
<Filter>Smw</Filter> <Filter>Smw</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="snes\ppu_old.c"> <ClCompile Include="snes\ppu_old.c">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\smb1\smb1_00.c"> <ClCompile Include="..\smb1\smb1_00.c">
<Filter>Smb1</Filter> <Filter>Smb1</Filter>
@ -157,6 +157,9 @@
<ClCompile Include="..\smb1\smb1_spc_player.c"> <ClCompile Include="..\smb1\smb1_spc_player.c">
<Filter>Smb1</Filter> <Filter>Smb1</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="lm.c">
<Filter>Smw</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="funcs.h"> <ClInclude Include="funcs.h">
@ -169,40 +172,40 @@
<Filter>Smw</Filter> <Filter>Smw</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\apu.h"> <ClInclude Include="snes\apu.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\cart.h"> <ClInclude Include="snes\cart.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\cpu.h"> <ClInclude Include="snes\cpu.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\dma.h"> <ClInclude Include="snes\dma.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\dsp.h"> <ClInclude Include="snes\dsp.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\dsp_regs.h"> <ClInclude Include="snes\dsp_regs.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\input.h"> <ClInclude Include="snes\input.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\ppu.h"> <ClInclude Include="snes\ppu.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\snes.h"> <ClInclude Include="snes\snes.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\spc.h"> <ClInclude Include="snes\spc.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="tracing.h"> <ClInclude Include="tracing.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\saveload.h"> <ClInclude Include="snes\saveload.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="glsl_shader.h"> <ClInclude Include="glsl_shader.h">
<Filter>Common\Shader</Filter> <Filter>Common\Shader</Filter>
@ -211,7 +214,7 @@
<Filter>Common\Shader</Filter> <Filter>Common\Shader</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="snes\snes_regs.h"> <ClInclude Include="snes\snes_regs.h">
<Filter>Common\Snes</Filter> <Filter>Snes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\smb1\smb1_variables.h"> <ClInclude Include="..\smb1\smb1_variables.h">
<Filter>Smb1</Filter> <Filter>Smb1</Filter>

File diff suppressed because it is too large Load Diff

View File

@ -243,7 +243,7 @@ void (*kSprStatus08SpriteNormalPtrs[201])(uint8 k) = {
&Spr018_SurfaceJumpingCheepCheep, &Spr018_SurfaceJumpingCheepCheep,
&Spr03E_PSwitch, &Spr03E_PSwitch,
&Spr01A_ClassicPiranhaPlant, &Spr01A_ClassicPiranhaPlant,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr01C_BulletBill, &Spr01C_BulletBill,
&Spr01D_HoppingFlame, &Spr01D_HoppingFlame,
&Spr01E_Lakitu, &Spr01E_Lakitu,
@ -297,7 +297,7 @@ void (*kSprStatus08SpriteNormalPtrs[201])(uint8 k) = {
&Spr04E_LedgeMontyMole, &Spr04E_LedgeMontyMole,
&Spr04F_JumpingPiranhaPlant, &Spr04F_JumpingPiranhaPlant,
&Spr04F_JumpingPiranhaPlant, &Spr04F_JumpingPiranhaPlant,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr052_MovingLedgeHole, &Spr052_MovingLedgeHole,
&SprStatus08_Return, &SprStatus08_Return,
&Spr054_ClimbingNetDoor, &Spr054_ClimbingNetDoor,
@ -338,9 +338,9 @@ void (*kSprStatus08SpriteNormalPtrs[201])(uint8 k) = {
&Spr077_Feather, &Spr077_Feather,
&SprXXX_PowerUps_StarEntry, &SprXXX_PowerUps_StarEntry,
&Spr079_VineHead, &Spr079_VineHead,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr07B_GoalTape, &Spr07B_GoalTape,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr080_Key, &Spr080_Key,
&Spr080_Key, &Spr080_Key,
&Spr080_Key, &Spr080_Key,
@ -376,47 +376,47 @@ void (*kSprStatus08SpriteNormalPtrs[201])(uint8 k) = {
&Spr09D_BubbleWithSprite, &Spr09D_BubbleWithSprite,
&Spr09E_BallNChain, &Spr09E_BallNChain,
&Spr09E_BallNChain, &Spr09E_BallNChain,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr09E_BallNChain, &Spr09E_BallNChain,
&SprXXX_BuoyantPlatformsAndMine_SpikeBallEntry, &SprXXX_BuoyantPlatformsAndMine_SpikeBallEntry,
&Spr0A5_Sparky, &Spr0A5_Sparky,
&Spr0A5_Sparky, &Spr0A5_Sparky,
&Spr0A7_IggyBall, &Spr0A7_IggyBall,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&SprXXX_NonBossBoos_BooEntry, &SprXXX_NonBossBoos_BooEntry,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0B4_NonLineGuideGrinder, &Spr0B4_NonLineGuideGrinder,
&Spr033_Podoboo, &Spr033_Podoboo,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
&Spr0A0_ActivateBowserBattle, &HandleExtraSprites,
}; };
@ -2044,39 +2044,35 @@ uint8 HandleNormalSpriteLevelColl_01944D(uint8 k, uint8 j, PointU16 *pt_out) {
pt_out->x = GetSprXPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingX[j]; pt_out->x = GetSprXPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingX[j];
if ((pt_out->x >> 8) < 2) { if ((pt_out->x >> 8) < 2) {
r0 |= (uint8)pt_out->x >> 4; r0 |= (uint8)pt_out->x >> 4;
uint8 v4 = kLevelDataLayoutTables_EightBitLo_Vertical[r13]; uint16 pp = GetLevelLayoutPtr_Vertical(r13 + (misc_scratch7e185e ? 14 : 0));
uint8 v5 = kLevelDataLayoutTables_EightBitHi_Vertical[r13]; return HandleNormalSpriteLevelColl_019523(pp + PAIR16(pt_out->x >> 8, r0));
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));
} }
} }
LABEL_9: LABEL_9:
blocks_currently_processed_map16_tile_lo = 0;
sprites_distance_to_snap_down_to_nearest_tile = 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; return 0;
} }
uint16 r12w = GetSprYPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingY[j]; uint16 r12w = GetSprYPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingY[j];
pt_out->y = r12w; pt_out->y = r12w;
if (r12w >= 0x1B0) if (r12w >= (g_lunar_magic ? lm_level_height : 0x1B0))
goto LABEL_9; goto LABEL_9;
pt_out->x = GetSprXPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingX[j]; pt_out->x = GetSprXPos(k) + kHandleNormalSpriteLevelColl_SpriteObjClippingX[j];
int xx = pt_out->x >> 8; int xx = pt_out->x >> 8;
if ((int8)xx < 0 || (uint8)xx >= misc_screens_in_lvl) if ((int8)xx < 0 || (uint8)xx >= misc_screens_in_lvl)
goto LABEL_9; goto LABEL_9;
uint8 r0 = (r12w & 0xF0) | ((uint8)pt_out->x >> 4); uint8 r0 = (r12w & 0xF0) | ((uint8)pt_out->x >> 4);
uint16 v10 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[xx], kLevelDataLayoutTables_EightBitLo_Horizontal[xx]); uint16 v10 = GetLevelLayoutPtr_Horizontal(xx + (misc_scratch7e185e ? 16 : 0));
if (misc_scratch7e185e) {
v10 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[xx + 16], kLevelDataLayoutTables_EightBitLo_Horizontal[xx + 16]);
}
return HandleNormalSpriteLevelColl_019523(PAIR16(r12w >> 8, r0) + v10); return HandleNormalSpriteLevelColl_019523(PAIR16(r12w >> 8, r0) + v10);
} }
uint8 HandleNormalSpriteLevelColl_019523(uint16 r5) { // 019523 uint8 HandleNormalSpriteLevelColl_019523(uint16 r5) { // 019523
blocks_currently_processed_map16_tile_lo = g_ram[r5]; 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 void SprStatus09_Stunned(uint8 k) { // 01953c
@ -3695,8 +3691,9 @@ void SubOffscreen_Bank01_01AC33(uint8 k, uint8 r3) { // 01ac33
} }
} }
} else { } else {
uint16 y = GetSprYPos(k) + 80; uint16 y = GetSprYPos(k);
if (!sign8((y >> 8) - 2)) { bool want_erase = g_lunar_magic ? LmHook_WantEraseSprite(k, y) : !sign8(((y + 80) >> 8) - 2);
if (want_erase) {
SubOffscreen_Bank01_EraseSprite(k); SubOffscreen_Bank01_EraseSprite(k);
} else if ((spr_property_bits167a[k] & 4) == 0) { } else if ((spr_property_bits167a[k] & 4) == 0) {
uint8 v4 = r3 | counter_global_frames & 1; 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); SetHiLo(&spr_table151c[k], &spr_table00c2[k], GetSprXPos(k) - 8);
spr_table1528[k] = spr_ypos_lo[k]; spr_table1528[k] = spr_ypos_lo[k];
uint8 v2 = spr_ypos_hi[k]; uint8 v2 = spr_ypos_hi[k];
spr_table187b[k] = v2; if (!g_lunar_magic) {
v2 &= 1; spr_table187b[k] = v2;
spr_ypos_hi[k] = v2; v2 &= 1;
spr_ypos_hi[k] = v2;
}
spr_table1534[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); uint8 v3 = r0w & 0xF0 | (r2 >> 4);
uint16 r5; uint16 r5;
if ((misc_level_layout_flags & 1) != 0) { 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 { } 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]; blocks_currently_processed_map16_tile_lo = g_ram[r5];
return kSprXXX_LineGuided_DATA_018000[v4 & 7] & g_ram[r5 + 0x10000]; return kSprXXX_LineGuided_DATA_018000[v4 & 7] & g_ram[r5 + 0x10000];

View File

@ -1628,13 +1628,8 @@ void GetBounceSpriteLevelCollisionMap16ID(uint8 k) { // 029265
return; return;
uint8 r2 = bounce_spr_xpos_hi[k]; uint8 r2 = bounce_spr_xpos_hi[k];
r0 |= r1 >> 4; r0 |= r1 >> 4;
uint8 v3 = kLevelDataLayoutTables_EightBitLo_Vertical[r3]; uint16 v34 = GetLevelLayoutPtr_Vertical(r3 + (r15 ? 14 : 0));
uint8 v4 = kLevelDataLayoutTables_EightBitHi_Vertical[r3]; r5w = PAIR16(r2, r0) + v34;
if (r15) {
v3 = kLevelDataLayoutTables_EightBitLo_Vertical[r3 + 14];
v4 = kLevelDataLayoutTables_EightBitHi_Vertical[r3 + 14];
}
r5w = PAIR16(r2, r0) + PAIR16(v4, v3);
} else { } else {
uint16 t = PAIR16(bounce_spr_ypos_hi[k], bounce_spr_ypos_lo[k]) - 3; uint16 t = PAIR16(bounce_spr_ypos_hi[k], bounce_spr_ypos_lo[k]) - 3;
uint8 r0 = t & ~0xf; uint8 r0 = t & ~0xf;
@ -1648,14 +1643,8 @@ void GetBounceSpriteLevelCollisionMap16ID(uint8 k) { // 029265
return; return;
uint8 r3 = bounce_spr_xpos_hi[k]; uint8 r3 = bounce_spr_xpos_hi[k];
r0 |= r1 >> 4; r0 |= r1 >> 4;
uint8 v6 = v5; uint16 v78 = GetLevelLayoutPtr_Horizontal(v5 + (r15 ? 16 : 0));
uint8 v7 = kLevelDataLayoutTables_EightBitLo_Horizontal[v5]; r5w = PAIR16(r2, r0) + v78;
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);
} }
uint8 v9 = sprites_currently_processed_misc_sprite; uint8 v9 = sprites_currently_processed_misc_sprite;
blocks_currently_processed_map16_tile_lo = g_ram[r5w]; blocks_currently_processed_map16_tile_lo = g_ram[r5w];
@ -1816,17 +1805,12 @@ void HandleCapeLevelColl_029540(uint8 r15) { // 029540
if ((uint8)(posx >> 8) < 2) { if ((uint8)(posx >> 8) < 2) {
HIBYTE(blocks_xpos) = r2 = (posx >> 8); HIBYTE(blocks_xpos) = r2 = (posx >> 8);
r0 |= r1 >> 4; r0 |= r1 >> 4;
uint8 v2 = kLevelDataLayoutTables_EightBitLo_Vertical[r3]; uint16 pp = GetLevelLayoutPtr_Vertical(r3 + (r15 ? 14 : 0));
uint8 v3 = kLevelDataLayoutTables_EightBitHi_Vertical[r3]; r5 = pp + PAIR16(r2, r0);
if (r15) {
v2 = kLevelDataLayoutTables_EightBitLo_Vertical[r3 + 14];
v3 = kLevelDataLayoutTables_EightBitHi_Vertical[r3 + 14];
}
r5 = PAIR16(r2, r0) + PAIR16(v3, v2);
LABEL_17: LABEL_17:
blocks_currently_processed_map16_tile_lo = g_ram[r5]; blocks_currently_processed_map16_tile_lo = g_ram[r5];
uint8 *v8 = &g_ram[r5 + 0x10000]; uint8 v8 = g_ram[r5 + 0x10000];
if (ModifyMap16IDForSpecialBlocks(*v8)) { if (LmHook_ModifyMap16IDForSpecialBlocks(v8)) {
LOBYTE(misc_current_layer_being_processed) = r15; LOBYTE(misc_current_layer_being_processed) = r15;
CheckIfBlockWasHit(blocks_currently_processed_map16_tile_lo, 0); CheckIfBlockWasHit(blocks_currently_processed_map16_tile_lo, 0);
} }
@ -1842,13 +1826,8 @@ LABEL_17:
if ((uint8)(posx >> 8) < misc_screens_in_lvl) { if ((uint8)(posx >> 8) < misc_screens_in_lvl) {
HIBYTE(blocks_xpos) = r3 = posx >> 8; HIBYTE(blocks_xpos) = r3 = posx >> 8;
r0 |= r1 >> 4; r0 |= r1 >> 4;
uint8 v6 = kLevelDataLayoutTables_EightBitLo_Horizontal[r3]; uint16 pp = GetLevelLayoutPtr_Horizontal(r3 + (r15 ? 16 : 0));
uint8 v7 = kLevelDataLayoutTables_EightBitHi_Horizontal[r3]; r5 = pp + PAIR16(r2, r0);
if (r15) {
v6 = kLevelDataLayoutTables_EightBitLo_Horizontal[r3 + 16];
v7 = kLevelDataLayoutTables_EightBitHi_Horizontal[r3 + 16];
}
r5 = PAIR16(r2, r0) + PAIR16(v7, v6);
goto LABEL_17; goto LABEL_17;
} }
} }
@ -2910,20 +2889,21 @@ uint8 HandleExtendedSpriteLevelColl_02A611(uint8 k, uint8 r15, ExtCollOut *out)
return 0; return 0;
HIBYTE(blocks_xpos) = r2 = (t >> 8); HIBYTE(blocks_xpos) = r2 = (t >> 8);
r0 |= r1 >> 4; r0 |= r1 >> 4;
uint8 v4 = kLevelDataLayoutTables_EightBitLo_Vertical[r3]; uint16 pp = GetLevelLayoutPtr_Vertical(r3 + (r15 ? 14 : 0));
uint8 v5 = kLevelDataLayoutTables_EightBitHi_Vertical[r3]; r5 = pp + PAIR16(r2, r0);
if (r15) {
v4 = kLevelDataLayoutTables_EightBitLo_Vertical[r3 + 14];
v5 = kLevelDataLayoutTables_EightBitHi_Vertical[r3 + 14];
}
r5 = PAIR16(r2, r0) + PAIR16(v5, v4);
} else { } else {
uint16 t = PAIR16(ext_spr_ypos_hi[k], ext_spr_ypos_lo[k]) + 8; uint16 t = PAIR16(ext_spr_ypos_hi[k], ext_spr_ypos_lo[k]) + 8;
blocks_ypos = t; blocks_ypos = t;
r0 = t & 0xf0; t &= 0xfff0;
r0 = t;
r2 = t >> 8; r2 = t >> 8;
if ((uint8)(r0 - mirror_current_layer1_ypos) >= 0xF0) if (g_lunar_magic) {
return 0; 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; uint16 xpos = PAIR16(ext_spr_xpos_hi[k], ext_spr_xpos_lo[k]) + 4;
LOBYTE(blocks_xpos) = r1 = xpos; LOBYTE(blocks_xpos) = r1 = xpos;
if ((xpos >> 8) >= misc_screens_in_lvl) if ((xpos >> 8) >= misc_screens_in_lvl)
@ -2931,17 +2911,12 @@ uint8 HandleExtendedSpriteLevelColl_02A611(uint8 k, uint8 r15, ExtCollOut *out)
r3 = (xpos >> 8); r3 = (xpos >> 8);
HIBYTE(blocks_xpos) = (xpos >> 8); HIBYTE(blocks_xpos) = (xpos >> 8);
r0 |= r1 >> 4; r0 |= r1 >> 4;
uint8 v10 = kLevelDataLayoutTables_EightBitLo_Horizontal[r3]; uint16 pp = GetLevelLayoutPtr_Horizontal(r3 + (r15 ? 16 : 0));
uint8 v11 = kLevelDataLayoutTables_EightBitHi_Horizontal[r3]; r5 = pp + PAIR16(r2, r0);
if (r15) {
v10 = kLevelDataLayoutTables_EightBitLo_Horizontal[r3 + 16];
v11 = kLevelDataLayoutTables_EightBitHi_Horizontal[r3 + 16];
}
r5 = PAIR16(r2, r0) + PAIR16(v11, v10);
} }
k = spr_current_slotid; k = spr_current_slotid;
blocks_currently_processed_map16_tile_lo = g_ram[r5]; blocks_currently_processed_map16_tile_lo = g_ram[r5];
if (!ModifyMap16IDForSpecialBlocks(g_ram[r5 + 0x10000])) if (!LmHook_ModifyMap16IDForSpecialBlocks(g_ram[r5 + 0x10000]))
return 0; return 0;
if (blocks_currently_processed_map16_tile_lo < 0x11) if (blocks_currently_processed_map16_tile_lo < 0x11)
return (blocks_ypos & 0xF) < 6; return (blocks_ypos & 0xF) < 6;
@ -2984,7 +2959,7 @@ void ParseLevelSpriteList() { // 02a7fc
void ParseLevelSpriteList_Entry2() { // 02a802 void ParseLevelSpriteList_Entry2() { // 02a802
int8 v0; int8 v0;
uint8 r0; uint8 r0, r1;
if (misc_level_layout_flags & 1) { if (misc_level_layout_flags & 1) {
uint16 t = kParseLevelSpriteList_DATA_02A7F6[camera_layer1_scrolling_direction] + (uint8)mirror_current_layer1_ypos; uint16 t = kParseLevelSpriteList_DATA_02A7F6[camera_layer1_scrolling_direction] + (uint8)mirror_current_layer1_ypos;
r0 = t & 0xF0; r0 = t & 0xF0;
@ -2994,131 +2969,136 @@ void ParseLevelSpriteList_Entry2() { // 02a802
r0 = t & 0xF0; r0 = t & 0xF0;
v0 = HIBYTE(mirror_current_layer1_xpos) + (t >> 8); v0 = HIBYTE(mirror_current_layer1_xpos) + (t >> 8);
} }
int8 v1 = kParseLevelSpriteList_DATA_02A7F9[camera_layer1_scrolling_direction] + v0; r1 = kParseLevelSpriteList_DATA_02A7F9[camera_layer1_scrolling_direction] + v0;
if (v1 >= 0) {
uint8 r1 = v1; if (g_lunar_magic) {
ParseLevelSpriteList_LoadSpriteLoopStrt(0, 1, r0 | r1 << 8); 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(); const uint8 *p = GetSpriteListPtr();
uint8 r2;
while (1) { while (1) {
// printf("M: Load sprites offs %d: 0x%x\n", j, r0w); // printf("M: Load sprites offs %d: 0x%x\n", j, r0w);
const uint8 *v2 = &p[j]; const uint8 *v2 = &p[j];
if (*v2 == 0xFF) if (*v2 == 0xFF)
break; break;
r2 = (8 * *v2) & 0x10; uint8 v4 = (8 * *v2) & 0x10 | p[j + 1] & 0xF;
uint8 v4 = r2 | p[j + 1] & 0xF; if (v4 >= (pt.x >> 8)) {
bool v5 = v4 < (r0w >> 8); if (v4 > (pt.x >> 8))
int8 v6 = v4 - (r0w >> 8); return;
if (v5) if ((p[j + 1] & 0xF0) == (uint8)pt.x && !sprites_load_status[spr_index]) {
goto LABEL_3; if (LoadOneSprite(p + j, spr_index, pt))
if (v6) return;
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;
} }
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; 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; flag_run_cluster_sprites = 1;
switch (a) { switch (a) {
case 0xE4: case 0xE4:
@ -3197,8 +3177,8 @@ void Spr0E1_LoadBooCeiling(uint8 k, uint8 a, uint16 r0w, uint8 r2, const uint8 *
uint8 v18 = *edata; uint8 v18 = *edata;
*(&cluster_spr04_boo_ring1_center_ypos_lo + v11) = v18 & 0xF0; *(&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_ypos_hi + v11) = v18 & 1;
*(&cluster_spr04_boo_ring1_center_xpos_lo + v11) = r0w; *(&cluster_spr04_boo_ring1_center_xpos_lo + v11) = pt.x;
*(&cluster_spr04_boo_ring1_center_xpos_hi + v11) = r0w >> 8; *(&cluster_spr04_boo_ring1_center_xpos_hi + v11) = pt.x >> 8;
*(&cluster_spr04_boo_ring1_offscreen_flag + v11) = 0; *(&cluster_spr04_boo_ring1_offscreen_flag + v11) = 0;
*(&cluster_spr04_boo_ring_unused_ring1_level_list_index + v11) = r2; *(&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 r2 = k;
uint8 r4 = a; uint8 r4 = a;
uint8 v3 = 7; uint8 v3 = 7;
@ -3244,12 +3224,12 @@ void SprXXX_LoadShooter(uint8 k, uint8 a, uint16 r0w, const uint8 *edata) { //
uint8 v7 = *edata; uint8 v7 = *edata;
shooter_spr_xpos_lo[v3] = v7 & 0xF0; shooter_spr_xpos_lo[v3] = v7 & 0xF0;
shooter_spr_xpos_hi[v3] = v7 & 1; 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 { } else {
uint8 v8 = *edata; uint8 v8 = *edata;
shooter_spr_ypos_lo[v3] = v8 & 0xF0; shooter_spr_ypos_lo[v3] = v8 & 0xF0;
shooter_spr_ypos_hi[v3] = v8 & 1; 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_unused_level_list_index[v3] = r2;
shooter_spr_shoot_timer[v3] = 16; shooter_spr_shoot_timer[v3] = 16;
@ -3287,6 +3267,8 @@ void LoadSpritesOnLevelLoad() { // 02ac5c
if (misc_level_layout_flags & 1) { if (misc_level_layout_flags & 1) {
uint8 v5 = camera_layer1_scrolling_direction; uint8 v5 = camera_layer1_scrolling_direction;
camera_layer1_scrolling_direction = 1; camera_layer1_scrolling_direction = 1;
if (g_lunar_magic)
LmHook_LoadSpritesOnLevelLoad();
uint16 old_y = mirror_current_layer1_ypos; uint16 old_y = mirror_current_layer1_ypos;
mirror_current_layer1_ypos -= 96; mirror_current_layer1_ypos -= 96;
misc_scratch7e18b6 = 0; misc_scratch7e18b6 = 0;
@ -3300,6 +3282,8 @@ void LoadSpritesOnLevelLoad() { // 02ac5c
} else { } else {
uint8 v6 = camera_layer1_scrolling_direction; uint8 v6 = camera_layer1_scrolling_direction;
camera_layer1_scrolling_direction = 1; camera_layer1_scrolling_direction = 1;
if (g_lunar_magic)
LmHook_LoadSpritesOnLevelLoad();
uint16 old_x = mirror_current_layer1_xpos; uint16 old_x = mirror_current_layer1_xpos;
mirror_current_layer1_xpos -= 96; mirror_current_layer1_xpos -= 96;
misc_scratch7e18b6 = 0; 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; uint8 v3 = *edata;
uint16 ypos = PAIR16(v3 & 1, v3 & 0xF0); uint16 ypos = pt.y + PAIR16(v3 & 1, v3 & 0xF0);
uint8 r4 = 2; uint8 r4 = 2;
do { do {
uint8 j = FindFreeNormalSpriteSlot_HighPriority(); 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_current_status[j] = 1;
spr_spriteid[j] = -93; spr_spriteid[j] = -93;
InitializeNormalSpriteRAMTables(j); InitializeNormalSpriteRAMTables(j);
SetSprXYPos(j, r0w, ypos); SetSprXYPos(j, pt.x, ypos);
uint8 v2 = r4; uint8 v2 = r4;
spr_table1602[v1] = kSpr0E0_Load3Platforms_InitialAngleLo[r4]; spr_table1602[v1] = kSpr0E0_Load3Platforms_InitialAngleLo[r4];
spr_table151c[v1] = kSpr0E0_Load3Platforms_InitialAngleHi[v2]; 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); } 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; uint8 v5 = *edata;
uint16 ypos = PAIR16(v5 & 1, v5 & 0xF0); uint16 ypos = pt.y + PAIR16(v5 & 1, v5 & 0xF0);
uint8 r4 = 4; uint8 r4 = 4;
do { do {
uint8 j = FindFreeNormalSpriteSlot_HighPriority(); 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_current_status[j] = 8;
spr_spriteid[j] = 57; spr_spriteid[j] = 57;
InitializeNormalSpriteRAMTables(j); 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_yspeed[j] = kSpr0DE_Load5Eeries_InitialYSpeed[v3];
spr_table00c2[j] = kSpr0DE_Load5Eeries_InitialVerticalDirection[v3]; spr_table00c2[j] = kSpr0DE_Load5Eeries_InitialVerticalDirection[v3];
if (v3 == 4) if (v3 == 4)
@ -4072,15 +4056,13 @@ void CheckPlayerToNormalSpriteColl_02B9D9(uint8 j) { // 02b9d9
void CheckBerryTileCollisionWithYoshiTongue(CollInfo *ci) { // 02b9fa void CheckBerryTileCollisionWithYoshiTongue(CollInfo *ci) { // 02b9fa
uint8 r15 = 0; uint8 r15 = 0;
uint8 r4 = ci->r1 & 0xF0; 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; uint8 r13 = ci->r9;
HIBYTE(yoshi_ypos) = ci->r9; HIBYTE(yoshi_ypos) = ci->r9;
if (ci->r8 < misc_screens_in_lvl) { if (ci->r8 < misc_screens_in_lvl) {
r4 |= ci->r0 >> 4; r4 |= ci->r0 >> 4;
uint16 vv = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[ci->r8], kLevelDataLayoutTables_EightBitLo_Horizontal[ci->r8]); uint16 vv = GetLevelLayoutPtr_Horizontal(ci->r8 + (r15 ? 16 : 0));
if (r15)
vv = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[ci->r8 + 16], kLevelDataLayoutTables_EightBitLo_Horizontal[ci->r8 + 16]);
uint16 r5 = PAIR16(r13, r4) + vv; uint16 r5 = PAIR16(r13, r4) + vv;
blocks_currently_processed_map16_tile_lo = g_ram[r5]; 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) { 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; return;
} }
if (r3 != 4) { if (r3 != 4) {
uint16 ypos = GetSprYPos(k) + 0x50; uint16 y = GetSprYPos(k);
if (!sign8((ypos >> 8) - 2)) { bool want_erase = g_lunar_magic ? LmHook_WantEraseSprite(k, y) : !sign8(((y + 80) >> 8) - 2);
if (want_erase) {
LABEL_10: LABEL_10:
SubOffscreen_Bank02_EraseSprite(k); SubOffscreen_Bank02_EraseSprite(k);
return; return;
@ -5421,8 +5404,9 @@ void Spr035_Yoshi_02D0E6(uint8 k) { // 02d0e6
uint8 r15 = 0; uint8 r15 = 0;
uint16 t = GetSprYPos(k) + 8; uint16 t = GetSprYPos(k) + 8;
LOBYTE(yoshi_ypos) = t; LOBYTE(yoshi_ypos) = t;
uint8 r0 = t & 0xF0; t &= 0xfff0;
if (t < 0x200) { uint8 r0 = t;
if (t < (g_lunar_magic ? lm_level_height : 0x200)) {
uint8 r2 = t >> 8; uint8 r2 = t >> 8;
HIBYTE(yoshi_ypos) = t >> 8; HIBYTE(yoshi_ypos) = t >> 8;
uint8 v2 = spr_table157c[k]; uint8 v2 = spr_table157c[k];
@ -5434,10 +5418,8 @@ void Spr035_Yoshi_02D0E6(uint8 k) { // 02d0e6
uint8 r3 = (xpos >> 8); uint8 r3 = (xpos >> 8);
r0 |= r1 >> 4; r0 |= r1 >> 4;
uint8 v6 = (xpos >> 8); uint8 v6 = (xpos >> 8);
uint16 v8 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[v6], kLevelDataLayoutTables_EightBitLo_Horizontal[v6]); uint16 pp = GetLevelLayoutPtr_Horizontal(v6 + (r15 ? 16 : 0));
if (r15) uint16 r5 = pp + PAIR16(r2, r0);
v8 = PAIR16(kLevelDataLayoutTables_EightBitHi_Horizontal[v6 + 16], kLevelDataLayoutTables_EightBitLo_Horizontal[v6 + 16]);
uint16 r5 = PAIR16(r2, r0) + v8;
uint8 v9 = spr_current_slotid; uint8 v9 = spr_current_slotid;
blocks_currently_processed_map16_tile_lo = g_ram[r5]; 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) { if (!g_ram[0x10000 + r5] && blocks_currently_processed_map16_tile_lo >= 0x45 && blocks_currently_processed_map16_tile_lo < 0x48) {

View File

@ -2342,7 +2342,7 @@ void Spr0A0_ActivateBowserBattle_Init(uint8 k) { // 03a0f1
InitializeMode7TilemapsAndPalettes(k); InitializeMode7TilemapsAndPalettes(k);
} }
void Spr0A0_ActivateBowserBattle(uint8 k) { // 03a118 void HandleExtraSprites(uint8 k) { // 03a118
uint8 v1 = spr_spriteid[k]; uint8 v1 = spr_spriteid[k];
switch (v1) { switch (v1) {
case 0xC8: Spr0C8_LightSwitch(k); break; case 0xC8: Spr0C8_LightSwitch(k); break;
@ -3475,8 +3475,9 @@ void SubOffscreen_Bank03_03B85F(uint8 k, uint8 r3) { // 03b85f
goto LABEL_8; goto LABEL_8;
} }
} else { } else {
uint16 ypos = GetSprYPos(k) + 0x50; uint16 y = GetSprYPos(k);
if (!sign8((ypos >> 8) - 2)) bool want_erase = g_lunar_magic ? LmHook_WantEraseSprite(k, y) : !sign8(((y + 80) >> 8) - 2);
if (want_erase)
goto LABEL_8; goto LABEL_8;
if ((spr_property_bits167a[k] & 4) == 0) { if ((spr_property_bits167a[k] & 4) == 0) {
uint8 r1 = r3 | counter_global_frames & 1; uint8 r1 = r3 | counter_global_frames & 1;
@ -4415,7 +4416,7 @@ void InitializeMode7TilemapsAndPalettes(uint8 k) { // 03dd7d
*((uint8 *)&palettes_palette_mirror[2] + i) = p0[i]; *((uint8 *)&palettes_palette_mirror[2] + i) = p0[i];
uint16 *dst = RtlGetVramAddr(); uint16 *dst = RtlGetVramAddr();
if (v1) { if (v1) {
const uint8 *pp = GraphicsDecompress(v1); const uint8 *pp = LmHook_GraphicsDecompress(v1);
uint8 r3 = 0x80; uint8 r3 = 0x80;
do { do {
pp = InitializeMode7TilemapsAndPalettes_BufferTilemap(&dst, pp); 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; *(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 void Spr0A0_ActivateBowserBattle_UpdatePaletteAndLightningAnimation() { // 03dfcc
unsigned int v1; unsigned int v1;
uint16 v4; uint16 v4;
@ -4619,7 +4618,7 @@ LABEL_7:
--palettes_lightning_flash_color_index; --palettes_lightning_flash_color_index;
timer_lightning_frame_duration = 4; timer_lightning_frame_duration = 4;
} }
v4 = kGlobalPalettes_BowserLightningFlash[v3]; v4 = kGlobalPalettes_OW_Sprites[0x31 + v3];
goto LABEL_10; goto LABEL_10;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -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_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_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_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 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 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 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_05B106[2] = { 0x4c, 0x50, };
static const uint8 kDisplayMessage_DATA_05B108[2] = { 0x50, 0x0, }; static const uint8 kDisplayMessage_DATA_05B108[2] = { 0x50, 0x0, };
static const uint8 kDisplayMessage_DATA_05B10A[2] = { 0x4, 0xfc, }; 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, }; const uint8 kBitTable_Bank05[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, };
// todo: oob read // 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, }; 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_layer2_tiles_lo[i + 512] = 37;
} }
blocks_screen_to_place_current_object = 0; blocks_screen_to_place_current_object = 0;
lm_varB = ptr_layer2_is_bg;
if (ptr_layer2_is_bg & 2) { if (ptr_layer2_is_bg & 2) {
uint8 v1 = ptr_layer2_is_bg >> 4; if (!(ptr_layer2_is_bg & 4)) {
for (uint16 j = 0; j != 512; ++j) { uint8 v1 = ptr_layer2_is_bg >> 4;
blocks_layer2_tiles_hi[j] = v1; for (uint16 j = 0; j != 1024; ++j)
blocks_layer2_tiles_hi[j + 512] = v1; blocks_layer2_tiles_hi[j] = v1;
} }
unusedram_copy_of_level_tileset_setting = 0; unusedram_copy_of_level_tileset_setting = 0;
misc_level_tileset_setting = 0; misc_level_tileset_setting = 0;
@ -343,24 +346,34 @@ void InitializeLevelLayer1And2Tilemaps() { // 05809e
blocks_screen_to_place_current_object = 0; blocks_screen_to_place_current_object = 0;
camera_xy_layer1_vramupd_left_up = -1; camera_xy_layer1_vramupd_left_up = -1;
camera_xy_layer1_vramupd_right_down = -1; camera_xy_layer1_vramupd_right_down = -1;
if (g_lunar_magic)
LmHook_InitializeLevelLayer1And2Tilemaps();
CalculateRowOrColumnOfTilemapToUpdate(); CalculateRowOrColumnOfTilemapToUpdate();
camera_layer1_row_column_to_update_right_down = camera_layer1_row_column_to_update_left_up; 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; camera_layer2_row_column_to_update_right_down = camera_layer2_row_column_to_update_left_up;
*(uint16 *)&camera_layer1_scrolling_direction = 514; *(uint16 *)&camera_layer1_scrolling_direction = 514;
do { do {
BufferScrollingTiles_Layer1_Init(); if (g_lunar_magic) {
BufferScrollingTiles_Layer2_Init(); LmHook_BufferTilemap_L1();
UploadLevelLayer1And2Tilemaps(); LmHook_BufferTilemap_L2();
++camera_layer1_row_column_to_update_right_down; LmHook_UploadLevelLayer1And2Tilemaps();
++camera_layer2_row_column_to_update_right_down; ++camera_layer1_row_column_to_update_right_down;
uint16 v0 = 614; ++camera_layer2_row_column_to_update_right_down;
uint16 R0_W = 7; } else {
uint16 v1 = kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[(camera_layer1_row_column_to_update_right_down >> 4) & 3]; BufferScrollingTiles_Layer1_Init();
do { BufferScrollingTiles_Layer2_Init();
pointer_map16_tiles[v0 >> 1] = v1; UploadLevelLayer1And2Tilemaps();
v0 += 2; ++camera_layer1_row_column_to_update_right_down;
v1 += 8; ++camera_layer2_row_column_to_update_right_down;
} while ((--R0_W & 0x8000) == 0); 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; ++blocks_screen_to_place_current_object;
} while (blocks_screen_to_place_current_object != 32); } while (blocks_screen_to_place_current_object != 32);
uint8 v2 = mirror_main_screen_layers; uint8 v2 = mirror_main_screen_layers;
@ -518,10 +531,17 @@ uint16 InitializeLevelData_Hi(uint16 k, uint8 a) { // 05833a
extern Snes *g_snes; extern Snes *g_snes;
void BeginLoadingLevelData() { // 0583ac void BeginLoadingLevelData() { // 0583ac
if (g_lunar_magic)
LmHook_InitExanimForLevel();
LOBYTE(misc_current_layer_being_processed) = 0; LOBYTE(misc_current_layer_being_processed) = 0;
LoadLevelHeader(); LoadLevelHeader();
InitializeMap16Pointers(); 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) if (*ptr_layer1_data != 0xFF)
LoadLevelDataObject(); LoadLevelDataObject();
if (misc_level_mode_setting == 0 || misc_level_mode_setting == 10 || misc_level_mode_setting == 12 || 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]; uint8 r0 = hdr[2];
graphics_level_sprite_graphics_setting = r0 & 0xF; graphics_level_sprite_graphics_setting = r0 & 0xF;
uint8 v3 = kLoadLevelHeader_LevelMusicTable[(r0 >> 4) & 7]; uint8 v3 = kLoadLevelHeader_LevelMusicTable[(r0 >> 4) & 7];
if ((misc_music_register_backup & 0x80) != 0) if (HAS_LM_FEATURE(kLmFeature_MusicRegTweak)) {
v3 |= 0x80; if (misc_game_mode >= 7)
if (v3 == misc_music_register_backup) misc_music_register_backup = v3;
v3 |= 0x40; } else {
misc_music_register_backup = v3; 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; mirror_bgmode_and_tile_size_setting = ((uint8)(r0 & 0x80) >> 4) | 1;
r0 = hdr[3]; r0 = hdr[3];
if (!counter_sublevels_entered) { if (!counter_sublevels_entered) {
@ -632,6 +657,11 @@ void LoadLevelDataObject() { // 0585ff
void CheckIfLevelTilemapsNeedScrollUpdate() { // 0586f1 void CheckIfLevelTilemapsNeedScrollUpdate() { // 0586f1
uint16 v0, v1, v2, v3; uint16 v0, v1, v2, v3;
CalculateRowOrColumnOfTilemapToUpdate(); CalculateRowOrColumnOfTilemapToUpdate();
if (g_lunar_magic) {
LmHook_CheckIfLevelTilemapsNeedScrollUpdate();
return;
}
if ((misc_level_layout_flags & 1) != 0) { if ((misc_level_layout_flags & 1) != 0) {
v0 = camera_layer1_scrolling_direction; v0 = camera_layer1_scrolling_direction;
v1 = mirror_current_layer1_ypos & 0xFFF0; v1 = mirror_current_layer1_ypos & 0xFFF0;
@ -675,15 +705,18 @@ void CalculateRowOrColumnOfTilemapToUpdate() { // 05877e
} else { } else {
camera_layer1_row_column_to_update_left_up = (mirror_current_layer1_xpos >> 4) - 8; 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; 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; if (!g_lunar_magic) {
uint16 R0_W = 7; uint16 v0 = (*((uint8 *)&camera_layer1_row_column_to_update_left_up + camera_layer1_scrolling_direction) >> 3) & 6;
uint16 v2 = kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[v0 >> 1]; uint16 v1 = 614;
do { uint16 R0_W = 7;
pointer_map16_tiles[v1 >> 1] = v2; uint16 v2 = kCalculateRowOrColumnOfTilemapToUpdate_PipeMap16Ptrs[v0 >> 1];
v1 += 2; do {
v2 += 8; pointer_map16_tiles[v1 >> 1] = v2;
} while ((--R0_W & 0x8000) == 0); v1 += 2;
v2 += 8;
} while ((--R0_W & 0x8000) == 0);
}
} }
if ((misc_level_layout_flags & 2) != 0) { if ((misc_level_layout_flags & 2) != 0) {
camera_layer2_row_column_to_update_left_up = (mirror_current_layer2_ypos >> 4) - 8; 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, 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, 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]; 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 void BufferScrollingTiles_Layer1() { // 0589ce
uint16 v0 = camera_layer1_scrolling_direction; uint16 v0 = camera_layer1_scrolling_direction;
HIBYTE(blocks_layer1_vramupload_address) = 2 * (*((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0xF); 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) if ((*((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0x10) != 0)
v1 = 36; v1 = 36;
LOBYTE(blocks_layer1_vramupload_address) = v1; 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]; const uint8 *plo = g_ram + kLevelDataLayoutTables_Layer1LoPtrs[misc_level_mode_setting][R0_W];
uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5; uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5;
uint16 r8 = *((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0xF; uint16 r8 = *((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) & 0xF;
@ -836,7 +853,7 @@ void BufferScrollingTiles_Layer1() { // 0589ce
do { do {
uint16 v5 = r8; uint16 v5 = r8;
R0_W = plo[v5] | plo[v5 + 0x10000] << 8; 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; int v6 = v4 >> 1;
blocks_layer1_tiles_to_upload_buffer[v6] = r10t[0]; blocks_layer1_tiles_to_upload_buffer[v6] = r10t[0];
blocks_layer1_tiles_to_upload_buffer[v6 + 1] = r10t[1]; blocks_layer1_tiles_to_upload_buffer[v6 + 1] = r10t[1];
@ -863,7 +880,8 @@ void BufferScrollingTiles_Layer1_VerticalLevel() { // 058a9b
v1 = 40; v1 = 40;
LOBYTE(blocks_layer1_vramupload_address) = v1 | (*((uint8 *)&camera_layer1_row_column_to_update_left_up + v0) >> 2) & 3; 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; 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; uint16 v2 = (R0_W < max_n) ? R0_W : 0;
const uint8 *plo = g_ram + r10[v2]; const uint8 *plo = g_ram + r10[v2];
uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5; uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5;
@ -873,7 +891,7 @@ void BufferScrollingTiles_Layer1_VerticalLevel() { // 058a9b
uint16 v5 = r8; uint16 v5 = r8;
R0_W = plo[r8] | plo[v5 + 0x10000] << 8; 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; int v6 = v4 >> 1;
blocks_layer1_tiles_to_upload_buffer[v6] = r10p[0]; blocks_layer1_tiles_to_upload_buffer[v6] = r10p[0];
blocks_layer1_tiles_to_upload_buffer[v6 + 64] = r10p[1]; 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) if ((*((uint8 *)&camera_layer2_row_column_to_update_left_up + v0) & 0x10) != 0)
v2 = 52; v2 = 52;
LOBYTE(blocks_layer2_vramupload_address) = v2; 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]; const uint8 *plo = g_ram + r10[R0_W];
uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5; uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5;
@ -911,7 +930,7 @@ void BufferScrollingTiles_Layer2() { // 058b8d
do { do {
uint16 v6 = r8; uint16 v6 = r8;
R0_W = plo[r8] | plo[v6 + 0x10000] << 8; 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; int v7 = v5 >> 1;
blocks_layer2_tiles_to_upload_buffer[v7] = R3_W | r10w[0]; blocks_layer2_tiles_to_upload_buffer[v7] = R3_W | r10w[0];
blocks_layer2_tiles_to_upload_buffer[v7 + 1] = R3_W | r10w[1]; blocks_layer2_tiles_to_upload_buffer[v7 + 1] = R3_W | r10w[1];
@ -943,7 +962,8 @@ void BufferScrollingTiles_Layer2_VerticalLevel() { // 058c71
v3 = 56; v3 = 56;
LOBYTE(blocks_layer2_vramupload_address) = v3 | (*((uint8 *)&camera_layer2_row_column_to_update_left_up + v1) >> 2) & 3; 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; 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; uint16 v4 = (R0_W < max_n) ? R0_W : 0;
const uint8 *plo = g_ram + r10[v4]; const uint8 *plo = g_ram + r10[v4];
uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5; uint8 bank = sign8(misc_level_tileset_setting - 16) ? 13 : 5;
@ -952,7 +972,7 @@ void BufferScrollingTiles_Layer2_VerticalLevel() { // 058c71
do { do {
uint16 v7 = r8; uint16 v7 = r8;
R0_W = plo[r8] | plo[r8 + 0x10000] << 8; 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; int v8 = v6 >> 1;
blocks_layer2_tiles_to_upload_buffer[v8] = R3_W | r10w[0]; blocks_layer2_tiles_to_upload_buffer[v8] = R3_W | r10w[0];
blocks_layer2_tiles_to_upload_buffer[v8 + 64] = R3_W | r10w[1]; 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; LOBYTE(blocks_layer2_vramupload_address) = v0;
const uint8 *phi = g_ram + 0xbd00, *plo = g_ram + 0xb900; 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) { if ((blocks_screen_to_place_current_object & 0xF0) != 0) {
plo += 432; plo += 432;
phi += 432; phi += 432;
} }
const uint8 *r10 = (const uint8 *)kMap16Data + 0x1100; // kMap16Data_Backgrounds
uint16 r8 = blocks_screen_to_place_current_object & 0xF; uint16 r8 = blocks_screen_to_place_current_object & 0xF;
uint16 v1 = 0; uint16 v1 = 0;
do { do {
@ -1013,7 +1038,7 @@ void DisplayMessage() { // 05b10c
mirror_color_math_initial_settings = 2; mirror_color_math_initial_settings = 2;
return; 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) if ((counter_global_frames & 3) != 0)
return; return;
if (--timer_title_screen_input_timer) if (--timer_title_screen_input_timer)
@ -1029,7 +1054,8 @@ void DisplayMessage() { // 05b10c
(((io_controller_press1 ^ io_controller_hold1 & 0xF0) & 0xF0) == 0 || (((io_controller_press1 ^ io_controller_hold1 & 0xF0) & 0xF0) == 0 ||
(io_controller_hold2 & 0xC0) != 0 && ((io_controller_press2 ^ io_controller_hold2 & 0xC0) & 0xC0) == 0)) { (io_controller_hold2 & 0xC0) != 0 && ((io_controller_press2 ^ io_controller_hold2 & 0xC0) & 0xC0) == 0)) {
if (misc_intro_level_flag) { 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(); DisplayMessage_ExitToOverworldNoEvent();
} else { } else {
++flag_message_window_size_change_direction; ++flag_message_window_size_change_direction;
@ -1040,6 +1066,8 @@ void DisplayMessage() { // 05b10c
if (flag_message_window_size_change_direction) { if (flag_message_window_size_change_direction) {
DisplayMessage_RemoveSwitchBlocks(); DisplayMessage_RemoveSwitchBlocks();
graphics_stripe_image_to_upload = 9; graphics_stripe_image_to_upload = 9;
} else if (HAS_LM_FEATURE(kLmFeature_CustomDisplayMessage)) {
LmHook_DisplayMessage();
} else { } else {
uint8 v0 = 22; uint8 v0 = 22;
do { do {
@ -1093,6 +1121,7 @@ void DisplayMessage() { // 05b10c
mirror_layer3_ypos = 0; mirror_layer3_ypos = 0;
} }
} }
timer_wait_before_message_window_size_change += kDisplayMessage_DATA_05B10A[flag_message_window_size_change_direction]; 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; HIBYTE(v7) = timer_wait_before_message_window_size_change + 0x80;
LOBYTE(v7) = 0x80 - timer_wait_before_message_window_size_change; 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]; return kBitTable_Bank05[j & 7] & ow_event_flags[j >> 3];
} }
static const kLevelTileAnimationsAddrs[] = { static const uint16 kLevelTileAnimationsAddrs[] = {
0x600, 0x640, 0x680, 0x600, 0x640, 0x680,
0x740, 0xEA0, 0x800, 0x740, 0xEA0, 0x800,
0x500, 0x540, 0x580, 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() { const uint8 *GetSpriteListPtr() {
uint32 v = Load24(ptr_sprite_list_data); return kLvlSprBlob(Load24(ptr_sprite_list_data));
int idx = (int)FindWithBinarySearch(kSpriteListPtrToIndex, arraysize(kSpriteListPtrToIndex), v);
assert(idx != -1);
const uint8 *bb = kLoadLevelSpriteList(idx).ptr;
return bb;
} }
void LoadLevel() { // 05d796 bool LoadLevel() { // 05d796
uint16 v1; uint16 v1;
int16 v5; int16 v5;
uint16 v10; uint16 v10;
uint16 r14w; 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; flag_override_no_yoshi_intro_for_midway_entrance = 0;
if (in_yoshi_wings_bonus_area || flag_active_bonus_game) if (in_yoshi_wings_bonus_area || flag_active_bonus_game)
LoadLevel_05DBAC(); LoadLevel_05DBAC();
if (counter_sublevels_entered) { if (counter_sublevels_entered) {
uint8 v0 = HIBYTE(player_xpos); uint8 v0 = ((misc_level_layout_flags & 1) != 0) ? HIBYTE(player_ypos) : HIBYTE(player_xpos);
if ((misc_level_layout_flags & 1) != 0)
v0 = HIBYTE(player_ypos);
r14w = (ow_players_map[(uint8)player_current_characterx4 >> 2] != 0) << 8 | misc_subscreen_exit_entrance_number_lo[v0]; 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) { if (flag_use_secondary_entrance) {
uint16 j = r14w; uint16 j = r14w;
r14w = (r14w & ~0xff) | kLevelInfo_05F800[j]; r14w = (r14w & ~0xff) | kLevelInfo_05F800[j];
@ -2373,10 +2357,17 @@ void LoadLevel() { // 05d796
HIBYTE(player_ypos) = kLoadLevel_DATA_05D740[r0 & 0xF]; HIBYTE(player_ypos) = kLoadLevel_DATA_05D740[r0 & 0xF];
LOBYTE(mirror_current_layer1_ypos) = kLoadLevel_DATA_05D708[(r0 & 0x30) >> 4]; LOBYTE(mirror_current_layer1_ypos) = kLoadLevel_DATA_05D708[(r0 & 0x30) >> 4];
LOBYTE(mirror_current_layer2_ypos) = kLoadLevel_DATA_05D70C[r0 >> 6]; LOBYTE(mirror_current_layer2_ypos) = kLoadLevel_DATA_05D70C[r0 >> 6];
R1_ = kLevelInfo_05FC00[j]; r1 = kLevelInfo_05FC00[j];
LOBYTE(player_xpos) = kLoadLevel_DATA_05D750[R1_ >> 5]; LOBYTE(player_xpos) = kLoadLevel_DATA_05D750[r1 >> 5];
HIBYTE(player_xpos) = kLoadLevel_DATA_05D758[R1_ >> 5]; HIBYTE(player_xpos) = kLoadLevel_DATA_05D758[r1 >> 5];
misc_level_header_entrance_settings = kLevelInfo_05FE00[j] & 7; 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 { } else {
v1 = 0; v1 = 0;
@ -2396,17 +2387,25 @@ void LoadLevel() { // 05d796
ow_level_number_lo = v2; ow_level_number_lo = v2;
} }
if (v2 >= 0x25) if (v2 >= 0x25)
v2 -= 36; v2 -= 0x24;
r14w = (ow_players_map[(uint8)v1] != 0) << 8 | v2; r14w = (ow_players_map[(uint8)v1] != 0) << 8 | v2;
r14w = LmHook_LoadLevelInfo_C(r14w);
} }
ptr_layer1_data = kLevelData_Layer1(r14w).ptr; ptr_layer1_data = kLevelData_Layer1(r14w).ptr;
ptr_layer2_data = kLevelData_Layer2(r14w).ptr; ptr_layer2_data = kLevelData_Layer2(r14w).ptr;
ptr_layer2_is_bg = kLevelData_Layer2_IsBg[r14w]; ptr_layer2_is_bg = kLevelData_Layer2_IsBg[r14w];
if (g_lunar_magic)
lunar_magic_FE = r14w + 1;
HIBYTE(v5) = 0; 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(); 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; sprites_sprite_buoyancy_settings = sprite_hdr & 0xC0;
uint8 v6 = kLevelInfo_05F000[r14w] >> 4; uint8 v6 = kLevelInfo_05F000[r14w] >> 4;
flag_layer2_horiz_scroll_level_setting = kLoadLevel_L2HorzScrollSettings[v6]; flag_layer2_horiz_scroll_level_setting = kLoadLevel_L2HorzScrollSettings[v6];
@ -2417,44 +2416,49 @@ void LoadLevel() { // 05d796
HIBYTE(mirror_current_layer2_ypos) = 0; HIBYTE(mirror_current_layer2_ypos) = 0;
flag_disable_no_yoshi_intro = kLevelInfo_05F600[r14w] & 0x80; flag_disable_no_yoshi_intro = kLevelInfo_05F600[r14w] & 0x80;
misc_level_layout_flags = (uint8)(kLevelInfo_05F600[r14w] & 0x60) >> 5; misc_level_layout_flags = (uint8)(kLevelInfo_05F600[r14w] & 0x60) >> 5;
uint8 R2_ = 0; // todo: what is R2 here?
if (!flag_use_secondary_entrance) { if (!flag_use_secondary_entrance) {
v10 = kLevelInfo_05F000[r14w] & 0xF; v10 = kLevelInfo_05F000[r14w] & 0xF;
player_ypos = PAIR16(kLoadLevel_DATA_05D740[v10], kLoadLevel_DATA_05D730[v10]); player_ypos = PAIR16(kLoadLevel_DATA_05D740[v10], kLoadLevel_DATA_05D730[v10]);
R2_ = kLevelInfo_05F200[r14w]; r2 = kLevelInfo_05F200[r14w];
v10 = R2_ & 7; v10 = r2 & 7;
player_xpos = PAIR16(kLoadLevel_DATA_05D758[v10], kLoadLevel_DATA_05D750[v10]); player_xpos = PAIR16(kLoadLevel_DATA_05D758[v10], kLoadLevel_DATA_05D750[v10]);
misc_level_header_entrance_settings = (uint8)(R2_ & 0x38) >> 3; misc_level_header_entrance_settings = (uint8)(r2 & 0x38) >> 3;
R2_ = kLevelInfo_05F400[r14w]; LmHook_ExpandLvlHdr(r14w);
v10 = R2_ & 3; r2 = kLevelInfo_05F400[r14w];
v10 = r2 & 3;
mirror_current_layer2_ypos = kLoadLevel_DATA_05D70C[v10]; 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]; 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) { if ((misc_level_layout_flags & 1) != 0) {
HIBYTE(player_ypos) = *ptr_layer1_data & 0x1F; HIBYTE(player_ypos) = *ptr_layer1_data & 0x1F;
camera_last_screen_vert = HIBYTE(player_ypos) + 1; camera_last_screen_vert = HIBYTE(player_ypos) + 1;
flag_layer1_vert_scroll_level_setting = 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_current_event_number = kLoadLevel_DATA_05D608[ow_level_number_lo],
(ow_level_tile_settings[ow_level_number_lo] & 0x40) == 0)) { (ow_level_tile_settings[ow_level_number_lo] & 0x40) == 0)) {
R1_ &= 0x1F; r1 &= 0x1F;
if ((misc_level_layout_flags & 1) != 0) { if ((misc_level_layout_flags & 1) != 0) {
HIBYTE(player_ypos) = R1_; HIBYTE(player_ypos) = r1;
HIBYTE(mirror_current_layer1_ypos) = R1_; HIBYTE(mirror_current_layer1_ypos) = r1;
if (flag_layer2_vert_scroll_level_setting != 3) 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; flag_layer1_vert_scroll_level_setting = 1;
} else { } else {
HIBYTE(player_xpos) = R1_; HIBYTE(player_xpos) = r1;
} }
} else { } else {
flag_override_no_yoshi_intro_for_midway_entrance = ow_level_tile_settings[ow_level_number_lo] & 0x40; 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; uint8 v11;
LmHook_LoadLevelB(ptr_layer1_data, r2, r14w);
if (ow_level_number_lo < 0x52) { if (ow_level_number_lo < 0x52) {
v11 = 4; v11 = 4;
uint8 v12 = ptr_layer1_data[4] & 0xF; uint8 v12 = ptr_layer1_data[4] & 0xF;
@ -2478,8 +2482,9 @@ void LoadLevel() { // 05d796
LOBYTE(mirror_current_layer2_ypos) = -64; LOBYTE(mirror_current_layer2_ypos) = -64;
misc_level_header_entrance_settings = 0; misc_level_header_entrance_settings = 0;
ptr_sprite_list_data = (LongPtr){ .bank = 7, .addr = 0xc3ee }; ptr_sprite_list_data = (LongPtr){ .bank = 7, .addr = 0xc3ee };
LmHook_LoadLevelInfo();
uint8 sprite_hdr = *GetSpriteListPtr(); 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; sprites_sprite_buoyancy_settings = sprite_hdr & 0xC0;
flag_layer2_horiz_scroll_level_setting = 0; flag_layer2_horiz_scroll_level_setting = 0;
flag_layer2_vert_scroll_level_setting = 0; flag_layer2_vert_scroll_level_setting = 0;
@ -2495,6 +2500,8 @@ void LoadLevel() { // 05d796
LABEL_47: LABEL_47:
if (counter_sublevels_entered && !flag_active_bonus_game && ow_level_number_lo == 36) if (counter_sublevels_entered && !flag_active_bonus_game && ow_level_number_lo == 36)
LoadLevel_HandleChocolateIsland2Gimmick(); LoadLevel_HandleChocolateIsland2Gimmick();
return false;
} }
void LoadLevel_HandleChocolateIsland2Gimmick() { // 05daef void LoadLevel_HandleChocolateIsland2Gimmick() { // 05daef
@ -2530,9 +2537,9 @@ void LoadLevel_HandleChocolateIsland2Gimmick() { // 05daef
ptr_sprite_list_data.addr = kChoclateIsland2_SpritePtrs[v3]; ptr_sprite_list_data.addr = kChoclateIsland2_SpritePtrs[v3];
ptr_layer2_data = kChoclateIsland2_Layer2(v3).ptr; ptr_layer2_data = kChoclateIsland2_Layer2(v3).ptr;
ptr_layer2_is_bg = kChoclateIsland2_Layer2_IsBg[v3]; ptr_layer2_is_bg = kChoclateIsland2_Layer2_IsBg[v3];
LmHook_LoadLevelInfo();
uint8 sprite_hdr = *GetSpriteListPtr(); 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; sprites_sprite_buoyancy_settings = sprite_hdr & 0x80;
} }
@ -2602,3 +2609,4 @@ void Spr07B_GoalTape_GiveBonusStars(uint8 k) { // 07f252
if (counter_bonus_stars_earned == 80) if (counter_bonus_stars_earned == 80)
GivePoints(k, 0xA); GivePoints(k, 0xA);
} }

View File

@ -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 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 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 uint16 kGameMode1B_EndingCinema_BackgroundChangeHeight[7] = { 0xc0, 0x180, 0x240, 0x300, 0x3c0, 0x480, 0x559, };
static const uint8 kGameMode1B_EndingCinema_PeachOnYoshiOffset[3] = { 0x0, 0xff, 0x0, }; static const uint8 kGameMode1B_EndingCinema_PeachOnYoshiOffset[3] = { 0x0, 0xff, 0x0, };
@ -194,6 +192,7 @@ void BufferCreditsBackgrounds() { // 0c93dd
++*(uint16 *)&blocks_screen_to_place_current_object; ++*(uint16 *)&blocks_screen_to_place_current_object;
} while (*(uint16 *)&blocks_screen_to_place_current_object != 7); } while (*(uint16 *)&blocks_screen_to_place_current_object != 7);
credits_var65 = 0x5840; credits_var65 = 0x5840;
LmHook_BufferCreditsBackgrounds();
credits_index = 0; credits_index = 0;
blocks_screen_to_place_current_object = 0; blocks_screen_to_place_current_object = 0;
UpdateCreditsBackground(); UpdateCreditsBackground();

View File

@ -302,14 +302,14 @@ void (*kProcessGrasslandObjects_GrasslandPtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog, &StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog, &StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge, &StdObj21_WideScaleGroundLedge,
&RopeObj2E_Unused, &LmStdObj22_DirectMap16,
&RopeObj2E_Unused, &LmStdObj23,
&RopeObj2E_Unused, &LmStdObj24,
&RopeObj2E_Unused, &LmStdObj25,
&RopeObj2E_Unused, &LmStdObj26_MusicBypass,
&RopeObj2E_Unused, &LmStdObj27,
&RopeObj2E_Unused, &LmStdObj28,
&RopeObj2E_Unused, &LmStdObj29,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
@ -374,14 +374,14 @@ void (*kProcessCastleObjects_CastlePtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog, &StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog, &StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge, &StdObj21_WideScaleGroundLedge,
&RopeObj2E_Unused, &LmStdObj22_DirectMap16,
&RopeObj2E_Unused, &LmStdObj23,
&RopeObj2E_Unused, &LmStdObj24,
&RopeObj2E_Unused, &LmStdObj25,
&RopeObj2E_Unused, &LmStdObj26_MusicBypass,
&RopeObj2E_Unused, &LmStdObj27,
&RopeObj2E_Unused, &LmStdObj28,
&RopeObj2E_Unused, &LmStdObj29,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
@ -443,14 +443,14 @@ void (*kProcessRopeObjects_RopePtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog, &StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog, &StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge, &StdObj21_WideScaleGroundLedge,
&RopeObj2E_Unused, &LmStdObj22_DirectMap16,
&RopeObj2E_Unused, &LmStdObj23,
&RopeObj2E_Unused, &LmStdObj24,
&RopeObj2E_Unused, &LmStdObj25,
&RopeObj2E_Unused, &LmStdObj26_MusicBypass,
&RopeObj2E_Unused, &LmStdObj27,
&RopeObj2E_Unused, &LmStdObj28,
&RopeObj2E_Unused, &LmStdObj29,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
@ -516,14 +516,14 @@ void (*kProcessUndergroundObjects_UndergroundPtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog, &StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog, &StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge, &StdObj21_WideScaleGroundLedge,
&RopeObj2E_Unused, &LmStdObj22_DirectMap16,
&RopeObj2E_Unused, &LmStdObj23,
&RopeObj2E_Unused, &LmStdObj24,
&RopeObj2E_Unused, &LmStdObj25,
&RopeObj2E_Unused, &LmStdObj26_MusicBypass,
&RopeObj2E_Unused, &LmStdObj27,
&RopeObj2E_Unused, &LmStdObj28,
&RopeObj2E_Unused, &LmStdObj29,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
@ -591,14 +591,14 @@ void (*kProcessGhostHouseObjects_GhostHousePtrs[63])(uint8 k) = {
&StdObj1F_SkinnyVerticalPipeBoneLog, &StdObj1F_SkinnyVerticalPipeBoneLog,
&StdObj20_SkinnyHorizontalPipeBoneLog, &StdObj20_SkinnyHorizontalPipeBoneLog,
&StdObj21_WideScaleGroundLedge, &StdObj21_WideScaleGroundLedge,
&RopeObj2E_Unused, &LmStdObj22_DirectMap16,
&RopeObj2E_Unused, &LmStdObj23,
&RopeObj2E_Unused, &LmStdObj24,
&RopeObj2E_Unused, &LmStdObj25,
&RopeObj2E_Unused, &LmStdObj26_MusicBypass,
&RopeObj2E_Unused, &LmStdObj27,
&RopeObj2E_Unused, &LmStdObj28,
&RopeObj2E_Unused, &LmStdObj29,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
&RopeObj2E_Unused, &RopeObj2E_Unused,
@ -774,8 +774,13 @@ void ExtObj00_ScreenExit(uint8 k) { // 0da512
blocks_object_number = *ptr_layer1_data++; blocks_object_number = *ptr_layer1_data++;
uint8 v2 = loadlvl_R10 & 0x1F; uint8 v2 = loadlvl_R10 & 0x1F;
misc_subscreen_exit_entrance_number_lo[v2] = blocks_object_number; misc_subscreen_exit_entrance_number_lo[v2] = blocks_object_number;
misc_subscreen_exit_properties[v2] = loadlvl_R11 & 1; if (g_lunar_magic) {
flag_use_secondary_entrance = loadlvl_R11 >> 1; 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 void ExtObj01_ScreenJump(uint8 k) { // 0da53d
@ -1049,7 +1054,7 @@ uint8 HandleHorizontalSubScreenCrossingForCurrentObject(uint8 j, uint8 a) { //
uint8 HandleHorizontalSubScreenCrossingForCurrentObject_Entry2(uint8 j) { // 0da95d uint8 HandleHorizontalSubScreenCrossingForCurrentObject_Entry2(uint8 j) { // 0da95d
uint8 result = j + 1; uint8 result = j + 1;
if ((result & 0xF) == 0) { 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; ++blocks_screen_to_place_next_object;
result = blocks_sub_scr_pos & 0xF0; result = blocks_sub_scr_pos & 0xF0;
} }
@ -1098,13 +1103,13 @@ uint8 GoDownRightAndUpdateLevelDataPointerInObjects() { // 0da9b4
} }
void GoBackOneScreenAndUpdateLevelDataPointerInObjects() { // 0da9d6 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; ptr_lo_map16_data_bak = ptr_lo_map16_data;
--blocks_screen_to_place_next_object; --blocks_screen_to_place_next_object;
} }
void GoForwardOneScreenAndUpdateLevelDataPointerInObjects() { // 0da9ef 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; ptr_lo_map16_data_bak = ptr_lo_map16_data;
++blocks_screen_to_place_next_object; ++blocks_screen_to_place_next_object;
} }

View File

@ -3,6 +3,9 @@
#include "snes/snes.h" #include "snes/snes.h"
#include "variables.h" #include "variables.h"
#include "funcs.h" #include "funcs.h"
#include "assets/smw_assets.h"
extern bool g_custom_music;
static const uint32 kPatchedCarrys_SMW[] = { static const uint32 kPatchedCarrys_SMW[] = {
0xFE1F, 0xFE1F,
@ -61,6 +64,10 @@ static const uint32 kPatchedCarrys_SMW[] = {
static uint8 preserved_db; static uint8 preserved_db;
static uint32 get_24(uint32 a) {
return *(uint32*)SnesRomPtr(a) & 0xffffff;
}
uint32 PatchBugs_SMW1(void) { uint32 PatchBugs_SMW1(void) {
if (FixBugHook(0xA33C) || FixBugHook(0xa358) || FixBugHook(0xA378)) { if (FixBugHook(0xA33C) || FixBugHook(0xa358) || FixBugHook(0xA378)) {
if (g_cpu->a == 0x0) if (g_cpu->a == 0x0)
@ -142,15 +149,102 @@ uint32 PatchBugs_SMW1(void) {
} else if (FixBugHook(0x817e)) { } else if (FixBugHook(0x817e)) {
g_cpu->y = g_ram[kSmwRam_APUI02]; g_cpu->y = g_ram[kSmwRam_APUI02];
return 0x8181; 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; return 0;
} }
void SmwCpuInitialize(void) { void SmwCpuInitialize(void) {
g_lunar_magic = HAS_LM_FEATURE(kLmFeature_LmEnabled);
if (g_rom) { if (g_rom) {
*SnesRomPtr(0x843B) = 0x60; // remove WaitForHBlank_Entry2 *SnesRomPtr(0x843B) = 0x60; // remove WaitForHBlank_Entry2
*SnesRomPtr(0x2DDA2) = 5; *SnesRomPtr(0x2DDA2) = 5;
*SnesRomPtr(0xCA5AC) = 7; *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[0x14B0], &a->ram[0x14B0], 0x11); // temp14b0 etc
memcpy(&b->ram[0x1436], &a->ram[0x1436], 4); // 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) { static uint32 RunCpuUntilPC(uint32 pc1, uint32 pc2) {
@ -174,7 +275,7 @@ static uint32 RunCpuUntilPC(uint32 pc1, uint32 pc2) {
for(;;) { for(;;) {
snes_runCpu(g_snes); snes_runCpu(g_snes);
// snes_runCycle(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)) { if (addr != addr_last && (addr == pc1 || addr == pc2)) {
return addr; return addr;
} }

View File

@ -3,6 +3,7 @@
#include <time.h> #include <time.h>
#include "common_cpu_infra.h" #include "common_cpu_infra.h"
#include "snes/snes.h" #include "snes/snes.h"
#include "src/funcs.h"
const uint8 *ptr_layer1_data; const uint8 *ptr_layer1_data;
const uint8 *ptr_layer2_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;
uint8 *ptr_lo_map16_data_bak; uint8 *ptr_lo_map16_data_bak;
bool g_lunar_magic;
void AddSprXPos(uint8 k, uint16 x) { void AddSprXPos(uint8 k, uint16 x) {
AddHiLo(&spr_xpos_hi[k], &spr_xpos_lo[k], x); AddHiLo(&spr_xpos_hi[k], &spr_xpos_lo[k], x);
} }
@ -91,4 +95,54 @@ void SmwRunOneFrameOfGame(void) {
SmwVectorReset(); SmwVectorReset();
SmwRunOneFrameOfGame_Internal(); SmwRunOneFrameOfGame_Internal();
SmwVectorNMI(); SmwVectorNMI();
} }
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;
}
}
}

View File

@ -1,7 +1,11 @@
#pragma once #ifndef SMW_SMW_RTL_H_
#define SMW_SMW_RTL_H_
#include "common_rtl.h" #include "common_rtl.h"
#include "snes/snes_regs.h" #include "snes/snes_regs.h"
extern bool g_lunar_magic;
extern int g_dbg_ctr_mine;
PointU16 *get_PointU16(PointU16 *pt, uint8 off); PointU16 *get_PointU16(PointU16 *pt, uint8 off);
static inline OamEnt *get_OamEnt(OamEnt *base, uint16 off) { return (OamEnt *)((uint8 *)base + 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 SmwClearVram(uint16 vram_addr, uint16 value, int n);
void SmwCopyToVramPitch32(uint16 vram_addr, const uint8 *src, int n); void SmwCopyToVramPitch32(uint16 vram_addr, const uint8 *src, int n);
void SmwCopyToVramLow(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 SmwDrawPpuFrame(void);
void SmwRunOneFrameOfGame(void); void SmwRunOneFrameOfGame(void);
@ -60,4 +65,6 @@ typedef struct GenTileArgs {
} GenTileArgs; } GenTileArgs;
const uint8 *GetSpriteListPtr(); const uint8 *GetSpriteListPtr();
uint8 GetCurrentSlope(int i); uint8 GetCurrentSlope(int i);
#endif // SMW_SMW_RTL_H_

View File

@ -735,34 +735,34 @@ int bp_cnt = 0;
extern bool g_debug_apu_cycles; extern bool g_debug_apu_cycles;
void DumpCpuHistory() { void DumpCpuHistory() {
for (int i = 0; i < 8; i++) { for (int i = 0; i < 16; i++) {
printf("PC history: 0x%x\n", pc_hist[(pc_hist_ctr + i) & 7]); 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) { 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[pc_hist_ctr] = cur_pc;
pc_hist_ctr = (pc_hist_ctr + 1) & 15; pc_hist_ctr = (pc_hist_ctr + 1) & 15;
if (0 && cur_pc == 0x5D83B) {
g_snes->debug_cycles = 0;
}
if (cur_pc == pc_bp) { if (cur_pc == pc_bp) {
printf("Reached BP 0x%x. A=0x%.2x, X=0x%.2x, Y=0x%.2x. C=%d. 0x%x\n", printf("Reached BP 0x%x. A=0x%.2x, X=0x%.2x, Y=0x%.2x. C=%d. lm_var13CD=%x\n",
cur_pc, (uint8)cpu->a, cpu->x, cpu->y, cpu->c, cur_pc, cpu->a, cpu->x, cpu->y, cpu->c,
0); *(uint16*)&g_ram[14]);
// printf("T: 16 j=%d, %d\n", g_cpu->y, g_cpu->a);
bp_cnt += 1; bp_cnt += 1;
//g_snes->debug_cycles = 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: restart:
switch(opcode) { switch(opcode) {

View File

@ -206,7 +206,7 @@ void snes_runCycle(Snes* snes) {
snes_handle_pos_stuff(snes); snes_handle_pos_stuff(snes);
} }
#define IS_ADR(x) (x == 0xffffff) #define IS_ADR(x) (x == 0xfffff)
void snes_runCpu(Snes *snes) { void snes_runCpu(Snes *snes) {
uint32_t pc = snes->cpu->k << 16 | snes->cpu->pc; uint32_t pc = snes->cpu->k << 16 | snes->cpu->pc;

View File

@ -1,3 +1,5 @@
#ifndef SNES_SNES_REGS_H_
#define SNES_SNES_REGS_H_
#pragma once #pragma once
typedef enum SnesRegs { typedef enum SnesRegs {
@ -213,3 +215,5 @@ typedef enum SnesRegs {
UNUSED7 = 0x437B, UNUSED7 = 0x437B,
MIRR7 = 0x437F, MIRR7 = 0x437F,
} SnesRegs; } SnesRegs;
#endif // SNES_SNES_REGS_H_

View File

@ -157,6 +157,7 @@ typedef struct MemBlk {
size_t size; size_t size;
} MemBlk; } MemBlk;
MemBlk FindIndexInMemblk(MemBlk data, size_t i); MemBlk FindIndexInMemblk(MemBlk data, size_t i);
const uint8 *FindAddrInMemblk(MemBlk data, uint32 addr);
#endif // SM_TYPES_H_ #endif // SM_TYPES_H_

View File

@ -208,3 +208,32 @@ MemBlk FindIndexInMemblk(MemBlk data, size_t i) {
return (MemBlk) { 0, 0 }; return (MemBlk) { 0, 0 };
return (MemBlk) { data.ptr + left_off, right_off - left_off }; 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;
}

View File

@ -154,6 +154,13 @@ extern uint8 ptr_layer2_is_bg;
#define spr86_wiggler_segment_pos_ptr (*(LongPtr*)(g_ram+0xD5)) #define spr86_wiggler_segment_pos_ptr (*(LongPtr*)(g_ram+0xD5))
#define spr_ypos_lo ((uint8*)(g_ram+0xD8)) #define spr_ypos_lo ((uint8*)(g_ram+0xD8))
#define spr_xpos_lo ((uint8*)(g_ram+0xE4)) #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_game_mode (*(uint8*)(g_ram+0x100))
#define misc_currently_loaded_sprite_graphics_files ((uint8*)(g_ram+0x101)) #define misc_currently_loaded_sprite_graphics_files ((uint8*)(g_ram+0x101))
#define misc_intro_level_flag (*(uint8*)(g_ram+0x109)) #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 flag_show_save_prompt (*(uint8*)(g_ram+0x13CA))
#define unusedram_got_invincible_star_from_goal (*(uint8*)(g_ram+0x13CB)) #define unusedram_got_invincible_star_from_goal (*(uint8*)(g_ram+0x13CB))
#define counter_coin_handler (*(uint8*)(g_ram+0x13CC)) #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_got_midpoint (*(uint8*)(g_ram+0x13CE))
#define flag_override_no_yoshi_intro_for_midway_entrance (*(uint8*)(g_ram+0x13CF)) #define flag_override_no_yoshi_intro_for_midway_entrance (*(uint8*)(g_ram+0x13CF))
#define ow_destroy_tile_event_tile_index (*(uint8*)(g_ram+0x13D0)) #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_xspeed (*(uint16*)(g_ram+0x1458))
#define misc_layer3_yspeed (*(uint16*)(g_ram+0x145A)) #define misc_layer3_yspeed (*(uint16*)(g_ram+0x145A))
#define misc_layer3_tide_sub_ypos (*(uint16*)(g_ram+0x145C)) #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 flag_layer3_vert_scroll_direction (*(uint8*)(g_ram+0x1460))
#define unusedram_7e1461 (*(uint8*)(g_ram+0x1461)) #define unusedram_7e1461 (*(uint8*)(g_ram+0x1461))
#define misc_layer1_pos ((PointU16*)(g_ram+0x1462)) #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 graphics_decompressed_loading_letters ((uint8*)(g_ram+0x1977B))
#define spr86_wiggler_segment_pos_table ((uint8*)(g_ram+0x19A7B)) #define spr86_wiggler_segment_pos_table ((uint8*)(g_ram+0x19A7B))
#define blocks_map16_table_hi ((uint8*)(g_ram+0x1C800)) #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;