Skip to content

Commit

Permalink
Merge pull request #6 from manz/dev/battle_items_two_columns
Browse files Browse the repository at this point in the history
Dev/battle items two columns
  • Loading branch information
manz authored Sep 16, 2024
2 parents b48d89d + fe2f0d3 commit 36f6173
Show file tree
Hide file tree
Showing 81 changed files with 4,956 additions and 1,849 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI

on:
push:
branches:
- master
create:
tags:

pull_request:

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install Requirements
if: steps.cache-requirements.outputs.cache-hit != 'true'
run: pip install -r requirements.txt
- name: Build patch
run: ./build.py
- name: Upload nightly patch artifact
uses: actions/upload-artifact@v4
with:
name: ff4-nightly
path: build/ff4.ips
14 changes: 7 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ python:
- '3.4'
install: pip install -r requirements.txt
script: python3.4 build.py
deploy:
provider: releases
api_key:
secure: nRzGa4y5c1Au3rYSoepsyIM8m6NTvkobmze0iKqOpRkNkS0L+r+EfAySgVpOB9eFPDzkgIbjWPe5L1TbPs/UQDHxauPpL2xwJiDSKimGYipVGhVZoSwI6jREIc51zU4jqAi37kNUKPRsDg5HDKkE7IhnRlcEqppOkGT23/DYd7o=
file: build/ff4.ips
on:
repo: manz/ff4
#deploy:
# provider: releases
# api_key:
# secure: nRzGa4y5c1Au3rYSoepsyIM8m6NTvkobmze0iKqOpRkNkS0L+r+EfAySgVpOB9eFPDzkgIbjWPe5L1TbPs/UQDHxauPpL2xwJiDSKimGYipVGhVZoSwI6jREIc51zU4jqAi37kNUKPRsDg5HDKkE7IhnRlcEqppOkGT23/DYd7o=
# file: build/ff4.ips
# on:
# repo: manz/ff4
128 changes: 103 additions & 25 deletions build.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
#!/usr/bin/env python3
# coding:utf-8
#!/usr/bin/env python3.4
import os
import struct
from typing import Callable
from xml.etree import ElementTree

from a816.cpu.cpu_65c816 import snes_to_rom
from a816.program import Program
from a816.symbols import low_rom_bus
from script import Table
from script.formulas import long_low_rom_pointer
from script.pointers import read_pointers_from_xml, write_pointers_value_as_binary, write_pointers_addresses_as_binary, \
Pointer
from utils.font import convert_font_to_1bpp

from utils.font import convert_font_to_1bpp, convert_font_to_2bpp
from utils.smallvwf import generate_8x8_vwf_asset


def read_fixed_from_xml(input_file, table, formatter=None):
Expand All @@ -23,7 +27,8 @@ def read_fixed_from_xml(input_file, table, formatter=None):
for child in root:
text = child.text
pointer = Pointer(i)
pointer.value = table.to_bytes(formatter(text) if formatter else text) if text else b''
formatted_text = formatter(text) if formatter else text
pointer.value = table.to_bytes(formatted_text) if text else b''

if len(pointer.value) < length:
pad_length = length - len(pointer.value)
Expand Down Expand Up @@ -65,40 +70,84 @@ def build_patch(input, output):
ff4_asm = Program()
ff4_asm.assemble_as_patch(input, output)
ff4_asm.resolver.dump_symbol_map()
ff4_asm.exports_symbol_file("./build/ff4.cpu.sym")

def word_low_rom_pointer(base: int) -> Callable[[int], bytes]:
def inner_func(pointer: int) -> bytes:
snes_address = low_rom_bus.get_address(base) + pointer
return struct.pack("<H", snes_address.logical_value & 0xFFFF)

return inner_func


def build_pointed_16bits_lowrom(table, input_file, binary_text_file, pointers_file, address):
pointers = read_pointers_from_xml(input_file, table)

