Skip to content

Commit

Permalink
LADX: AP egg title screen (ArchipelagoMW#1683)
Browse files Browse the repository at this point in the history
  • Loading branch information
zig-for authored Apr 11, 2023
1 parent b02b329 commit 70ff19a
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 31 deletions.
20 changes: 10 additions & 10 deletions worlds/ladx/LADXR/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import importlib.util
import importlib.machinery
import os
import pkgutil

from .romTables import ROMWithTables
from . import assembler
Expand Down Expand Up @@ -61,7 +62,12 @@

# Function to generate a final rom, this patches the rom with all required patches
def generateRom(args, settings, ap_settings, auth, seed_name, logic, rnd=None, multiworld=None, player_name=None, player_names=[], player_id = 0):
rom = ROMWithTables(args.input_filename)
rom_patches = []

if ap_settings["ap_title_screen"]:
rom_patches.append(pkgutil.get_data(__name__, "patches/title_screen.bdiff4"))

rom = ROMWithTables(args.input_filename, rom_patches)
rom.player_names = player_names
pymods = []
if args.pymod:
Expand Down Expand Up @@ -271,6 +277,8 @@ def generateRom(args, settings, ap_settings, auth, seed_name, logic, rnd=None, m

patches.core.warpHome(rom) # Needs to be done after setting the start location.
patches.titleScreen.setRomInfo(rom, auth, seed_name, settings, player_name, player_id)
if ap_settings["ap_title_screen"]:
patches.titleScreen.setTitleGraphics(rom)
patches.endscreen.updateEndScreen(rom)
patches.aesthetics.updateSpriteData(rom)
if args.doubletrouble:
Expand Down Expand Up @@ -363,15 +371,7 @@ def clamp(x, min, max):
if x > max:
return max
return x
def bin_to_rgb(word):
red = word & 0b11111
word >>= 5
green = word & 0b11111
word >>= 5
blue = word & 0b11111
return (red, green, blue)
def rgb_to_bin(r, g, b):
return (b << 10) | (g << 5) | r
from patches.aesthetics import rgb_to_bin, bin_to_rgb

for address in range(start, end, 2):
packed = (rom.banks[bank][address + 1] << 8) | rom.banks[bank][address]
Expand Down
12 changes: 12 additions & 0 deletions worlds/ladx/LADXR/patches/aesthetics.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,15 @@ def updateSpriteData(rom):
rom.room_sprite_data_overworld[room_nr] = data
else:
rom.room_sprite_data_indoor[room_nr - 0x100] = data


def bin_to_rgb(word):
red = word & 0b11111
word >>= 5
green = word & 0b11111
word >>= 5
blue = word & 0b11111
return (red, green, blue)

def rgb_to_bin(r, g, b):
return (b << 10) | (g << 5) | r
2 changes: 1 addition & 1 deletion worlds/ladx/LADXR/patches/endscreen.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,4 @@ def updateEndScreen(rom):
addr = 0x1000
data = pkgutil.get_data(__name__, "nyan.bin")
rom.banks[0x3F][addr : addr + len(data)] = data

73 changes: 68 additions & 5 deletions worlds/ladx/LADXR/patches/titleScreen.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from ..backgroundEditor import BackgroundEditor
import subprocess
import binascii


from .aesthetics import rgb_to_bin, bin_to_rgb, prepatch
import copy
import pkgutil
CHAR_MAP = {'z': 0x3E, '-': 0x3F, '.': 0x39, ':': 0x42, '?': 0x3C, '!': 0x3D}


def _encode(s):
result = bytearray()
for char in s:
Expand Down Expand Up @@ -82,3 +80,68 @@ def setRomInfo(rom, seed, seed_name, settings, player_name, player_id):
ba.tiles[0x9820 + n] = 0x08 | pal
be.store(rom)
ba.store(rom)

def setTitleGraphics(rom):
BASE = 0x9800
ROW_SIZE = 0x20

be = BackgroundEditor(rom, 0x11, attributes=True)
for tile in be.tiles:
if be.tiles[tile] == 7:
be.tiles[tile] = 3

be.tiles[BASE + 10 * ROW_SIZE + 8] = 7
be.tiles[BASE + 10 * ROW_SIZE + 10] = 2
be.tiles[BASE + 10 * ROW_SIZE + 11] = 5
be.tiles[BASE + 11 * ROW_SIZE + 10] = 6
be.tiles[BASE + 11 * ROW_SIZE + 11] = 6
be.tiles[BASE + 12 * ROW_SIZE + 11] = 6
be.tiles[BASE + 11 * ROW_SIZE + 9] = 1
be.tiles[BASE + 12 * ROW_SIZE + 9] = 1
be.tiles[BASE + 12 * ROW_SIZE + 10] = 1
be.tiles[BASE + 13 * ROW_SIZE + 9] = 1
be.tiles[BASE + 13 * ROW_SIZE + 10] = 1

be.store(rom)

SKIP_INTRO = True
if SKIP_INTRO:
# Skip intro as it's causing problems
rom.banks[1][0x2F5B : 0x2F5B + 3] = [0xC3, 0x39, 0x6E]
# Disable initial music
rom.banks[1][0x2F03 : 0x2F03 + 5] = [0] * 5
# Disable music fade on reset
rom.banks[1][0x3436 : 0x3436 + 3] = [0] * 3


# Set egg palette
BASE = 0x3DEE
palettes = []
BANK = 0x21
for i in range(8):
palette = []
for c in range(4):
address = BASE + i * 8 + c * 2
packed = (rom.banks[BANK][address + 1] << 8) | rom.banks[BANK][address]
r,g,b = bin_to_rgb(packed)
palette.append([r, g, b])
palettes.append(palette)

for i in [1, 2, 5, 6, 7]:
palettes[i] = copy.copy(palettes[3])

def to_5_bit(r, g, b):
return [r >> 3, g >> 3, b >> 3]

palettes[1][3] = to_5_bit(0xFF, 0x80, 145)
palettes[2][2] = to_5_bit(119, 198, 155)
palettes[5][3] = to_5_bit(119, 198, 155)
palettes[6][3] = to_5_bit(192, 139, 215)
palettes[7][3] = to_5_bit(229, 196, 139)

for i in range(8):
for c in range(4):
address = BASE + i * 8 + c * 2
packed = rgb_to_bin(*palettes[i][c])
rom.banks[BANK][address] = packed & 0xFF
rom.banks[BANK][address + 1] = packed >> 8
Binary file added worlds/ladx/LADXR/patches/title_screen.bdiff4
Binary file not shown.
9 changes: 7 additions & 2 deletions worlds/ladx/LADXR/rom.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import bsdiff4
import binascii
import Utils

Expand All @@ -6,9 +7,13 @@


class ROM:
def __init__(self, filename):
def __init__(self, filename, patches=None):
data = open(Utils.user_path(filename), "rb").read()
#assert len(data) == 1024 * 1024

if patches:
for patch in patches:
data = bsdiff4.patch(data, patch)

self.banks = []
for n in range(0x40):
self.banks.append(bytearray(data[n*0x4000:(n+1)*0x4000]))
Expand Down
4 changes: 2 additions & 2 deletions worlds/ladx/LADXR/romTables.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ def __init__(self, rom):


class ROMWithTables(ROM):
def __init__(self, filename):
super().__init__(filename)
def __init__(self, filename, patches=None):
super().__init__(filename, patches)

# Ability to patch any text in the game with different text
self.texts = Texts(self)
Expand Down
9 changes: 8 additions & 1 deletion worlds/ladx/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ class DungeonShuffle(DefaultOffToggle, LADXROption):
"""
ladxr_name = "dungeonshuffle"

class APTitleScreen(DefaultOnToggle):
"""
Enables AP specific title screen and disables the intro cutscene
"""


class BossShuffle(Choice):
none = 0
shuffle = 1
Expand Down Expand Up @@ -396,5 +402,6 @@ class Palette(Choice):
'shuffle_compasses': ShuffleCompasses,
'shuffle_stone_beaks': ShuffleStoneBeaks,
'music_change_condition': MusicChangeCondition,
'nag_messages': NagMessages
'nag_messages': NagMessages,
'ap_title_screen': APTitleScreen,
}
17 changes: 8 additions & 9 deletions worlds/ladx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,16 +381,14 @@ def generate_output(self, output_directory: str):
# Kind of kludge, make it possible for the location to differentiate between local and remote items
loc.ladxr_item.location_owner = self.player

rom_path = "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced).gbc"
rom_name = "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced).gbc"
out_name = f"AP-{self.multiworld.seed_name}-P{self.player}-{self.multiworld.player_name[self.player]}.gbc"
out_file = os.path.join(output_directory, out_name)

rompath = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}.gbc")
out_path = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}.gbc")



parser = get_parser()
args = parser.parse_args([rom_path, "-o", out_name, "--dump"])
args = parser.parse_args([rom_name, "-o", out_name, "--dump"])

name_for_rom = self.multiworld.player_name[self.player]

Expand All @@ -408,14 +406,15 @@ def generate_output(self, output_directory: str):
player_names=all_names,
player_id = self.player)

handle = open(rompath, "wb")
handle = open(out_path, "wb")
rom.save(handle, name="LADXR")

handle.close()
patch = LADXDeltaPatch(os.path.splitext(rompath)[0]+LADXDeltaPatch.patch_file_ending, player=self.player,
player_name=self.multiworld.player_name[self.player], patched_path=rompath)
patch = LADXDeltaPatch(os.path.splitext(out_path)[0]+LADXDeltaPatch.patch_file_ending, player=self.player,
player_name=self.multiworld.player_name[self.player], patched_path=out_path)
patch.write()
if not DEVELOPER_MODE:
os.unlink(rompath)
os.unlink(out_path)

def generate_multi_key(self):
return bytearray(self.multiworld.random.getrandbits(8) for _ in range(10)) + self.player.to_bytes(2, 'big')
Expand Down
4 changes: 3 additions & 1 deletion worlds/ladx/docs/en_Links Awakening DX.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ This randomizer is based on (forked from) the wonderful work daid did on LADXR -

The autotracker code for communication with magpie tracker is directly copied from kbranch's repo - https://github.com/kbranch/Magpie/tree/master/autotracking

### Sprites
### Graphics

The following sprite sheets have been included with permission of their respective authors:

Expand All @@ -56,6 +56,8 @@ The following sprite sheets have been included with permission of their respecti
* Richard
* Tarin

Title screen graphics by toomanyteeth✨ (https://instagram.com/toomanyyyteeth)

## Some tips from LADXR...

<h3>Locations</h3>
Expand Down

0 comments on commit 70ff19a

Please sign in to comment.