diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c25a555 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.lua text eol=lf +*.py text eol=lf +*.pyx text eol=lf +*.pyxbld text eol=lf diff --git a/Lua/item values.lua b/Lua/item values.lua index a16237b..5d28a39 100755 --- a/Lua/item values.lua +++ b/Lua/item values.lua @@ -1,53 +1,53 @@ -mask_values_early = { - postman = 0x5A, - all_night = 0x55, - blast = 0x63, - stone = 0x61, - great_fairy = 0x5C, - deku = 0x4E, - keaton = 0x56, - bremen = 0x62, - bunny = 0x54, - don_gero = 0x5E, - scents = 0x64, - goron = 0x4F, - romani = 0x58, - troupe_leader = 0x59, - kafei = 0x53, - couples = 0x5B, - truth = 0x52, - zora = 0x50, - kamaro = 0x5F, - gibdo = 0x5D, - garos = 0x57, - captains = 0x60, - giants = 0x65, - fierce_deity = 0x51, -} - -mask_values = { - postman = 0x3E, - all_night = 0x38, - blast = 0x47, - stone = 0x45, - great_fairy = 0x40, - deku = 0x32, - keaton = 0x3A, - bremen = 0x46, - bunny = 0x39, - don_gero = 0x42, - scents = 0x48, - goron = 0x33, - romani = 0x3C, - troupe_leader = 0x3D, - kafei = 0x37, - couples = 0x3F, - truth = 0x36, - zora = 0x34, - kamaro = 0x43, - gibdo = 0x41, - garos = 0x3B, - captains = 0x44, - giants = 0x49, - fierce_deity = 0x35, +mask_values_early = { + postman = 0x5A, + all_night = 0x55, + blast = 0x63, + stone = 0x61, + great_fairy = 0x5C, + deku = 0x4E, + keaton = 0x56, + bremen = 0x62, + bunny = 0x54, + don_gero = 0x5E, + scents = 0x64, + goron = 0x4F, + romani = 0x58, + troupe_leader = 0x59, + kafei = 0x53, + couples = 0x5B, + truth = 0x52, + zora = 0x50, + kamaro = 0x5F, + gibdo = 0x5D, + garos = 0x57, + captains = 0x60, + giants = 0x65, + fierce_deity = 0x51, +} + +mask_values = { + postman = 0x3E, + all_night = 0x38, + blast = 0x47, + stone = 0x45, + great_fairy = 0x40, + deku = 0x32, + keaton = 0x3A, + bremen = 0x46, + bunny = 0x39, + don_gero = 0x42, + scents = 0x48, + goron = 0x33, + romani = 0x3C, + troupe_leader = 0x3D, + kafei = 0x37, + couples = 0x3F, + truth = 0x36, + zora = 0x34, + kamaro = 0x43, + gibdo = 0x41, + garos = 0x3B, + captains = 0x44, + giants = 0x49, + fierce_deity = 0x35, } \ No newline at end of file diff --git a/Lua/oneshot.lua b/Lua/oneshot.lua index e833e96..1bb2120 100755 --- a/Lua/oneshot.lua +++ b/Lua/oneshot.lua @@ -1,124 +1,124 @@ --- gimme gimme gimme -local addrs = require "addrs" -require "item values" -local inv = addrs.inventory -local masks = addrs.masks -local quantities = addrs.quantities -_=addrs.target_style and addrs.target_style(1) ---addrs.buttons_enabled (0) ---addrs.infinite_sword(1) -addrs.owl_save (1) -addrs.sot_count (0) -_=addrs.bubble_timer and addrs.bubble_timer(0) --- -addrs.sword_shield (0x23) -addrs.quiver_bag (0x1B) -addrs.hearts (16*20) -addrs.max_hearts (16*20) -addrs.doubled_hearts(20) -addrs.owls_hit (0xFFFF) -addrs.map_visible (0xFFFF) -addrs.map_visited (0xFFFF) -addrs.wallet_size (32) -addrs.rupees (999) -addrs.banked_rupees (9999) -addrs.magic (0x60) ---addrs.has_magic (1) -addrs.has_normal_magic(1) -addrs.has_double_magic(1) -addrs.chateau_romani(8) -addrs.quest_items (0x00FFFFFF) - -addrs.lottery_code_1(1*10000 + 2*0x100 + 3) -addrs.lottery_code_2(4*10000 + 5*0x100 + 6) -addrs.lottery_code_3(7*10000 + 8*0x100 + 9) -addrs.spider_mask_color_1(0) -addrs.spider_mask_color_2(0) -addrs.spider_mask_color_3(0) -addrs.spider_mask_color_4(0) -addrs.spider_mask_color_5(0) -addrs.bombers_code_1(1) -addrs.bombers_code_2(2) -addrs.bombers_code_3(3) -addrs.bombers_code_4(4) -addrs.bombers_code_5(5) - -addrs.items_wft(7) -addrs.items_sht(7) -addrs.items_gbt(7) -addrs.items_stt(7) -addrs.keys_wft(69) -addrs.keys_sht(69) -addrs.keys_gbt(69) -addrs.keys_stt(69) -addrs.fairies_wft(69) -addrs.fairies_sht(69) -addrs.fairies_gbt(69) -addrs.fairies_stt(69) - ---addrs.slulltula_count_wf(69) ---addrs.slulltula_count_gb(69) - ---inv.b_button (0x4F) -- don't really need this -inv.ocarina (0x00) -inv.bow (0x01) -inv.fire_arrows (0x02) -inv.ice_arrows (0x03) -inv.light_arrows (0x04) -inv.bombs (0x06) -inv.bombchu (0x07) -inv.deku_stick (0x08) -inv.deku_nut (0x09) -inv.magic_beans (0x0A) -inv.powder_keg (0x0C) -inv.pictograph (0x0D) -inv.lens_of_truth (0x0E) -inv.hookshot (0x0F) -inv.fairy_sword (0x10) -inv.bottle_1 (0x12) -inv.bottle_2 (0x1B) -inv.bottle_3 (0x1A) -inv.bottle_4 (0x18) -inv.bottle_5 (0x16) -inv.bottle_6 (0x25) ---addrs.event_1 (0x05) ---addrs.event_2 (0x0B) ---addrs.event_3 (0x11) - -local mv = mask_values -if version == "JP10" or version == "JP11" then - mv = mask_values_early -end - -masks.postman (mv.postman ) -masks.all_night (mv.all_night ) -masks.blast (mv.blast ) -masks.stone (mv.stone ) -masks.great_fairy (mv.great_fairy ) -masks.deku (mv.deku ) -masks.keaton (mv.keaton ) -masks.bremen (mv.bremen ) -masks.bunny (mv.bunny ) -masks.don_gero (mv.don_gero ) -masks.scents (mv.scents ) -masks.goron (mv.goron ) -masks.romani (mv.romani ) -masks.troupe_leader (mv.troupe_leader) -masks.kafei (mv.kafei ) -masks.couples (mv.couples ) -masks.truth (mv.truth ) -masks.zora (mv.zora ) -masks.kamaro (mv.kamaro ) -masks.gibdo (mv.gibdo ) -masks.garos (mv.garos ) -masks.captains (mv.captains ) -masks.giants (mv.giants ) -masks.fierce_deity (mv.fierce_deity ) - -quantities.arrows (69) -quantities.bombs (69) -quantities.bombchu (69) -quantities.sticks (69) -quantities.nuts (69) -quantities.beans (69) -quantities.kegs (69) +-- gimme gimme gimme +local addrs = require "addrs" +require "item values" +local inv = addrs.inventory +local masks = addrs.masks +local quantities = addrs.quantities +_=addrs.target_style and addrs.target_style(1) +--addrs.buttons_enabled (0) +--addrs.infinite_sword(1) +addrs.owl_save (1) +addrs.sot_count (0) +_=addrs.bubble_timer and addrs.bubble_timer(0) +-- +addrs.sword_shield (0x23) +addrs.quiver_bag (0x1B) +addrs.hearts (16*20) +addrs.max_hearts (16*20) +addrs.doubled_hearts(20) +addrs.owls_hit (0xFFFF) +addrs.map_visible (0xFFFF) +addrs.map_visited (0xFFFF) +addrs.wallet_size (32) +addrs.rupees (999) +addrs.banked_rupees (9999) +addrs.magic (0x60) +--addrs.has_magic (1) +addrs.has_normal_magic(1) +addrs.has_double_magic(1) +addrs.chateau_romani(8) +addrs.quest_items (0x00FFFFFF) + +addrs.lottery_code_1(1*10000 + 2*0x100 + 3) +addrs.lottery_code_2(4*10000 + 5*0x100 + 6) +addrs.lottery_code_3(7*10000 + 8*0x100 + 9) +addrs.spider_mask_color_1(0) +addrs.spider_mask_color_2(0) +addrs.spider_mask_color_3(0) +addrs.spider_mask_color_4(0) +addrs.spider_mask_color_5(0) +addrs.bombers_code_1(1) +addrs.bombers_code_2(2) +addrs.bombers_code_3(3) +addrs.bombers_code_4(4) +addrs.bombers_code_5(5) + +addrs.items_wft(7) +addrs.items_sht(7) +addrs.items_gbt(7) +addrs.items_stt(7) +addrs.keys_wft(69) +addrs.keys_sht(69) +addrs.keys_gbt(69) +addrs.keys_stt(69) +addrs.fairies_wft(69) +addrs.fairies_sht(69) +addrs.fairies_gbt(69) +addrs.fairies_stt(69) + +--addrs.slulltula_count_wf(69) +--addrs.slulltula_count_gb(69) + +--inv.b_button (0x4F) -- don't really need this +inv.ocarina (0x00) +inv.bow (0x01) +inv.fire_arrows (0x02) +inv.ice_arrows (0x03) +inv.light_arrows (0x04) +inv.bombs (0x06) +inv.bombchu (0x07) +inv.deku_stick (0x08) +inv.deku_nut (0x09) +inv.magic_beans (0x0A) +inv.powder_keg (0x0C) +inv.pictograph (0x0D) +inv.lens_of_truth (0x0E) +inv.hookshot (0x0F) +inv.fairy_sword (0x10) +inv.bottle_1 (0x12) +inv.bottle_2 (0x1B) +inv.bottle_3 (0x1A) +inv.bottle_4 (0x18) +inv.bottle_5 (0x16) +inv.bottle_6 (0x25) +--addrs.event_1 (0x05) +--addrs.event_2 (0x0B) +--addrs.event_3 (0x11) + +local mv = mask_values +if version == "JP10" or version == "JP11" then + mv = mask_values_early +end + +masks.postman (mv.postman ) +masks.all_night (mv.all_night ) +masks.blast (mv.blast ) +masks.stone (mv.stone ) +masks.great_fairy (mv.great_fairy ) +masks.deku (mv.deku ) +masks.keaton (mv.keaton ) +masks.bremen (mv.bremen ) +masks.bunny (mv.bunny ) +masks.don_gero (mv.don_gero ) +masks.scents (mv.scents ) +masks.goron (mv.goron ) +masks.romani (mv.romani ) +masks.troupe_leader (mv.troupe_leader) +masks.kafei (mv.kafei ) +masks.couples (mv.couples ) +masks.truth (mv.truth ) +masks.zora (mv.zora ) +masks.kamaro (mv.kamaro ) +masks.gibdo (mv.gibdo ) +masks.garos (mv.garos ) +masks.captains (mv.captains ) +masks.giants (mv.giants ) +masks.fierce_deity (mv.fierce_deity ) + +quantities.arrows (69) +quantities.bombs (69) +quantities.bombchu (69) +quantities.sticks (69) +quantities.nuts (69) +quantities.beans (69) +quantities.kegs (69) diff --git a/heuristics.py b/heuristics.py index 4f29b44..b4b7687 100644 --- a/heuristics.py +++ b/heuristics.py @@ -1,20 +1,39 @@ -def try_scene(f): +def try_makerom(f): f.seek(0) - while True: - command = f.read(8) - if len(command) == 0: + if f.read(12) == b'\x80\x37\x12\x40\x00\x00\x00\x0f\x80\x00\x04\x00': + return True + return False + +def try_dmadata(f): + f.seek(0) + if f.read(20) == b"\x00\x00\x00\x00\x00\x00\x10\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x60": + return True + return False + +def try_actor(f): + if True: + # this is dumb. + # actors are just object files really, + # so anything we can detect with would just detect code + # or inconsistent data. + # maybe there's some common-looking function between them. + return False + f.seek(-4*4, 2) + end = f.tell() + for i in range(end, end - 0x200, -4): + if i <= 0: return False - if command[2:4] != b'\x00\x00': + f.seek(i) + #row = f.read(0x10) + row = f.read(0xC) + if len(row) == 0: return False - if command[0] > 0x1e: - return False - if command[4] != 0x02 and command[4] != 0x00: - if command[0] not in (0x05, 0x10, 0x11, 0x12): - return False - if command == b'\x14\x00\x00\x00\x00\x00\x00\x00': + #if row == b'\x82\x00\x00\x10\x82\x00\x00\x14\x82\x00\x00\x18\x82\x00\x00\x1c': + # return True + if row == b'\x82\x00\x00\x10\x82\x00\x00\x14\x82\x00\x00\x18': return True -def try_room(f): +def try_scene_or_room(f, bank=2): # note: doesn't detect syotes_room_0 because it's missing a header f.seek(0) while True: @@ -25,16 +44,22 @@ def try_room(f): return False if command[0] > 0x1e: return False - if command[4] != 0x03 and command[4] != 0x00: + if command[4] != bank and command[4] != 0x00: if command[0] not in (0x05, 0x10, 0x11, 0x12): return False if command == b'\x14\x00\x00\x00\x00\x00\x00\x00': return True def detect_format(f, fn=None): - if try_scene(f): + if try_makerom(f): + return None + if try_dmadata(f): + return None + if try_actor(f): + return 'actor' + if try_scene_or_room(f, 2): return 'scene' - if try_room(f): + if try_scene_or_room(f, 3): return 'room' return None