write_pointers_value_as_binary(pointers, binary_text_file)

pointer_addr = low_rom_bus.get_address(address) + (len(pointers) * 2)
physical_addr = pointer_addr.physical

assert physical_addr is not None, f"Physical address for {address:02x} not found."

write_pointers_addresses_as_binary(pointers, word_low_rom_pointer(physical_addr), pointers_file)


def build_text_asset(table, input_file, binary_text_file, pointers_file, address):
pointers = read_pointers_from_xml(input_file, table)

write_pointers_value_as_binary(pointers, binary_text_file)
write_pointers_addresses_as_binary(pointers, long_low_rom_pointer(snes_to_rom(address)), pointers_file)

pointer_addr = low_rom_bus.get_address(address)
physical_addr = pointer_addr.physical

assert physical_addr is not None, f"Physical address for {address:02x} not found."

write_pointers_addresses_as_binary(pointers, long_low_rom_pointer(physical_addr), pointers_file)


def build_fixed_asset(table, input_file, binary_text_file):
pointers = read_fixed_from_xml(input_file, table)
write_pointers_value_as_binary(pointers, binary_text_file)


def build_null_terminated(table, input_file, binary_text_file):
def build_null_terminated(table, input_file, binary_text_file, pointers_file=None):
pointers = read_stringarray_from_xml(input_file, table)
write_pointers_value_as_binary(pointers, binary_text_file)
if pointers_file:
write_pointers_addresses_as_binary(pointers, lambda v: struct.pack('<H', v), pointers_file)


def build_text_assets(banks):
for bank in banks:
build_text_asset(dialog_table, bank[0], bank[1], bank[2], bank[3])


def build_vwf_font_asset(font_file, data_file, len_table_file):
len_table, data = convert_font_to_1bpp(font_file)
def build_vwf_font_asset_2bpp(font_file, has_grid, data_file, len_table_file, char_height):
len_table, data = convert_font_to_2bpp(font_file, has_grid, char_height)

# Espace
len_table[0xFF] = 3
# Espace fine
len_table[0xFD] = 1
# Espace insécable
len_table[0xFE] = 2

with open(data_file, 'wb') as fd:
fd.write(data)
with open(len_table_file, 'wb') as fd:
fd.write(bytes(len_table.values()))


def build_vwf_font_asset(font_file, has_grid, data_file, len_table_file, char_height):
len_table, data = convert_font_to_1bpp(font_file, has_grid)

# œ
len_table[0xA0] = 7
# Espace
len_table[0xFF] = 5
len_table[0xFF] = 3
# Espace fine
len_table[0xFD] = 1
# Espace insécable
len_table[0xFE] = 5
len_table[0xFE] = 2

with open(data_file, 'wb') as fd:
fd.write(data)
Expand All @@ -108,9 +157,11 @@ def build_vwf_font_asset(font_file, data_file, len_table_file):

assets_builder = {
'script': build_text_asset,
'pointed_16bits_lowrom': build_pointed_16bits_lowrom,
'fixed': build_fixed_asset,
'nullterminated': build_null_terminated,
'vwf-font': build_vwf_font_asset
'vwf-font': build_vwf_font_asset,
'vwf-font-2bpp': build_vwf_font_asset_2bpp
}


Expand All @@ -123,30 +174,57 @@ def build_assets(assets):
if __name__ == '__main__':
dialog_table = Table('text/ff4fr.tbl')
menu_table = Table('text/ff4_menus.tbl')

lang = 'fr'
text_root = 'text/{lang}'.format(lang=lang)

