From 1693213835af49a7b97675d2799759aaaf3b40ba Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Thu, 21 Mar 2024 00:33:44 -0500 Subject: [PATCH] initial base for local items, need to finish --- worlds/kdl3/Aesthetics.py | 4 +-- worlds/kdl3/Rom.py | 5 +-- worlds/kdl3/Room.py | 30 ++++++++++++++-- worlds/kdl3/data/kdl3_basepatch.bsdiff4 | Bin 2411 -> 2567 bytes worlds/kdl3/{data => src}/APPauseIcons.dat | Bin worlds/kdl3/src/kdl3_basepatch.asm | 40 ++++++++++++++++++++- 6 files changed, 70 insertions(+), 9 deletions(-) rename worlds/kdl3/{data => src}/APPauseIcons.dat (100%) diff --git a/worlds/kdl3/Aesthetics.py b/worlds/kdl3/Aesthetics.py index 8c7363908f..55ad0f2722 100644 --- a/worlds/kdl3/Aesthetics.py +++ b/worlds/kdl3/Aesthetics.py @@ -420,7 +420,7 @@ def rgb888_to_bgr555(red, green, blue) -> bytes: return struct.pack("H", outcol) -def get_palette_bytes(palette, target, offset, factor): +def get_palette_bytes(palette, target, offset, factor) -> bytes: output_data = bytearray() for color in target: hexcol = palette[color] @@ -431,4 +431,4 @@ def get_palette_bytes(palette, target, offset, factor): col = tuple(int(int(factor*x) + offset) for x in col) byte_data = rgb888_to_bgr555(col[0], col[1], col[2]) output_data.extend(bytearray(byte_data)) - return output_data + return bytes(output_data) diff --git a/worlds/kdl3/Rom.py b/worlds/kdl3/Rom.py index b8a81dc0e3..0505b2a14a 100644 --- a/worlds/kdl3/Rom.py +++ b/worlds/kdl3/Rom.py @@ -387,9 +387,6 @@ def patch_rom(world: "KDL3World", patch: KDL3ProcedurePatch): patch.write_file("kdl3_basepatch.bsdiff4", get_data(__name__, os.path.join("data", "kdl3_basepatch.bsdiff4"))) - tiles = get_data(__name__, os.path.join("data", "APPauseIcons.dat")) - patch.write_token(APTokenTypes.WRITE, 0x3F000, tiles) - # Write open world patch if world.options.open_world: patch.write_token(APTokenTypes.WRITE, 0x143C7, bytes([0xAD, 0xC1, 0x5A, 0xCD, 0xC1, 0x5A, ])) @@ -449,7 +446,7 @@ def patch_rom(world: "KDL3World", patch: KDL3ProcedurePatch): patch.write_token(APTokenTypes.WRITE, 0x4A38D, world.random.choice(music_choices).to_bytes(1, "little")) for room in rooms: - room.patch(patch) + room.patch(patch, bool(world.options.consumables.value), True) if world.options.virtual_console in [1, 3]: # Flash Reduction diff --git a/worlds/kdl3/Room.py b/worlds/kdl3/Room.py index 6c2363928f..e0edc85ef5 100644 --- a/worlds/kdl3/Room.py +++ b/worlds/kdl3/Room.py @@ -2,6 +2,7 @@ import struct import typing from BaseClasses import Region, ItemClassification from worlds.Files import APTokenTypes +from .ClientAddrs import consumable_addrs, star_addrs if typing.TYPE_CHECKING: from .Rom import KDL3ProcedurePatch @@ -43,14 +44,39 @@ class KDL3Room(Region): self.consumables = consumables self.consumable_pointer = consumable_pointer - def patch(self, patch: "KDL3ProcedurePatch"): + def patch(self, patch: "KDL3ProcedurePatch", consumables: bool, local_items: bool): patch.write_token(APTokenTypes.WRITE, self.pointer + 2, self.music.to_bytes(1, "little")) animals = [x.item.name for x in self.locations if "Animal" in x.name] if len(animals) > 0: for current_animal, address in zip(animals, self.animal_pointers): patch.write_token(APTokenTypes.WRITE, self.pointer + address + 7, animal_map[current_animal].to_bytes(1, "little")) - if self.multiworld.worlds[self.player].options.consumables: + if local_items: + for location in self.locations: + if not location.address or location.item.player != self.player: + continue + item = location.item.code + item_idx = item & 0x00000F + location_idx = location.address & 0xFFFF + if location_idx & 0xF00 in (0x300, 0x400, 0x500, 0x600): + # consumable or star, need remapped + location_base = location_idx & 0xF00 + if location_base == 0x300: + # consumable + location_idx = consumable_addrs[location_idx & 0xFF] | 0x1000 + else: + # star + location_idx = star_addrs[location.address] | 0x2000 + if item & 0x000070 == 0: + patch.write_token(APTokenTypes.WRITE, 0x4B000 + location_idx, bytes([item_idx | 0x10])) + elif item & 0x000010 > 0: + patch.write_token(APTokenTypes.WRITE, 0x4B000 + location_idx, bytes([item_idx | 0x20])) + elif item & 0x000020 > 0: + patch.write_token(APTokenTypes.WRITE, 0x4B000 + location_idx, bytes([item_idx | 0x40])) + elif item & 0x000040 > 0: + patch.write_token(APTokenTypes.WRITE, 0x4B000 + location_idx, bytes([item_idx | 0x80])) + + if consumables: load_len = len(self.entity_load) for consumable in self.consumables: location = next(x for x in self.locations if x.name == consumable["name"]) diff --git a/worlds/kdl3/data/kdl3_basepatch.bsdiff4 b/worlds/kdl3/data/kdl3_basepatch.bsdiff4 index cd002121cd38dcb319ba2148ced46c9592c3905b..662467bac0a677ffb22fb9878e09bcc5aff70a01 100644 GIT binary patch literal 2567 zcmYL|dpy&N8^^!9F|)a+S>?7_wp7M9mzrZ{)MUtzYvfX+D=i^qk+n##fFZPQlkq*?I@P{35GPbSll2(&3$#53Q* zlUf6J`xwl{N}dc*`l3@k|G0Zd5 z|KE7Sod}I@p6cpn7_i)ZJCXho_Q8PggzuJwqA@>GgI2V0dMD3R1G@qVL()!QsGIATSSOK}5YQ00R-J z@j!GO$eD-5mdEDyGSEUi;8F<%pWxJpcp}s~hhoi#MuU+!inY5wKm>HjnRcZOxD=jT z1OTx=(*OQM6SbTU4`vSbX!&dSQ*r<)2e zdnoj76u^U&UaT>!v^#ZGxd{yYRAG|&*;(`B;Q8qf2pd1|E7l7h_Tf2upRy0Wsyuf zV%@s<)MHP>&GO9}SNQp?*q_lI8C70&f3BCcv?07aCL;c^o9%IL-BH6xb!6%TH=RyPY2eN^?H&|r z7xv=-$J0g`Mz~j|Yv~yp^7OYj^}3OK3*B22nbXh8jJ`0S_K&5BBPEE<#LXFDrs>+X zISwtYMt)^l^!QW~wGin&UT}YPcXhA5ELqFf&ZgZA;Qe|hw0l??gS4BW)LelK1IEzY>z5}40s-IdITo_fUzRr1-9EzhIRHY21&8mioUl+eGE~(O* z6!5pN=d85u)crBD@MsEhJraJUV6|i-E+twnsVc2}0e&f*!xOJmiEWv=@-lBiFR>T{ zDijJQS5uGzVsJQ^tEVCc0w z_`Bo#;BY80x^4Uuyz^6F%v1gZYLvLVrpb!madDbMKY9Ge>3951+t1iKzM0`kt*#rE zHbTwx3&XX{_Cz!8V3WfRhLWorC~qme3q%L0JD+hq8+GB%>_W$-wKCh5@_}K8b9+9W4L$Y+LKZKzEu> ze`$dd?fH7cgWhJ2T>mgyTRyTggSVlXwBFwoS#mk?qT3(2i|ifGEPO`2UdC1pdlh_q zZNgJddnf-u^MvBM#Wu3elM`f@#OmhX@_arMDa`r+f?HZqDhnAu6ThpzM=eF?T1Mr! zsT&VEo5cU^f!W_6awySxP)sHiIPMm5F7t6jgy+vN1)%LPLt z#EP-tLAfHLs`ED+4-{VOs7utAbU9z@6L{taHLzJ!>Grlh8a4(GX#N@;GI{CVQAA73 zlo39VcHxBDslp_XK14YD8ezm_;BRtj)SqBv>}!-`A2b zSQdQuNx%Igv6l5Z4iSQq5!Si)Zc z%3TB*A^IW$w#&Fa_H?FI$Z_gOEjF)|%%rYmRyK+kuD6*oUAOzzrGTe2Fm9+KrWvt)y{2(u>Zb#il=8#SmWzfsd<^W@nNEM5gSKs#oUM& z4u>}sR-L$qaRvg0hTj;@++OPeU-v{}#aHJJNh~_JM7ERGJzwrB#^+M;%WHEa_^zI^ z(7c0nRkX5O2gCKYwoF~mh5cxEe}EG98wvcTi0FvKRERT z62Kh_hT2JWc`^2g{RW3T&O60$XKp8vTjGO?9$sFZ-r{oQ*j>+w7aX?WeG?fT8#6p}jqgj`c`e$|UIPL3C= z@bsQ|c`VXzuX+d*{l=2O*7`6hU#i!2K=`^iH?RdpLEKl@IomQ{6rVsMr8Q<~Aw9%& zP)PQP&(?YP{=B(4JQiMCZrtxP91*o8x1WEjE(sp>C_jDEuCcH!_?cagwGVI$*9ER* zLbe&}*zBFVdFcy@ym)%|viO;STJvM!d7;5GY2u5B4~2581K;|^-4XiYP)Rm4K&=Lq X*jnq6=>=20pW0G|(nBA>t~C8WNR&{E literal 2411 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 R2S2ZGPW5pM7JXgjzX0o>8Uz3U diff --git a/worlds/kdl3/data/APPauseIcons.dat b/worlds/kdl3/src/APPauseIcons.dat similarity index 100% rename from worlds/kdl3/data/APPauseIcons.dat rename to worlds/kdl3/src/APPauseIcons.dat diff --git a/worlds/kdl3/src/kdl3_basepatch.asm b/worlds/kdl3/src/kdl3_basepatch.asm index e419d0632f..4ddbd2b105 100644 --- a/worlds/kdl3/src/kdl3_basepatch.asm +++ b/worlds/kdl3/src/kdl3_basepatch.asm @@ -519,8 +519,16 @@ ConsumableSet: BRA .LoopHead ; return to loop head .ApplyCheck: LDA $A000, X ; consumables index + PHA ORA #$0001 STA $A000, X + PLA + AND #$00FF + BNE .Return + TXA + ORA #$1000 + JSL ApplyLocalCheck + .Return: PLY PLX PLA @@ -1183,8 +1191,15 @@ StarsSet: BRA .2LoopHead .2LoopEnd: LDA $B000, X + PHA ORA #$0001 STA $B000, X + PLA + AND #$00FF + BNE .Return + TXA + ORA #$2000 + JSL ApplyLocalCheck .Return: PLY PLX @@ -1199,6 +1214,26 @@ StarsSet: STA $39D7 BRA .Return +org $07A680 +ApplyLocalCheck: +; args: A-address of check following $08B000 + TAX + LDA $08B000, X + AND #$00FF + TAY + LDX #$0000 + .Loop: + LDA $C000, X + BEQ .Apply + INX + INX + CPX #$0010 + BCC .Loop + BRA .Return ; this is dangerous, could lose a check here + .Apply: + STY $C000, X + .Return: + RTL org $07C000 db "KDL3_BASEPATCH_ARCHI" @@ -1234,4 +1269,7 @@ org $07E040 db $3A, $01 db $3B, $05 db $3C, $05 - db $3D, $05 \ No newline at end of file + db $3D, $05 + +org $07F000 +incbin "APPauseIcons.bin" \ No newline at end of file