build improvements (no binary changes)

This commit is contained in:
4am 2024-06-11 11:21:32 -04:00
parent 52fe63f1d3
commit a6c3fc70f6
4 changed files with 85 additions and 66 deletions

View File

@ -103,7 +103,7 @@ HELP=res/HELP
JOYSTICK=res/JOYSTICK
TITLE=res/TITLE
.PHONY: preconditions compress attract cache clean mount all al
.PHONY: compress attract cache clean mount all al
$(HDV): $(PROBOOTHD) $(LAUNCHER.SYSTEM) $(PRELAUNCH) $(X) $(TOTAL.DATA) $(TITLE.ANIMATED.SOURCES) $(ICONS) $(FINDER.DATA) $(FINDER.ROOT) $(PREFS.CONF)
cp res/blank.hdv "$@"
@ -132,11 +132,12 @@ $(GAMES.CONF): $(MD)
$(GAMES.SORTED): $(GAMES.CONF)
awk -F, '/,/ { print $$2 }' < "$(GAMES.CONF)" | awk -F= '{ print $$1 }' | sort > "$@"
# extract files from original disk images and move them to their final directories
$(X): $(GAMES.CONF)
mkdir -p "$@" "$(BUILDDIR)"/X.INDEXED
$(PARALLEL) '$(CADIUS) EXTRACTVOLUME {} "$@"/ >>"$(BUILDDIR)"/log' ::: res/dsk/*.po
rm -f "$@"/**/.DS_Store "$@"/**/PRODOS* "$@"/**/LOADER.SYSTEM* "$@"/**/_FileInformation.txt
for f in $$(grep '^....1' "$(GAMES.CONF)" | awk '!/^$$|^#/' | awk -F, '/,/ { print $$2 }' | awk -F= '{ print $$1 }'); do mv "$@"/"$$(basename $$f)"/"$$(basename $$f)"* "$(BUILDDIR)"/X.INDEXED/; rm -rf "$@"/"$$(basename $$f)"; done
for f in $$(grep '^....1' "$(GAMES.CONF)" | awk '!/^$$|^#/' | awk -F, '/,/ { print $$2 }' | awk -F= '{ print $$1 }'); do mv "$@"/"$$f"/"$$f"* "$(BUILDDIR)"/X.INDEXED/; rm -rf "$@"/"$$f"; done
(cd "$(BUILDDIR)"/X.INDEXED/ && for f in *; do echo "$$f"; done) > "$(XSINGLE.LIST)"
for d in "$@"/*; do mv "$$d"/* "$@"/; rmdir "$$d"; done
@touch "$@"
@ -145,23 +146,28 @@ $(X): $(GAMES.CONF)
$(ATTRACT.IDX): $(MD)
bin/buildokvs.sh < res/ATTRACT.CONF > "$@"
# precompute binary data structure and substitute special characters in global help
$(HELPTEXT): $(MD)
bin/converthelp.sh res/HELPTEXT "$@"
# precompute binary data structure and substitute special characters in credits
$(CREDITS): $(MD)
bin/converthelp.sh res/CREDITS "$@"
# precompute binary data structures and substitute special characters for each game's help
$(GAMEHELP): $(GAMEHELP.SOURCES) | $(MD)
mkdir -p "$@"
$(PARALLEL) 'bin/converthelp.sh "{}" "$@/{/}"' ::: res/GAMEHELP/*
@touch "$@"
# precompute binary data structures for slideshow configuration files
$(SS): $(SS.SOURCES) | $(MD)
mkdir -p "$@"
$(PARALLEL) '[ $$(echo "{/}" | cut -c-3) = "ACT" ] && bin/buildslideshow.sh -d "$(GAMES.CONF)" < "{}" > "$@/{/}" || bin/buildslideshow.sh "$(GAMES.CONF)" < "{}" > "$@/{/}"' ::: res/SS/*
$(PARALLEL) '[ $$(echo "{/}" | cut -c-3) = "ACT" ] && bin/buildslideshow.py -d "$(GAMES.CONF)" < "{}" > "$@/{/}" || bin/buildslideshow.py "$(GAMES.CONF)" < "{}" > "$@/{/}"' ::: res/SS/*
(cd "$(BUILDDIR)"/SS/ && for f in *; do echo "$$f"; done) > "$(SS.LIST)"
@touch "$@"
# precompute binary data structures for each game's mini-attract configuration file
$(ATTRACT): $(ATTRACT.SOURCES) | $(MD)
mkdir -p "$@"
$(PARALLEL) 'bin/buildokvs.sh < "{}" > "$@/{/}"' ::: res/ATTRACT/*
@ -169,6 +175,7 @@ $(ATTRACT): $(ATTRACT.SOURCES) | $(MD)
(cd "$(ATTRACT)"/ && for f in [QRSTUVWXYZ]*; do echo "$$f"; done) > "$(MINI.ATTRACT1.LIST)"
@touch "$@"
# create lists of specific files used to build data structures later
$(ACTION.HGR0.LIST): $(ACTION.HGR.SOURCES) | $(MD)
(cd res/ACTION.HGR/ && for f in [ABCD]*; do echo "$$f"; done) > "$@"
@ -343,17 +350,20 @@ $(TOTAL.DATA): $(FX) $(PRELAUNCH) $(DEMO) $(SS) $(X) $(ATTRACT) $(ATTRACT.IDX) $
bin/addfile.sh "$(JOYSTICK)" "$(TOTAL.DATA)" > src/index/joystick.idx.a
@touch "$@"
# assemble main program
$(LAUNCHER.SYSTEM): $(LAUNCHER.SOURCES) | $(MD)
$(ACME) -DBUILDNUMBER=`git rev-list --count HEAD` src/4cade.a 2>"$(BUILDDIR)"/relbase.log
$(ACME) -r "$(BUILDDIR)"/4cade.lst -DBUILDNUMBER=`git rev-list --count HEAD` -DRELBASE=`cat "$(BUILDDIR)"/relbase.log | grep "RELBASE =" | cut -d"=" -f2 | cut -d"(" -f2 | cut -d")" -f1` src/4cade.a
@touch "$@"
# assemble launchers for self-running demos
$(DEMO): $(DEMO.SOURCES) | $(MD)
mkdir -p "$@"
$(PARALLEL) 'if grep -q "^!to" "{}"; then $(ACME) "{}"; fi' ::: src/demo/*.a
(cd "$(DEMO)"/ && for f in *; do echo "$$f"; done) > "$(DEMO.LIST)"
@touch "$@"
# assemble graphic effects
$(FX): $(FX.SOURCES) | $(MD)
mkdir -p "$@" "$(BUILDDIR)"/FX.INDEXED "$(BUILDDIR)"/FXDATA "$(BUILDDIR)"/FXCODE
$(PARALLEL) 'if grep -q "^!to" "{}"; then $(ACME) "{}"; fi' ::: src/fx/*.a
@ -361,11 +371,13 @@ $(FX): $(FX.SOURCES) | $(MD)
(cd "$(BUILDDIR)"/FXDATA/ && for f in *; do echo "$$f"; done) > "$(FXDATA.LIST)"
@touch "$@"
# assemble launchers for games
$(PRELAUNCH): $(PRELAUNCH.SOURCES) | $(MD)
mkdir -p "$@" "$(BUILDDIR)"/PRELAUNCH.INDEXED
$(PARALLEL) 'if grep -q "^!to" "{}"; then $(ACME) "{}"; fi' ::: src/prelaunch/*.a
@touch "$@"
# assemble bootloader
$(PROBOOTHD): $(PROBOOT.SOURCES) | $(MD)
$(ACME) -r "$(BUILDDIR)"/proboothd.lst src/proboothd/proboothd.a
@touch "$@"

View File

@ -36,12 +36,12 @@ def build(records, args):
output_file_size += standard_size
# yield OKVS header (2 x 2 bytes, unsigned int, little-endian)
yield struct.pack('<H', len(records))
yield struct.pack('<H', 0)
yield struct.pack('<2H', len(records), 0)
for rec in records:
filename, dummy, dummy = rec.partition('=')
key, dummy, addr = filename.partition('#')
key_length = len(key)
filename = os.path.join(args.input_directory, filename)
rec_offset = standard_offset
rec_size = standard_size
@ -49,14 +49,14 @@ def build(records, args):
# yield record length (1 byte, unsigned byte)
if addr:
# if filename is in the form 'NAME#06ADDR' then create extended index record
yield struct.pack('B', len(key)+9)
yield struct.pack('B', key_length+9)
# trim '06' so we get just the starting address
addr = addr[2:]
else:
yield struct.pack('B', len(key)+7)
yield struct.pack('B', key_length+7)
# yield key (Pascal-style string)
yield struct.pack(f'{len(key)+1}p', key.encode('ascii'))
yield struct.pack(f'{key_length+1}p', key.encode('ascii'))
if os.path.exists(filename):
rec_offset = output_file_size

65
bin/buildslideshow.py Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env python3
# flags
# -d include game display name (default off = display name will be 0-length string)
# parameters
# stdin - input containing slideshow (e.g. some file in res/SS/)
# stdout - binary OKVS data structure
# 1 - list of games with metadata (e.g. build/GAMES.CONF)
import argparse
import struct
import sys
# indexes into |flags| as string
iNeedsJoystick = 0
iNeeds128K = 1
# maps of flag raw string value -> value in final flags byte
kNeedsJoystick = {'0': 0, '1': 128}
kNeeds128K = {'0': 0, '1': 64}
def build(records, args):
with open(args.games_file, 'r') as games_file_handle:
games_list = [x.strip() for x in games_file_handle.readlines()]
games_list = [x.replace('=',',').split(',')
for x in games_list
if x and x[0] not in ('#', '[')]
games_cache = {}
for flags, key, displayname in games_list:
games_cache[key] = (flags, args.displayname and displayname or "")
record_count = len(records)
# yield OKVS header (2 x 2 bytes, unsigned int, little-endian)
yield struct.pack('<2H', record_count, 0)
for key, dummy, value in records:
filename = value or key
flags, displayname = games_cache[filename]
# yield record length (1 byte)
yield struct.pack('B', len(key) + len(value) + len(displayname) + 5)
# yield key (Pascal-style string)
yield struct.pack(f'{len(key)+1}p', key.encode('ascii'))
# yield value (Pascal-style string)
yield struct.pack(f'{len(value)+1}p', value.encode('ascii'))
# yield display name (Pascal-style string)
yield struct.pack(f'{len(displayname)+1}p', displayname.encode('ascii'))
# yield flags
yield struct.pack('B', kNeedsJoystick[flags[iNeedsJoystick]] + \
kNeeds128K[flags[iNeeds128K]])
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Build indexed OKVS structure from slideshow configuration file")
parser.add_argument("games_file")
parser.add_argument("-d", "--displayname", action="store_true", default=False, help="include game display name (default off = display name will be 0-length string)")
args = parser.parse_args()
records = [x.strip() for x in sys.stdin.readlines()]
records = [x.partition('=') for x in records if x and x[0] not in ('#', '[')]
for b in build(records, args):
sys.stdout.buffer.write(b)

View File

@ -1,58 +0,0 @@
#!/bin/bash
# flags
# -d include game display name (default off = display name will be 0-length string)
# parameters
# stdin - input containing slideshow (e.g. some file in res/SS/)
# stdout - binary OKVS data structure
# 1 - list of games with metadata (e.g. build/GAMES.CONF)
include_displayname=false
while getopts ":d" opt; do
case $opt in
d) include_displayname=true
;;
esac
done
shift $((OPTIND-1))
games=$(cat "$1")
# make temp file with just the key/value pairs (strip blank lines, comments, eof marker)
records=$(mktemp)
tr -d "\r" | awk '!/^$|^#/' > "$records"
# make temp assembly source file that represents the binary OKVS data structure
source=$(mktemp)
(echo "*=0" # dummy program counter for assembler
echo "!le16 $(wc -l <"$records"), 0" # OKVS header
while IFS="=" read -r key value; do
[ -n "$value" ] && filename="$value" || filename="$key"
line=$(echo "$games" | awk '/,'"$filename"'=/')
needsjoystick=$(echo "$line" | cut -c1) # 'requires joystick' flag (0 or 1)
needs128k=$(echo "$line" | cut -c2) # 'requires 128K' flag (0 or 1)
if [ "$include_displayname" = false ]; then
displayname=""
else
displayname=$(echo "$line" | tr -d "\r" | awk -F= '{ print $2 }')
fi
echo "!byte ${#key}+${#value}+${#displayname}+5" # OKVS record length
echo "!byte ${#key}" # OKVS key length
echo "!text \"$key\"" # OKVS key
echo "!byte ${#value}" # OKVS value length
echo "!text \"$value\"" # OKVS value
echo "!byte ${#displayname}"
echo "!text \"$displayname\""
echo "!byte $((needsjoystick*128))+$((needs128k*64))"
done < "$records") > "$source"
# assemble temp source file into binary OKVS data structure, then output that
out=$(mktemp)
acme -o "$out" "$source"
cat "$out"
# clean up
rm "$out"
rm "$source"
rm "$records"