assets_list = [
('script', dialog_table, os.path.join(text_root, '{lang}-bank1-1.xml'.format(lang=lang)), 'assets/bank1_1.dat',
('script', dialog_table, os.path.join(text_root, 'bank1-1.xml'), 'assets/bank1_1.dat',
'assets/bank1_1.ptr', 0x228000),
('script', dialog_table, os.path.join(text_root, '{lang}-bank1-2.xml'.format(lang=lang)), 'assets/bank1_2.dat',
('script', dialog_table, os.path.join(text_root, 'bank1-2.xml'), 'assets/bank1_2.dat',
'assets/bank1_2.ptr', 0x24A000),
('script', dialog_table, os.path.join(text_root, '{lang}-bank2.xml'.format(lang=lang)), 'assets/bank2.dat',
('script', dialog_table, os.path.join(text_root, 'bank2.xml'), 'assets/bank2.dat',
'assets/bank2.ptr', 0x25A000),
('vwf-font', 'fonts/vwf.png', 'assets/font.dat', 'assets/font_length_table.dat'),
('fixed', menu_table, os.path.join(text_root, '{lang}-items.xml'.format(lang=lang)), 'assets/items.dat'),
('fixed', menu_table, os.path.join(text_root, '{lang}-magic.xml'.format(lang=lang)), 'assets/magic.dat'),
('fixed', menu_table, os.path.join(text_root, '{lang}-characters_names.xml'.format(lang=lang)), 'assets/characters_names.dat'),
('fixed', menu_table, os.path.join(text_root, '{lang}-characters_names.xml'.format(lang=lang)), 'assets/characters_names.dat'),
('nullterminated', menu_table, os.path.join(text_root, '{lang}-places-names.xml'.format(lang=lang)), 'assets/places_names.dat')

('pointed_16bits_lowrom', menu_table,
os.path.join(text_root, 'battle_messages.xml'), 'assets/battle_messages.dat', 'assets/battle_messages.ptr',
0x298000),
('pointed_16bits_lowrom', menu_table,
os.path.join(text_root, 'battle_text.xml'), 'assets/battle_text.dat', 'assets/battle_text.ptr',
0x299900),

('vwf-font', 'fonts/vwf.png', False, 'assets/font.dat', 'assets/font_length_table.dat', 16),
('vwf-font', 'fonts/bold_vwf.png', False, 'assets/bold_font.dat', 'assets/bold_font_length_table.dat', 16),
(
'vwf-font', 'fonts/wicked_vwf.png', False, 'assets/wicked_font.dat', 'assets/wicked_font_length_table.dat',
16),
('vwf-font', 'fonts/book_vwf.png', False, 'assets/book_font.dat', 'assets/book_font_length_table.dat', 16),
('vwf-font-2bpp', 'fonts/8x8vwf2p.png', True, 'assets/menu_font.dat', 'assets/menu_font_length_table.dat',
8),

('fixed', menu_table, os.path.join(text_root, 'items.xml'), 'assets/items.dat'),
('fixed', menu_table, os.path.join(text_root, 'magic.xml'), 'assets/magic.dat'),
('fixed', menu_table, os.path.join(text_root, 'monsters.xml'), 'assets/monsters.dat'),
('fixed', menu_table, os.path.join(text_root, 'characters_names.xml'), 'assets/characters_names.dat'),
('fixed', menu_table, os.path.join(text_root, 'battle_commands.xml'), 'assets/battle_commands.dat'),

('nullterminated', menu_table, os.path.join(text_root, 'places-names.xml'), 'assets/places_names.dat'),
(
'nullterminated', menu_table, os.path.join(text_root, 'item_descriptions.xml'), 'assets/item_descriptions.dat'),
('nullterminated', menu_table, os.path.join(text_root, 'characters_classes.xml'),
'assets/classes.dat', 'assets/classes.ptr'),
]

build_assets(assets_list)

small_text = [
'Niveau',
'Gils'
]

generate_8x8_vwf_asset(small_text, 'vwf_precomp', 0x90)
menu_vwf_table = Table('text/vwf_precomp.tbl')

if not os.path.exists('build'):
os.mkdir('build')

build_patch('ff4.s', 'build/ff4.ips')


Loading

0 comments on commit 36f6173

Please sign in to comment.