sync build and UI code

This commit is contained in:
4am 2022-08-22 22:04:55 -04:00
parent d48bd6baa1
commit 4e7c832df0
444 changed files with 23853 additions and 3048 deletions

370
Makefile
View File

@ -1,99 +1,271 @@
#
# 4sports Makefile
# assembles source code, optionally builds a disk image and mounts it
# note: Windows users should probably use winmake.bat instead
#
# original by Quinn Dunki on 2014-08-15
# One Girl, One Laptop Productions
# http://www.quinndunki.com/blondihacks
#
# adapted by 4am on 2021-02-12
#
DISK=4sports.hdv
VOLUME=INSTANT.REPLAY
# third-party tools required to build
# https://sourceforge.net/projects/acme-crossass/
ACME=acme
# https://github.com/sicklittlemonkey/cadius
# version 1.4.0 or later
CADIUS=cadius
# https://bitbucket.org/magli143/exomizer/wiki/Home
EXOMIZER=exomizer mem -q -P23 -lnone
dsk: asm
cp res/blank.hdv build/"$(DISK)" >>build/log
cp res/_FileInformation.txt build/ >>build/log
$(CADIUS) ADDFILE build/"$(DISK)" "/$(VOLUME)/" "build/LAUNCHER.SYSTEM" >>build/log
rsync -aP res/PREFS.CONF build/PREFS.CONF >> build/log
bin/padto.sh 512 build/PREFS.CONF >>build/log
for f in res/TITLE res/COVER res/HELP res/GAMES.CONF res/ATTRACT.CONF res/FX.CONF res/DFX.CONF build/PREFS.CONF res/CREDITS res/HELPTEXT res/DECRUNCH res/JOYSTICK res/Finder.Data res/Finder.Root; do $(CADIUS) ADDFILE build/"$(DISK)" "/$(VOLUME)/" "$$f" >>build/log; done
bin/buildfileinfo.sh res/TITLE.HGR "06" "4000" >>build/log
bin/buildfileinfo.sh res/TITLE.DHGR "06" "4000" >>build/log
bin/buildfileinfo.sh res/ACTION.HGR "06" "3FF8" >>build/log
bin/buildfileinfo.sh res/ACTION.DHGR "06" "3FF8" >>build/log
bin/buildfileinfo.sh res/ACTION.GR "06" "6000" >>build/log
bin/buildfileinfo.sh res/ARTWORK.SHR "06" "1FF8" >>build/log
bin/buildfileinfo.sh res/ATTRACT "04" "8000" >>build/log
bin/buildfileinfo.sh res/SS "04" "4000" >>build/log
bin/buildfileinfo.sh res/ICONS "CA" "0000" >>build/log
for f in res/TITLE.HGR res/TITLE.DHGR res/ACTION.HGR res/ACTION.DHGR res/ACTION.GR res/ARTWORK.SHR res/ATTRACT res/SS res/DEMO res/ICONS; do rm -f "$$f"/.DS_Store; $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/$$(basename $$f)" "$$f" >>build/log; done
$(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/FX" "build/FX" >>build/log
for f in res/dsk/*.po; do $(CADIUS) EXTRACTVOLUME "$${f}" build/X/ >> build/log; done
rm -f build/X/**/.DS_Store build/X/**/PRODOS* build/X/**/LOADER.SYSTEM*
$(CADIUS) CREATEFOLDER build/"$(DISK)" "/$(VOLUME)/X/" >>build/log
for f in build/X/*; do $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/X/$$(basename $$f)" "$$f"; done >>build/log
bin/buildfileinfo.sh build/PRELAUNCH "06" "0106" >>build/log
$(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/PRELAUNCH" "build/PRELAUNCH" >>build/log
rsync -aP --exclude=STANDARD res/GAMEHELP build/ >>build/log
for f in res/TITLE.HGR/* res/TITLE.DHGR/*; do rsync --ignore-existing res/GAMEHELP/STANDARD build/GAMEHELP/$$(basename $$f); done
bin/buildfileinfo.sh build/GAMEHELP "04" "8000" >>build/log
$(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/GAMEHELP" "build/GAMEHELP" >>build/log
bin/changebootloader.sh build/"$(DISK)" build/proboothd
asm: asmproboot asmlauncher asmfx asmprelaunch
asmproboot: md
$(ACME) -r build/proboothd.lst src/proboothd/proboothd.a
asmlauncher: md
$(ACME) -DBUILDNUMBER=`git rev-list --count HEAD` src/4sports.a 2>build/relbase.log
$(ACME) -r build/4sports.lst -DBUILDNUMBER=`git rev-list --count HEAD` -DRELBASE=`cat build/relbase.log | grep "RELBASE =" | cut -d"=" -f2 | cut -d"(" -f2 | cut -d")" -f1` src/4sports.a
asmfx: md
for f in src/fx/*.a; do grep "^\!to" $${f} >/dev/null && $(ACME) $${f} >> build/log || true; done
bin/buildfileinfo.sh build/FX "06" "6000" >>build/log
asmprelaunch: md
for f in src/prelaunch/*.a; do grep "^\!to" $${f} >/dev/null && $(ACME) $${f} >> build/log; done
for f in res/TITLE.HGR/* res/TITLE.DHGR/*; do rsync --ignore-existing build/PRELAUNCH/STANDARD build/PRELAUNCH/$$(basename $$f); done
chd: dsk
chdman createhd -c none -i build/"$(DISK)" -o build/"$(DISK)".chd >>build/log
compress: md
for f in res/ACTION.HGR.UNCOMPRESSED/*; do o=res/ACTION.HGR/$$(basename $$f); [ -f "$$o" ] || ${EXOMIZER} "$$f"@0x4000 -o "$$o" >>build/log; done
for f in res/ACTION.DHGR.UNCOMPRESSED/*; do o=res/ACTION.DHGR/$$(basename $$f); [ -f "$$o" ] || ${EXOMIZER} "$$f"@0x4000 -o "$$o" >>build/log; done
for f in res/ARTWORK.SHR.UNCOMPRESSED/*; do o=res/ARTWORK.SHR/$$(basename $$f); [ -f "$$o" ] || ${EXOMIZER} "$$f"@0x2000 -o "$$o" >>build/log; done
attract: compress
bin/check-attract-mode.sh
bin/generate-mini-attract-mode.sh
mount: dsk
osascript bin/V2Make.scpt "`pwd`" bin/4sports.vii build/"$(DISK)"
md:
mkdir -p build/X build/FX build/PRELAUNCH build/GAMEHELP
touch build/log
clean:
rm -rf build/ || rm -rf build
all: clean dsk mount
al: all
#
# 4cade Makefile
# assembles source code, optionally builds a disk image and mounts it
# note: Windows users should probably use winmake.bat instead
#
# original by Quinn Dunki on 2014-08-15
# One Girl, One Laptop Productions
# http://www.quinndunki.com/blondihacks
#
# adapted by 4am on 2018-08-19
#
DISK=4sports.hdv
VOLUME=INSTANT.REPLAY
# third-party tools required to build
# https://sourceforge.net/projects/acme-crossass/
# version 0.96.3 or later
ACME=acme
# https://github.com/mach-kernel/cadius
# version 1.4.0 or later
CADIUS=cadius
# https://www.gnu.org/software/parallel/
PARALLEL=parallel
# https://python.org/
PYTHON=python3
# https://bitbucket.org/magli143/exomizer/wiki/Home
# version 3.1.0 or later
EXOMIZER=exomizer mem -q -P23 -lnone
dsk: index asmproboot asmlauncher
cp res/blank.hdv build/"$(DISK)"
cp res/_FileInformation.txt build/
$(CADIUS) ADDFILE build/"$(DISK)" "/$(VOLUME)/" build/LAUNCHER.SYSTEM -C >>build/log
cp res/PREFS.CONF build/PREFS.CONF
bin/padto.sh build/PREFS.CONF
#
# create _FileInformation.txt files for subdirectories
#
bin/buildfileinfo.sh res/ICONS "CA" "0000"
bin/buildfileinfo.sh build/FX "06" "6000"
cp src/prelaunch/_FileInformation.txt build/PRELAUNCH/
#
# add everything to the disk
#
for f in \
build/TOTAL.DATA \
build/PREFS.CONF \
res/Finder.Data \
res/Finder.Root; do \
$(CADIUS) ADDFILE build/"$(DISK)" "/$(VOLUME)/" "$$f" -C >>build/log; \
done
for f in \
res/DEMO \
res/TITLE.ANIMATED \
res/ICONS \
build/FX \
build/PRELAUNCH; do \
rm -f "$$f"/.DS_Store; \
$(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/$$(basename $$f)" "$$f" -C >>build/log; \
done
for i in 1 2 3 4 5 6; do \
$(CADIUS) RENAMEFILE build/"$(DISK)" "/$(VOLUME)/DEMO/SPCARTOON.$${i}$${i}" "SPCARTOON.$${i}." >>build/log; \
done
$(PARALLEL) '$(CADIUS) EXTRACTVOLUME {} build/X/ >>build/log' ::: res/dsk/*.po
rm -f build/X/**/.DS_Store build/X/**/PRODOS* build/X/**/LOADER.SYSTEM*
$(CADIUS) CREATEFOLDER build/"$(DISK)" "/$(VOLUME)/X/" -C >>build/log
for f in build/X/*; do \
$(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/X/$$(basename $$f)" "$$f" -C >>build/log; \
done
bin/changebootloader.sh build/"$(DISK)" build/proboothd
index: preconditions md asmfx asmprelaunch compress
#
# precompute binary data structure for mega-attract mode configuration file
#
[ -f build/index ] || (bin/buildokvs.sh < res/ATTRACT.CONF > build/ATTRACT.IDX)
#
# precompute binary data structure and substitute special characters
# in game help and other all-text pages
#
[ -f build/index ] || (bin/converthelp.sh res/HELPTEXT build/HELPTEXT)
[ -f build/index ] || (bin/converthelp.sh res/CREDITS build/CREDITS)
[ -f build/index ] || $(PARALLEL) 'bin/converthelp.sh "{}" "build/GAMEHELP/{/}"' ::: res/GAMEHELP/*
#
# create a version of GAMES.CONF without comments or blank lines
#
[ -f build/index ] || (awk '!/^$$|^#/' < res/GAMES.CONF > build/GAMES.CONF)
#
# create a list of all game filenames, without metadata or display names, sorted by game filename
#
[ -f build/index ] || (awk -F, '/,/ { print $$2 }' < build/GAMES.CONF | awk -F= '{ print $$1 }' | sort > build/GAMES.SORTED)
#
# precompute indexed files for prelaunch
# note: prelaunch must be first in TOTAL.DATA due to a hack in LoadStandardPrelaunch
# note 2: these can not be padded because they are loaded at $0106 and padding would clobber the stack
#
[ -f build/index ] || (bin/buildindexedfile.sh build/TOTAL.DATA build/PRELAUNCH.INDEXED < build/GAMES.SORTED > build/PRELAUNCH.IDX)
#
# precompute indexed files for HGR & DHGR titles
# note: these are not padded because they are all an exact block-multiple anyway
#
[ -f build/index ] || bin/padto.sh build/TOTAL.DATA
[ -f build/index ] || ((for f in res/TITLE.HGR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/TITLE.HGR build/HGR.TITLES.LOG > build/TITLE.IDX)
[ -f build/index ] || ((for f in res/TITLE.DHGR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/TITLE.DHGR build/DHGR.TITLES.LOG > build/DTITLE.IDX)
[ -f build/index ] || bin/addfile.sh res/COVER build/TOTAL.DATA > src/index/res.cover.idx.a
[ -f build/index ] || bin/addfile.sh res/TITLE build/TOTAL.DATA > src/index/res.title.idx.a
[ -f build/index ] || bin/addfile.sh res/HELP build/TOTAL.DATA > src/index/res.help.idx.a
#
# precompute indexed files for game help
# note: these can be padded because they're loaded into $800 at a time when $800..$1FFF is clobber-able
#
[ -f build/index ] || (bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/GAMEHELP < build/GAMES.SORTED > build/GAMEHELP.IDX)
#
# precompute indexed files for slideshows
# note: these can be padded because they're loaded into $800 at a time when $800..$1FFF is clobber-able
#
[ -f build/index ] || $(PARALLEL) '[ $$(echo "{/}" | cut -c-3) = "ACT" ] && bin/buildslideshow.sh -d build/GAMES.CONF < "{}" > "build/SS/{/}" || bin/buildslideshow.sh build/GAMES.CONF < "{}" > "build/SS/{/}"' ::: res/SS/*
[ -f build/index ] || ((for f in build/SS/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/SS > build/SLIDESHOW.IDX)
[ -f build/index ] || $(PARALLEL) 'bin/buildokvs.sh < "{}" > "build/ATTRACT/{/}"' ::: res/ATTRACT/*
[ -f build/index ] || ((for f in build/ATTRACT/[ABCDEFGHIJKLMNOP]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/ATTRACT > build/MINIATTRACT0.IDX)
[ -f build/index ] || ((for f in build/ATTRACT/[QRSTUVWXYZ]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/ATTRACT > build/MINIATTRACT1.IDX)
#
# precompute indexed files for graphic effects
# note: these can be padded because they're loaded into $6000 at a time when $6000..$BEFF is clobber-able
#
[ -f build/index ] || (bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/FX.INDEXED < res/FX.CONF > build/FX.IDX)
[ -f build/index ] || (bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/FX.INDEXED < res/DFX.CONF > build/DFX.IDX)
[ -f build/index ] || (bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/FX.INDEXED < res/SFX.CONF > build/SFX.IDX)
#
# precompute indexed files for HGR & DHGR action screenshots
# note: these can not be padded because they are compressed and the decompressor needs the exact size
#
[ -f build/index ] || ((for f in res/ACTION.HGR/[ABCD]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR0.IDX)
[ -f build/index ] || ((for f in res/ACTION.HGR/[EFGH]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR1.IDX)
[ -f build/index ] || ((for f in res/ACTION.HGR/[IJKL]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR2.IDX)
[ -f build/index ] || ((for f in res/ACTION.HGR/[MNOP]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR3.IDX)
[ -f build/index ] || ((for f in res/ACTION.HGR/[QRST]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR4.IDX)
[ -f build/index ] || ((for f in res/ACTION.HGR/[UVWX]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR5.IDX)
[ -f build/index ] || ((for f in res/ACTION.HGR/[YZ]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR6.IDX)
[ -f build/index ] || ((for f in res/ACTION.DHGR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.DHGR > build/DHGR.IDX)
#
# precompute indexed files for GR and DGR action screenshots
# note: these can be padded because they are not compressed
#
[ -f build/index ] || ((for f in res/ACTION.GR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a -p build/TOTAL.DATA res/ACTION.GR > build/GR.IDX)
[ -f build/index ] || ((for f in res/ACTION.DGR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a -p build/TOTAL.DATA res/ACTION.DGR > build/DGR.IDX)
#
# precompute indexed files for SHR artwork
# note: these can not be padded because they are compressed and the decompressor needs the exact size
#
[ -f build/index ] || ((for f in res/ARTWORK.SHR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ARTWORK.SHR > build/ARTWORK.IDX)
#
# create search indexes for each variation of (game-requires-joystick) X (game-requires-128K)
# in the form of OKVS data structures, plus game counts in the form of source files
#
[ -f build/index ] || $(PARALLEL) ::: \
'(grep "^00" < build/GAMES.CONF | bin/buildsearch.sh src/index/count00.a build/HGR.TITLES.LOG /dev/null > build/SEARCH00.IDX)' \
'(grep "^0" < build/GAMES.CONF | bin/buildsearch.sh src/index/count01.a build/HGR.TITLES.LOG build/DHGR.TITLES.LOG > build/SEARCH01.IDX)' \
'(grep "^.0" < build/GAMES.CONF | bin/buildsearch.sh src/index/count10.a build/HGR.TITLES.LOG /dev/null > build/SEARCH10.IDX)' \
'(bin/buildsearch.sh src/index/count11.a build/HGR.TITLES.LOG build/DHGR.TITLES.LOG < build/GAMES.CONF > build/SEARCH11.IDX)'
#
# add IDX files to the combined index file and generate
# the index records that callers use to reference them
#
[ -f build/index ] || bin/addfile.sh build/SEARCH00.IDX build/TOTAL.DATA > src/index/search00.idx.a
[ -f build/index ] || bin/addfile.sh res/CACHE00.IDX build/TOTAL.DATA > src/index/cache00.idx.a
[ -f build/index ] || bin/addfile.sh build/SEARCH01.IDX build/TOTAL.DATA > src/index/search01.idx.a
[ -f build/index ] || bin/addfile.sh res/CACHE01.IDX build/TOTAL.DATA > src/index/cache01.idx.a
[ -f build/index ] || bin/addfile.sh build/SEARCH10.IDX build/TOTAL.DATA > src/index/search10.idx.a
[ -f build/index ] || bin/addfile.sh res/CACHE10.IDX build/TOTAL.DATA > src/index/cache10.idx.a
[ -f build/index ] || bin/addfile.sh build/SEARCH11.IDX build/TOTAL.DATA > src/index/search11.idx.a
[ -f build/index ] || bin/addfile.sh res/CACHE11.IDX build/TOTAL.DATA > src/index/cache11.idx.a
[ -f build/index ] || bin/addfile.sh build/PRELAUNCH.IDX build/TOTAL.DATA > src/index/prelaunch.idx.a
[ -f build/index ] || bin/addfile.sh build/ATTRACT.IDX build/TOTAL.DATA > src/index/attract.idx.a
[ -f build/index ] || bin/addfile.sh build/FX.IDX build/TOTAL.DATA > src/index/fx.idx.a
[ -f build/index ] || bin/addfile.sh build/DFX.IDX build/TOTAL.DATA > src/index/dfx.idx.a
[ -f build/index ] || bin/addfile.sh build/SFX.IDX build/TOTAL.DATA > src/index/sfx.idx.a
[ -f build/index ] || bin/addfile.sh build/GAMEHELP.IDX build/TOTAL.DATA > src/index/gamehelp.idx.a
[ -f build/index ] || bin/addfile.sh build/SLIDESHOW.IDX build/TOTAL.DATA > src/index/slideshow.idx.a
[ -f build/index ] || bin/addfile.sh build/MINIATTRACT0.IDX build/TOTAL.DATA > src/index/miniattract0.idx.a
[ -f build/index ] || bin/addfile.sh build/MINIATTRACT1.IDX build/TOTAL.DATA > src/index/miniattract1.idx.a
[ -f build/index ] || bin/addfile.sh build/TITLE.IDX build/TOTAL.DATA > src/index/title.idx.a
[ -f build/index ] || bin/addfile.sh build/DTITLE.IDX build/TOTAL.DATA > src/index/dtitle.idx.a
[ -f build/index ] || bin/addfile.sh build/HGR0.IDX build/TOTAL.DATA > src/index/hgr0.idx.a
[ -f build/index ] || bin/addfile.sh build/HGR1.IDX build/TOTAL.DATA > src/index/hgr1.idx.a
[ -f build/index ] || bin/addfile.sh build/HGR2.IDX build/TOTAL.DATA > src/index/hgr2.idx.a
[ -f build/index ] || bin/addfile.sh build/HGR3.IDX build/TOTAL.DATA > src/index/hgr3.idx.a
[ -f build/index ] || bin/addfile.sh build/HGR4.IDX build/TOTAL.DATA > src/index/hgr4.idx.a
[ -f build/index ] || bin/addfile.sh build/HGR5.IDX build/TOTAL.DATA > src/index/hgr5.idx.a
[ -f build/index ] || bin/addfile.sh build/HGR6.IDX build/TOTAL.DATA > src/index/hgr6.idx.a
[ -f build/index ] || bin/addfile.sh build/DHGR.IDX build/TOTAL.DATA > src/index/dhgr.idx.a
[ -f build/index ] || bin/addfile.sh build/GR.IDX build/TOTAL.DATA > src/index/gr.idx.a
[ -f build/index ] || bin/addfile.sh build/DGR.IDX build/TOTAL.DATA > src/index/dgr.idx.a
[ -f build/index ] || bin/addfile.sh build/ARTWORK.IDX build/TOTAL.DATA > src/index/artwork.idx.a
#
# add additional miscellaneous files
#
[ -f build/index ] || bin/addfile.sh build/COVERFADE build/TOTAL.DATA > src/index/coverfade.idx.a
[ -f build/index ] || bin/addfile.sh build/GR.FIZZLE build/TOTAL.DATA > src/index/gr.fizzle.idx.a
[ -f build/index ] || bin/addfile.sh build/DGR.FIZZLE build/TOTAL.DATA > src/index/dgr.fizzle.idx.a
[ -f build/index ] || bin/addfile.sh build/HELPTEXT build/TOTAL.DATA > src/index/helptext.idx.a
[ -f build/index ] || bin/addfile.sh build/CREDITS build/TOTAL.DATA > src/index/credits.idx.a
[ -f build/index ] || bin/addfile.sh res/DECRUNCH build/TOTAL.DATA > src/index/decrunch.idx.a
[ -f build/index ] || bin/addfile.sh res/JOYSTICK build/TOTAL.DATA > src/index/joystick.idx.a
touch build/index
asmlauncher: md
$(ACME) -DBUILDNUMBER=`git rev-list --count HEAD` src/4cade.a 2>build/relbase.log
$(ACME) -r build/4cade.lst -DBUILDNUMBER=`git rev-list --count HEAD` -DRELBASE=`cat build/relbase.log | grep "RELBASE =" | cut -d"=" -f2 | cut -d"(" -f2 | cut -d")" -f1` src/4cade.a
asmfx: preconditions md
$(PARALLEL) 'if grep -q "^!to" "{}"; then $(ACME) "{}"; fi' ::: src/fx/*.a
asmprelaunch: preconditions md
$(PARALLEL) 'if grep -q "^!to" "{}"; then $(ACME) "{}"; fi' ::: src/prelaunch/*.a
asmproboot: md
$(ACME) -r build/proboothd.lst src/proboothd/proboothd.a
compress: preconditions md
$(PARALLEL) '[ -f "res/ACTION.HGR/{/}" ] || ${EXOMIZER} "{}"@0x4000 -o "res/ACTION.HGR/{/}"' ::: res/ACTION.HGR.UNCOMPRESSED/*
$(PARALLEL) '[ -f "res/ACTION.DHGR/{/}" ] || ${EXOMIZER} "{}"@0x4000 -o "res/ACTION.DHGR/{/}"' ::: res/ACTION.DHGR.UNCOMPRESSED/*
$(PARALLEL) '[ -f "res/ARTWORK.SHR/{/}" ] || ${EXOMIZER} "{}"@0x2000 -o "res/ARTWORK.SHR/{/}"' ::: res/ARTWORK.SHR.UNCOMPRESSED/*
$(PARALLEL) '[ -f "res/TITLE.HGR/{/}" ] || bin/packhgrfile.py "{}" "res/TITLE.HGR/{/}"' ::: res/TITLE.HGR.UNPACKED/*
#
# |attract| must be called separately because it is slow and
# only needs to be run when a new game or demo is added.
# It create files in the repository which can then be checked in.
#
attract: compress
bin/check-attract-mode.sh
bin/generate-mini-attract-mode.sh
cache: preconditions md
$(PARALLEL) ::: \
'awk -F= '"'"'/^00/ { print $$2 }'"'"' < res/GAMES.CONF | bin/buildcache.py > build/cache00.a' \
'awk -F= '"'"'/^0/ { print $$2 }'"'"' < res/GAMES.CONF | bin/buildcache.py > build/cache01.a' \
'awk -F= '"'"'/^.0/ { print $$2 }'"'"' < res/GAMES.CONF | bin/buildcache.py > build/cache10.a' \
'awk -F= '"'"'!/^$$|^#|^\[/ { print $$2 }'"'"' < res/GAMES.CONF | bin/buildcache.py > build/cache11.a'
$(PARALLEL) ::: \
'$(ACME) -o res/CACHE00.IDX build/cache00.a' \
'$(ACME) -o res/CACHE01.IDX build/cache01.a' \
'$(ACME) -o res/CACHE10.IDX build/cache10.a' \
'$(ACME) -o res/CACHE11.IDX build/cache11.a'
mount: dsk
osascript bin/V2Make.scpt "`pwd`" bin/4cade.vii build/"$(DISK)"
md:
mkdir -p build/X build/FX.INDEXED build/FX build/PRELAUNCH.INDEXED build/PRELAUNCH build/ATTRACT build/SS build/GAMEHELP
touch build/log
clean:
rm -rf build/ || rm -rf build
preconditions:
@$(ACME) --version | grep -q "ACME, release" || (echo "ACME is not installed" && exit 1)
@$(CADIUS) | grep -q "cadius v" || (echo "Cadius is not installed" && exit 1)
@$(PARALLEL) --version | grep -q "GNU" || (echo "GNU Parallel is not installed" && exit 1)
@$(PYTHON) --version | grep -q "Python 3" || (echo "Python 3 is not installed" && exit 1)
all: clean dsk mount
al: all

5
bin/addfile.js Normal file
View File

@ -0,0 +1,5 @@
a=new ActiveXObject("scripting.filesystemobject")
offset=a.getfile("BUILD\\TOTAL.DATA").size
new ActiveXObject("wscript.shell").run('cmd /c copy /b /y BUILD\\TOTAL.DATA + ' + WScript.Arguments(0) + ' BUILD\\TOTAL.DATA', 0, 1)
size=a.getfile(WScript.Arguments(0)).size
a.createtextfile(WScript.Arguments(1)).write(";\r\n; Index record for " + WScript.Arguments(0).replace(/\\/, "/") + "\r\n;\r\n; This file is automatically generated\r\n;\r\n !byte 0\r\n !be24 " + offset + "\r\n !le16 " + " ".substr(0, 8 - size.toString().length) + size + "\r\n")

19
bin/addfile.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# parameters
# 1 - input file
# 2 - output filename for data file
# stdout - source code of index record
touch "$2"
size=$(wc -c < "$1")
offset=$(wc -c < "$2")
cat "$1" >> "$2"
echo ";"
echo "; Index record for $1"
echo ";"
echo "; This file is automatically generated"
echo ";"
echo " !byte 0"
echo " !be24 $offset"
echo " !le16 $size"

60
bin/buildcache.js Normal file
View File

@ -0,0 +1,60 @@
a = new ActiveXObject("scripting.filesystemobject")
b = a.opentextfile("res\\GAMES.CONF")
f00 = a.createtextfile("build\\filter00.txt")
f01 = a.createtextfile("build\\filter01.txt")
f10 = a.createtextfile("build\\filter10.txt")
f11 = a.createtextfile("build\\filter11.txt")
while (!b.atendofstream)
{
c = b.readline()
d = c.indexOf("#")
if (d >= 0)
{
c = c.substr(0, d)
}
if (c.indexOf("[eof]") >= 0)
{
break
}
if (c.length == 0)
{
continue
}
if (c.substr(0, 2) == "00")
{
f00.writeline(c.substr(c.indexOf("=") + 1))
}
if (c.substr(0, 1) == "0")
{
f01.writeline(c.substr(c.indexOf("=") + 1))
}
if (c.substr(1, 1) == "0")
{
f10.writeline(c.substr(c.indexOf("=") + 1))
}
f11.writeline(c.substr(c.indexOf("=") + 1))
}
f11.close()
f10.close()
f01.close()
f00.close()
x = new ActiveXObject("wscript.shell")
x.run('cmd /c %python% bin\\buildcache.py < build\\filter00.txt > build\\cache00.a', 0, 1)
x.run('cmd /c %python% bin\\buildcache.py < build\\filter01.txt > build\\cache01.a', 0, 1)
x.run('cmd /c %python% bin\\buildcache.py < build\\filter10.txt > build\\cache10.a', 0, 1)
x.run('cmd /c %python% bin\\buildcache.py < build\\filter11.txt > build\\cache11.a', 0, 1)
x.run('cmd /c %acme% -o res\\CACHE00.IDX build\\cache00.a', 0, 1)
x.run('cmd /c %acme% -o res\\CACHE01.IDX build\\cache01.a', 0, 1)
x.run('cmd /c %acme% -o res\\CACHE10.IDX build\\cache10.a', 0, 1)
x.run('cmd /c %acme% -o res\\CACHE11.IDX build\\cache11.a', 0, 1)

126
bin/buildcache.py Executable file
View File

@ -0,0 +1,126 @@
#!/usr/bin/env python3
from collections import OrderedDict
from pprint import pprint
from string import ascii_lowercase
from sys import stdin
def score(inputbuffer, displayname):
if len(inputbuffer) > len(displayname):
return 0, False
likely = True
startat = 0
score = 0
for c in inputbuffer:
x = 10
y = displayname[startat:].find(c)
if y < 0:
return 0, False
if y == 0:
x = 80
elif (startat > 0) and (displayname[startat+y-1] == " "):
x = 90
else:
likely = False
score += x
startat += y + 1
score = int(score/len(displayname) + (score/len(inputbuffer)) + 0.99)/2
if (inputbuffer[0] == displayname[0]) and (score < 85):
score += 15
return score, likely
def best(keys, games):
gameindex = 0
bestscore = -1
bestindex = -1
bestlikely = False
for game in games:
gamescore, likely = score(keys, game)
if (gamescore > bestscore):
bestscore = gamescore
bestindex = gameindex
bestlikely = likely
gameindex += 1
if not bestlikely:
return 0
return bestindex
def main():
games = [line.strip().lower() for line in stdin]
cache = OrderedDict()
for a in ascii_lowercase:
index1 = best(a, games)
if not index1: continue
cache[a] = OrderedDict()
cache[a][" "] = index1
for b in ascii_lowercase:
index2 = best(a+b, games)
if not index2: continue
cache[a][b] = OrderedDict()
if index2 != index1:
cache[a][b][" "] = index2
for c in ascii_lowercase:
index3 = best(a+b+c, games)
if not index3: continue
cache[a][b][c] = OrderedDict()
if index3 != index2:
cache[a][b][c][" "] = index3
for d in ascii_lowercase:
index4 = best(a+b+c+d, games)
if not index4: continue
if index4 != index3:
cache[a][b][c][d] = index4
if not cache[a][b][c]:
del cache[a][b][c]
if not cache[a][b]:
del cache[a][b]
if not cache[a]:
del cache[a]
print('*=$A000')
for a in cache:
print(f' !text "{a}"')
if type(cache[a]) == int:
print(f' !word {cache[a]}')
else:
print(f' !word _{a}')
print(' !byte 0')
for a in cache:
if type(cache[a]) == int: continue
print(f'_{a}')
for b in cache[a]:
print(f' !text "{b}"')
if type(cache[a][b]) == int:
print(f' !word {cache[a][b]}')
else:
print(f' !word _{a}{b}')
print(' !byte 0')
for a in cache:
if type(cache[a]) == int: continue
for b in cache[a]:
if type(cache[a][b]) == int: continue
print(f'_{a}{b}')
for c in cache[a][b]:
print(f' !text "{c}"')
if type(cache[a][b][c]) == int:
print(f' !word {cache[a][b][c]}')
else:
print(f' !word _{a}{b}{c}')
print(' !byte 0')
for a in cache:
if type(cache[a]) == int: continue
for b in cache[a]:
if type(cache[a][b]) == int: continue
for c in cache[a][b]:
if type(cache[a][b][c]) == int: continue
print(f'_{a}{b}{c}')
for d in cache[a][b][c]:
print(f' !text "{d}"')
print(f' !word {cache[a][b][c][d]}')
print(' !byte 0')
if __name__ == '__main__':
main()

28
bin/builddisplaynames.js Normal file
View File

@ -0,0 +1,28 @@
a = new ActiveXObject("scripting.filesystemobject")
b = a.opentextfile("build\\GAMES.CONF")
c = a.createtextfile("build\\DISPLAY.CONF")
while (!b.atendofstream)
{
d = b.readline()
if (d.indexOf("[eof]") >= 0)
{
break
}
if (d.indexOf("=") == -1)
{
e = d.indexOf(",") + 1
f = d.substr(e).split(".")
for (g = 0; g < f.length; g++)
{
f[g] = f[g].charAt(0) + f[g].substr(1).toLowerCase()
}
d += "=" + f.join(" ").replace(" Ii", " II")
}
c.writeline(d)
}

View File

@ -9,4 +9,4 @@ for (b = new Enumerator(a.GetFolder(WScript.Arguments(0)).files); !b.atEnd(); b.
}
}
fileinfo += "\r\n" + "_FileInformation.txt=Type(" + WScript.Arguments(1) + "),AuxType(" + WScript.Arguments(2) + "),Access(C3)\r\n"
a.createtextfile(WScript.Arguments(0)+"\\_FILEINFORMATION.TXT", 1).write(fileinfo)
a.createtextfile(WScript.Arguments(0)+"\\_FileInformation.txt", 1).write(fileinfo)

53
bin/buildfx.js Normal file
View File

@ -0,0 +1,53 @@
a = new ActiveXObject("scripting.filesystemobject")
x = new ActiveXObject("wscript.shell")
fx_off = a.fileexists(WScript.Arguments(2)) ? a.getFile(WScript.Arguments(2)).size : 0
x.run('cmd /c bin\\buildfxful.bat ' + WScript.Arguments(0) + ' ' + WScript.Arguments(2) + ' ' + WScript.Arguments(3), 0, 1)
b = a.opentextfile(WScript.Arguments(0))
entries = []
while (!b.atendofstream)
{
c = b.readline()
d = c.indexOf("#")
if (d >= 0)
{
c = c.substr(0, d)
}
d = c.indexOf("=")
if (d >= 0)
{
c = c.substr(0, d)
}
if (c.indexOf("[eof]") >= 0)
{
break
}
if (c.length > 0)
{
entries.push(c)
}
}
groups = "*=0\n" + "!le16 " + entries.length.toString() + ", 0\n"
for (i = 0; i < entries.length; i++)
{
groups += "!byte " + (1 + 1 + entries[i].length + 5).toString() + "\n" + "!byte " + entries[i].length.toString() + "\n" + "!text \"" + entries[i] + "\"\n" + "!be24 " + fx_off.toString() + "\n"
size = a.getfile(WScript.Arguments(3) + "\\" + entries[i]).size
// if offset+size does not cross a block boundary, use the size
// otherwise adjust size until it ends at the next block boundary to avoid a partial copy on the last block
groups += "!le16 " + ((Math.floor(fx_off / 512) == Math.floor((fx_off + size) / 512)) ? size : (((fx_off + size + 511) & -512) - fx_off)).toString() + "\n"
fx_off += size
}
f = a.createtextfile("build\\fx.tmp")
f.write(groups)
f.close()
x.run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\fx.tmp', 0, 1)

14
bin/buildfxful.bat Normal file
View File

@ -0,0 +1,14 @@
@echo off
setlocal enabledelayedexpansion
for /f "tokens=*" %%a in (%1) do (
set f=0
call :x %%a
if !f!==2 goto:eof
if !f!==0 1>nul copy /b /y %2+%3\%%a %2
)
goto:eof
:x
set a=%1
if not x%a:#=%==x%a% set/a f=1
if not x%a:[=%==x%a% set/a f=2

88
bin/buildindexedfile.sh Executable file
View File

@ -0,0 +1,88 @@
#!/bin/bash
# flags
# -a append to data file (default off = truncate)
# -p pad sizes within data file to next block size (default off)
# parameters
# stdin - input containing list of effects (probably FX.CONF or DFX.CONF)
# stdout - binary OKVS data structure
# 1 - output filename for data file
# 2 - input directory of files to merge into data file
# 3 - (optional) output filename for log of key,offset,size
pad=false
append=false
standardoffset=0
standardsize=0
while getopts ":ap" opt; do
case $opt in
a) append=true
;;
p) pad=true
;;
esac
done
shift $((OPTIND-1))
if [ "$append" = false ]; then
rm -f "$1"
fi
touch "$1"
if [ "${#3}" -ne "0" ]; then
rm -f "$3"
touch "$3"
fi
# if there is a file called "STANDARD" in the input directory, add it now
# because we will reuse it for any files that don't exist
if [ -f "$2"/STANDARD ]; then
standardoffset=$(wc -c < "$1")
standardsize=$(wc -c < "$2/STANDARD")
cat "$2"/STANDARD >> "$1"
fi
# make temp file with list of lines that contain keys
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
echo "!byte ${#key}+7" # OKVS record length
echo "!byte ${#key}" # OKVS key length
echo "!text \"$key\"" # OKVS key
if [ ! -e "$2/$key" ]; then # if file does not exist, use standard offset and size
offset="$standardoffset"
size="$standardsize"
else # otherwise calculate offset and size from file and options
offset=$(wc -c < "$1")
size=$(wc -c < "$2/$key")
if [ "$pad" = true ]; then
# If offset+size does not cross a block boundary, use file's true size.
# Otherwise, round up size to the next block boundary.
# This padding does not get added to the file; it is just an
# optimization to avoid a partial copy on the last block read.
if [ $(($offset / 512)) -ne $((($offset + $size) / 512)) ]; then
size=$(((($offset + $size + 511) & -512) - $offset))
fi
fi
cat "$2/$key" >> "$1" # append this file to the end of the merged data file
fi
echo "!be24 $offset"
echo "!le16 $size"
[ "${#3}" -ne "0" ] && echo "$key,$offset,$size" >> "$3"
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"

46
bin/buildokvs.js Normal file
View File

@ -0,0 +1,46 @@
a = new ActiveXObject("scripting.filesystemobject")
if (!a.fileexists(WScript.Arguments(1)) || a.getfile(WScript.Arguments(1)).datelastmodified < a.getFile(WScript.Arguments(0)).datelastmodified)
{
b = a.opentextfile(WScript.Arguments(0))
entries = []
while (!b.atendofstream)
{
c = b.readline()
d = c.indexOf("#")
if (d >= 0)
{
c = c.substr(0, d)
}
if (c.indexOf("[eof]") >= 0)
{
break
}
if (c.length > 0)
{
entries.push(c)
}
}
source = a.createtextfile("build\\okvs.tmp")
source.writeline("*=0")
source.writeline("!le16 " + entries.length + ", 0")
for (i = 0; i < entries.length; i++)
{
val = entries[i].indexOf("=")
source.writeline("!byte " + (entries[i].length - ((val >= 0) ? 1 : 0) + 3).toString())
source.writeline("!byte " + ((val >= 0) ? val : entries[i].length).toString())
source.writeline("!text \"" + ((val >= 0) ? entries[i].substr(0, val) : entries[i]) + "\"")
source.writeline("!byte " + ((val >= 0) ? (entries[i].length - (val + 1)) : 0).toString())
source.writeline("!text \"" + ((val >= 0) ? (entries[i].substr(val + 1)) : "") + "\"")
}
source.close()
new ActiveXObject("wscript.shell").run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\okvs.tmp', 0, 1)
}

27
bin/buildokvs.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/bash
# 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
echo "!byte ${#key}+${#value}+3" # 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
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"

43
bin/buildpre.js Normal file
View File

@ -0,0 +1,43 @@
a = new ActiveXObject("scripting.filesystemobject")
b = a.opentextfile("build\\GAMES.SORTED")
entries = []
while (!b.atendofstream)
{
entries.push(b.readline())
}
osize = a.getfile(WScript.Arguments(0) + "\\STANDARD").size
pre_off = a.getfile(WScript.Arguments(2)).size + osize
groups = "*=0\n" + "!le16 " + entries.length + ", 0\n"
for (i = 0; i < entries.length; i++)
{
c = a.getfile(WScript.Arguments(2)).size
size = osize
if (a.fileexists(WScript.Arguments(0) + "\\" + entries[i]))
{
c = pre_off
size = a.getfile(WScript.Arguments(0) + "\\" + entries[i]).size
pre_off += size
}
if (WScript.Arguments.length == 4)
{
// if offset+size does not cross a block boundary, use the size
// otherwise adjust size until it ends at the next block boundary to avoid a partial copy on the last block
size = ((Math.floor(c / 512) == Math.floor((c + size) / 512)) ? size : (((c + size + 511) & -512) - c))
}
groups += "!byte " + (1 + 1 + entries[i].length + 5) + "\n" + "!byte " + entries[i].length + "\n" + "!text \"" + entries[i] + "\"\n" + "!be24 " + c + "\n" + "!le16 " + size + "\n"
}
f = a.createtextfile("build\\pre.tmp")
f.write(groups)
f.close()
x = new ActiveXObject("wscript.shell")
x.run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\pre.tmp', 0, 1)
x.run('cmd /c bin\\buildpreall.bat ' + WScript.Arguments(0) + ' ' + WScript.Arguments(2) + ' ' + WScript.Arguments(0) + '\\STANDARD', 0, 1)

3
bin/buildpreall.bat Normal file
View File

@ -0,0 +1,3 @@
@echo off
1>nul copy /y /b %2+%3 %2
for /f "tokens=*" %%a in (build\GAMES.SORTED) do 1>nul copy /b /y %2+%1\%%a %2

90
bin/buildsearch.js Normal file
View File

@ -0,0 +1,90 @@
a = new ActiveXObject("scripting.filesystemobject")
x = new ActiveXObject("wscript.shell")
b = x.exec('findstr /b \"' + WScript.Arguments(0) + '\" build\\DISPLAY.CONF')
entries = []
while (!b.stdout.atendofstream)
{
c = b.stdout.readline()
d = c.indexOf("#")
if (d >= 0)
{
c = c.substr(0, d)
}
if (c.indexOf("[eof]") >= 0)
{
break
}
if (c.length > 0)
{
entries.push(c)
}
}
a.createtextfile(WScript.Arguments(1)).write(";\r\n; Game count\r\n;\r\n; This file is automatically generated\r\n;\r\n" + "!word " + " ".substr(0, 8 - entries.length.toString().length) + entries.length + "\r\n")
source = a.createtextfile("build\\search.a")
source.writeline("*=$6000")
source.writeline("!le16 " + entries.length)
source.writeline("!word KeyLookup")
hgrlog = a.opentextfile("build\\HGR.TITLES.LOG").readall().replace(/\r\n/, "\n")
dhgrlog = a.opentextfile("build\\DHGR.TITLES.LOG").readall().replace(/\r\n/, "\n")
for (i = 0; i < entries.length; i++)
{
bits = entries[i].indexOf(",")
dhgr = entries[i].substr(bits - 2, 1)
if (WScript.Arguments(1).substr(WScript.Arguments(1).length - 3, 1) == "0")
{
dhgr = "0"
}
cheat = entries[i].substr(bits - 1, 1)
eq = entries[i].indexOf("=")
key = ((eq >= 0) ? entries[i].substr(bits + 1, eq - bits - 1) : entries[i])
value = ((eq >= 0) ? entries[i].substr(eq + 1) : "")
source.writeline("!byte " + (key.length + value.length + 10).toString())
source.writeline("Key" + (i + 1).toString())
source.writeline("!byte " + key.length)
source.writeline("!text \"" + key + "\"")
source.writeline("!byte " + value.length)
source.writeline("!text \"" + value + "\"")
source.writeline("!byte 1")
source.writeline("!byte " + ((dhgr * 128) + Number(cheat)))
if (dhgr != 0)
{
dname = dhgrlog.indexOf("\n" + key + ",") + key.length + 2
dpos = dhgrlog.substr(dname).indexOf(",")
dsize = dhgrlog.substr(dname + dpos + 1).indexOf("\n")
dsize = dhgrlog.substr(dname + dpos + 1, dsize)
dpos = dhgrlog.substr(dname, dpos)
}
else
{
dname = hgrlog.indexOf("\n" + key + ",") + key.length + 2
dpos = hgrlog.substr(dname).indexOf(",")
dsize = hgrlog.substr(dname + dpos + 1).indexOf("\n")
dsize = hgrlog.substr(dname + dpos + 1, dsize)
dpos = hgrlog.substr(dname, dpos)
}
source.writeline("!be24 " + dpos)
source.writeline("!le16 " + dsize)
}
source.writeline("KeyLookup")
for (i = 0; i < entries.length; i++)
{
source.writeline("!word Key" + (i + 1))
}
source.close()
new ActiveXObject("wscript.shell").run('cmd /c %acme% -o ' + WScript.Arguments(2) + ' build\\search.a', 0, 1)

76
bin/buildsearch.sh Executable file
View File

@ -0,0 +1,76 @@
#!/bin/bash
# parameters
# stdin - input containing list of game metadata, filename, display name (e.g. GAMES.CONF or some subset of it)
# stdout - binary OKVS data structure
# 1 - output filename for game count in assembler code format
# 2 - input filename of HGR titles, offsets, and sizes
# 3 - input filename of DHGR titles, offsets, and sizes
# make temp file with just the key/value pairs (strip blank lines, comments, eof marker)
records=$(mktemp)
tr -d "\r" | awk '!/^$|^#|^\[/' > "$records"
# read logs of offsets & sizes for HGR and DHGR titles
# that were generated by an earlier script
hgrlog=$(< "$2")
dhgrlog=$(< "$3")
# generate source file with game count
(echo ";"
echo "; Game count"
echo ";"
echo "; This file is automatically generated"
echo ";"
echo "!word $(wc -l < "$records")") > "$1"
# make temp assembly source file that represents the binary OKVS data structure
source=$(mktemp)
(echo '*=$6000'
echo "!le16 $(wc -l <"$records")" # OKVS header
echo "!word KeyLookup"
count=0
while IFS="=" read -r key value; do
count=$((count+1))
if [ -z "$dhgrlog" ]; then
dhgr="0"
else
dhgr=$(echo "$key" | cut -c3) # 'has DHGR title screen' flag (0 or 1)
fi
cheat=$(echo "$key" | cut -c4) # 'cheat category' (0..5)
key=$(echo "$key" | cut -d"," -f2)
if [ "$dhgr" -eq "0" ]; then
offset=$hgrlog
size=$hgrlog
else
offset=$dhgrlog
size=$dhgrlog
fi
offset=$(echo "$offset" | awk -F, '/^'"$key"',/ { print $2 }')
size=$(echo "$size" | awk -F, '/^'"$key"',/ { print $3 }')
echo "!byte ${#key}+${#value}+10" # OKVS record length
echo "Key${count}"
echo "!byte ${#key}" # OKVS key length
echo "!text \"$key\"" # OKVS key (filename)
echo "!byte ${#value}" # OKVS value length
echo "!text \"$value\"" # OKVS value (display name)
echo "!byte 1"
echo "!byte $((dhgr*128))+$cheat"
echo "!be24 $offset"
echo "!le16 $size"
done < "$records"
echo "KeyLookup"
for i in $(seq $count); do
echo "!word Key$i"
done
) > "$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"

57
bin/buildslideshow.js Normal file
View File

@ -0,0 +1,57 @@
a = new ActiveXObject("scripting.filesystemobject")
if (!a.fileexists(WScript.Arguments(1)) || a.getfile(WScript.Arguments(1)).datelastmodified < a.getFile(WScript.Arguments(0)).datelastmodified)
{
b = a.opentextfile(WScript.Arguments(0))
entries = []
while (!b.atendofstream)
{
c = b.readline()
d = c.indexOf("#")
if (d >= 0)
{
c = c.substr(0, d)
}
if (c.indexOf("[eof]") >= 0)
{
break
}
if (c.length > 0)
{
entries.push(c)
}
}
source = a.createtextfile("build\\okvs.tmp")
source.writeline("*=0")
source.writeline("!le16 " + entries.length + ", 0")
q = a.opentextfile("build\\DISPLAY.CONF").readall().replace(/\r\n/g, "\n")
for (i = 0; i < entries.length; i++)
{
val = entries[i].indexOf("=")
name = ((val >= 0) ? entries[i].substr(val + 1) : entries[i])
bits = q.indexOf("," + name + "=") + 1
name = q.substr(bits + name.length + 1)
name = name.substr(0, name.indexOf("\n"))
needsjoystick = q.substr(bits - 5, 1)
needs128k = q.substr(bits - 4, 1)
displayname = ((WScript.Arguments.length == 3) ? name : "")
source.writeline("!byte " + (entries[i].length - ((val >= 0) ? 1 : 0) + displayname.length + 5))
source.writeline("!byte " + ((val >= 0) ? val : entries[i].length))
source.writeline("!text \"" + ((val >= 0) ? entries[i].substr(0, val) : entries[i]) + "\"")
source.writeline("!byte " + ((val >= 0) ? (entries[i].length - (val + 1)) : 0))
source.writeline("!text \"" + ((val >= 0) ? (entries[i].substr(val + 1)) : "") + "\"")
source.writeline("!byte " + displayname.length)
source.writeline("!text \"" + displayname + "\"")
source.writeline("!byte " + ((needsjoystick * 128) + (Number(needs128k) * 64)))
}
source.close()
new ActiveXObject("wscript.shell").run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\okvs.tmp', 0, 1)
}

58
bin/buildslideshow.sh Executable file
View File

@ -0,0 +1,58 @@
#!/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"

73
bin/buildss.js Normal file
View File

@ -0,0 +1,73 @@
a = new ActiveXObject("scripting.filesystemobject")
entries = []
p = WScript.Arguments(0)
if (p.charAt(p.length - 1) == "*")
{
b = a.opentextfile(p.substr(0, p.length - 1))
while (!b.atendofstream)
{
c = b.readline()
entries.push(c.substr(c.lastIndexOf("\\") + 1))
}
p = c.substr(0, c.lastIndexOf("\\"))
}
else
{
for (b = new Enumerator(a.GetFolder(p).files); !b.atEnd(); b.moveNext())
{
entries.push(b.item().name)
}
}
entries.sort()
f = a.createtextfile("build\\GAMES.SORTED")
f.write(entries.toString().replace(/,/g, "\n"))
f.close()
ss_off = a.fileexists(WScript.Arguments(3)) ? a.getFile(WScript.Arguments(3)).size : 0
groups = "*=0\n" + "!le16 " + entries.length + ", 0\n"
q = 0
if (WScript.Arguments(2) != "nul")
{
q = a.createtextfile(WScript.Arguments(2))
q.writeline()
}
for (i = 0; i < entries.length; i++)
{
size = a.getfile(p + "\\" + entries[i]).size
c = ss_off
ss_off += size
if (WScript.Arguments.length == 6)
{
// if offset+size does not cross a block boundary, use the size
// otherwise adjust size until it ends at the next block boundary to avoid a partial copy on the last block
size = ((Math.floor(c / 512) == Math.floor((c + size) / 512)) ? size : (((c + size + 511) & -512) - c))
}
groups += "!byte " + (entries[i].length + 7) + "\n" + "!byte " + entries[i].length + "\n" + "!text \"" + entries[i] + "\"\n" + "!be24 " + c + "\n" + "!le16 " + size + "\n"
if (typeof(q) == "object")
{
q.writeline(entries[i] + "," + c + "," + size)
}
}
if (typeof(q) == "object")
{
q.close()
}
f = a.createtextfile("build\\ss.tmp")
f.write(groups)
f.close()
x = new ActiveXObject("wscript.shell")
x.run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\ss.tmp', 0, 1)
x.run('cmd /c bin\\buildpreall.bat ' + p + ' ' + WScript.Arguments(3) + ' ' + WScript.Arguments(4), 0, 1)

View File

@ -1,3 +1,3 @@
#!/bin/sh
dd of="$1" bs=1 count=512 conv=notrunc < "$2"
dd of="$1" bs=1 count=512 conv=notrunc < "$2" 2>/dev/null

View File

@ -7,23 +7,11 @@ fatal_error() {
exit 1
}
check_title_slideshow() {
check_slideshow() {
[ -f "$1" ] ||
fatal_error "Can't find HGR title slideshow" "$1"
cat "$1" |
grep -v "^#" |
grep -v "^\[" |
grep -v "^$" |
while read ssline; do
[ -f "$2"/"$ssline" ] ||
fatal_error "Can't find title screenshot" "$ssline"
done
}
check_action_slideshow() {
[ -f "$1" ] ||
fatal_error "Can't find HGR action slideshow" "$1"
fatal_error "Can't find slideshow" "$1"
cat "$1" |
tr -d "\r" |
grep -v "^#" |
grep -v "^\[" |
grep -v "^$" |
@ -33,20 +21,50 @@ check_action_slideshow() {
gamename=$filename
fi
[ -f "$2"/"$filename" ] ||
fatal_error "Can't find action screenshot" "$filename"
fatal_error "Can't find screenshot" "$filename"
grep "^$gamename$" /tmp/games >/dev/null ||
fatal_error "Action screenshot links to non-existent game" "$gamename"
fatal_error "Screenshot links to non-existent game" "$gamename"
done
}
# fatal error if an attract mode module is listed more than once
dupes=$(cat res/ATTRACT.CONF |
tr -d "\r" |
grep -v "^#" |
grep -v "^$" |
sort |
uniq -d)
if [[ $dupes ]]; then
fatal_error "Duplicate ATTRACT.CONF module:" "$dupes"
fi
cat res/GAMES.CONF |
tr -d "\r" |
grep -v "^#" |
grep -v "^\[" |
grep -v "^$" |
cut -d"," -f2 |
cut -d"=" -f1 > /tmp/games
# warn about unused self-running demos
cat res/DEMO/_FileInformation.txt |
tr -d "\r" |
grep "Type(06)" |
grep -v "SPCARTOON" |
cut -d"=" -f1 |
while read f; do
grep "$f=0" res/ATTRACT.CONF >/dev/null || echo "unused demo: $f";
done
# warn about unused slideshows
cd res/SS
for f in *.CONF; do
grep "$f" ../ATTRACT.CONF >/dev/null || echo "unused slideshow: $f";
done
cd ../..
cat res/ATTRACT.CONF |
tr -d "\r" |
grep "=" |
grep -v "^#" |
while read line; do
@ -57,17 +75,19 @@ cat res/ATTRACT.CONF |
[ "${module_name%???}" = "SPCARTOON" ] ||
fatal_error "Can't find demo" $module_name
elif [ "$module_type" = "1" ]; then
check_title_slideshow res/SS/"$module_name" res/TITLE.HGR/
check_slideshow res/SS/"$module_name" res/TITLE.HGR/
elif [ "$module_type" = "2" ]; then
check_action_slideshow res/SS/"$module_name" res/ACTION.HGR/
check_slideshow res/SS/"$module_name" res/ACTION.HGR/
elif [ "$module_type" = "3" ]; then
check_title_slideshow res/SS/"$module_name" res/TITLE.DHGR/
check_slideshow res/SS/"$module_name" res/TITLE.DHGR/
elif [ "$module_type" = "4" ]; then
check_action_slideshow res/SS/"$module_name" res/ACTION.DHGR/
check_slideshow res/SS/"$module_name" res/ACTION.DHGR/
elif [ "$module_type" = "5" ]; then
check_title_slideshow res/SS/"$module_name" res/ARTWORK.SHR/
check_slideshow res/SS/"$module_name" res/ARTWORK.SHR/
elif [ "$module_type" = "6" ]; then
check_action_slideshow res/SS/"$module_name" res/ACTION.GR/
check_slideshow res/SS/"$module_name" res/ACTION.GR/
elif [ "$module_type" = "7" ]; then
check_slideshow res/SS/"$module_name" res/ACTION.DGR/
else
fatal_error "Unknown module type" $module_type
fi

2
bin/checkdate.js Normal file
View File

@ -0,0 +1,2 @@
a = new ActiveXObject("scripting.filesystemobject")
WScript.quit(Math.abs(!a.fileexists(WScript.Arguments(0)) || a.getfile(WScript.Arguments(0)).datelastmodified < a.getFile(WScript.Arguments(1)).datelastmodified))

63
bin/converthelp.js Normal file
View File

@ -0,0 +1,63 @@
a = new ActiveXObject("scripting.filesystemobject")
if (!a.fileexists(WScript.Arguments(1)) || a.getfile(WScript.Arguments(1)).datelastmodified < a.getFile(WScript.Arguments(0)).datelastmodified)
{
z = a.opentextfile(WScript.Arguments(0))
d = a.createtextfile(WScript.Arguments(1))
String.prototype.replaceWith = function(q)
{
return this.substr(0, c) + String.fromCharCode(q) + this.substr(c + 1)
}
while (!z.atendofstream)
{
b = z.readline()
c = b.search(/\[eof\]/)
if (c > -1)
{
break
}
c = b.search(/\r\n/)
if (c > -1)
{
b = b.substr(0, c)
}
for (c = 0; c < b.length; c++)
{
if (b.charAt(c) == '*')
{
b = b.replaceWith(16)
}
else if (b.charAt(c) == '~')
{
b = b.replaceWith(17)
}
else if (b.charAt(c) == '<')
{
b = b.replaceWith(8)
}
else if (b.charAt(c) == '>')
{
b = b.replaceWith(21)
}
else if (b.charAt(c) == '$')
{
b = b.replaceWith(14)
}
else if (b.charAt(c) == '%')
{
b = b.replaceWith(15)
}
}
d.write(String.fromCharCode(b.length) + b)
}
d.write(String.fromCharCode(255))
}

4
bin/converthelp.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
tr "\*\~\<\>\$\%" "\020\021\010\025\016\017" < "$1" | \
tr -d "\r" | awk '!/^\[/ { printf "%c%s", length, $0 } END { printf "\xFF" }' > "$2"

View File

@ -1,7 +1,7 @@
#!/bin/bash
# directory of PNG files (assume they are properly sized and named)
PNGS="$HOME/Dropbox/a2/4cade/artwork/cropped-and-named-320x200/_4sports"
PNGS="$HOME/Dropbox/a2/4cade/artwork/cropped-and-named-320x200"
# Python 3
export PYTHON="python"

39
bin/makesorted.js Normal file
View File

@ -0,0 +1,39 @@
a = new ActiveXObject("scripting.filesystemobject")
b = a.opentextfile("res\\GAMES.CONF")
c = []
q = a.createtextfile("build\\GAMES.CONF")
while (!b.atendofstream)
{
d = b.readline()
e = d.indexOf("#")
if (e >= 0)
{
d = d.substr(0, e)
}
e = d.indexOf("[eof]")
if (e > -1)
{
break
}
e = d.indexOf("=")
if (e == -1)
{
e = d.length
}
if (d.length > 0)
{
q.write(d + "\n")
f = d.indexOf(",") + 1
c.push(d.substr(f, e - f))
}
}
q.write(d + "\n")
a.createtextfile("build\\GAMES.SORTED").write(c.sort().toString().replace(/,/g, "\n"))

28
bin/packhgrfile.py Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/env python3
import sys
infile = sys.argv[1]
outfile = sys.argv[2]
i = open(infile,"rb")
filedata = i.read()
i.close
# If the file has a JMP in the last screen hole, the
# game has an animated title, skip packing and copy
# the file as is instead.
if(len(filedata) >= 8192 and filedata[8189] == 0x4c):
print (infile, "has animation, not packing")
outdata = bytearray(filedata[0:8192])
else:
outdata = bytearray(filedata[0:7680])
for h in range(60):
oh = h*128+120
ih = h*8+7680+(int(h/15)*8)
outdata[oh:oh+8] = filedata[ih:ih+8]
o = open(outfile,"wb")
o.write(outdata)
o.close

View File

@ -1,5 +1,14 @@
a = new ActiveXObject("scripting.filesystemobject")
b = a.opentextfile(WScript.Arguments(1))
c = b.readall()
b.close()
a.createtextfile(WScript.Arguments(1)).write(String(c + Array(512).join(" ")).substr(0, 512))
if (WScript.Arguments(1) == "build\\PREFS.CONF")
{
b = a.opentextfile(WScript.Arguments(1))
c = b.readall().replace(/\r\n/g, "\n")
b.close()
b = a.createtextfile(WScript.Arguments(1))
b.write(c)
b.close()
}
c = a.getfile(WScript.Arguments(1)).size
b = a.opentextfile(WScript.Arguments(1), 8).write(Array((Math.floor((c + 511) / 512) * 512) - c + 1).join(String.fromCharCode(0)))

View File

@ -1,11 +1,5 @@
#!/bin/bash
totalsize=$1
outfile=$2
# zero-pads $1 to a multiple of 512 bytes, in place
[[ "$OSTYPE" == "linux-gnu" ]] \
&& filesize=$(stat -c "%s" "$outfile") \
|| filesize=$(stat -f "%z" "$outfile")
padsize=$((512-$filesize))
dd if=/dev/zero bs=1 count=$padsize >> "$outfile"
dd if=/dev/null of="$1" bs=1 count=1 seek="$((($(wc -c < "$1") + 511) & -512))" 2>/dev/null

176
bin/rename.py Executable file
View File

@ -0,0 +1,176 @@
#!/usr/bin/env python3
import fileinput
import glob
import subprocess
import sys
import tempfile
def replace_string_in_file(filename, old_string, new_string):
for line in fileinput.input(glob.glob(filename), inplace=True):
print(line.replace(old_string, new_string), end='')
def rename_files_in_directory(dirname, old_filename, new_filename):
for filename in glob.glob(f'{dirname}/{old_filename}*'):
subprocess.run(['git', 'mv', filename, filename.replace(old_filename, new_filename)])
def rename_one_file_in_directory(dirname, old_filename, new_filename):
for filename in glob.glob(f'{dirname}/{old_filename}'):
subprocess.run(['git', 'mv', f'{dirname}/{old_filename}', f'{dirname}/{new_filename}'])
def rename_inside_disk_image(filename, old_name, new_name):
rt = subprocess.run(['cadius', 'CATALOG', filename], stdout=subprocess.PIPE, text=True)
if not rt:
print('cadius CATALOG command failed')
if not [line for line in rt.stdout.split('\n') if line == f'/{old_name}/']:
return
rt = subprocess.run(['cadius', 'RENAMEFILE', filename, f'/{old_name}/{old_name}', new_name], stdout=subprocess.PIPE, text=True)
if not rt:
print('cadius RENAMEFILE command failed')
rt = subprocess.run(['cadius', 'RENAMEVOLUME', filename, new_name], stdout=subprocess.PIPE, text=True)
if not rt:
print('cadius RENAMEVOLUME command failed')
with tempfile.TemporaryDirectory() as tmpdir:
rt = subprocess.run(['cadius', 'EXTRACTFILE', filename, f'/{new_name}/LOADER.SYSTEM', tmpdir], stdout=subprocess.PIPE, text=True)
if not rt:
print('cadius EXTRACTFILE command failed')
try:
loader_file = glob.glob(tmpdir + "/LOADER.SYSTEM*").pop()
except IndexError:
return
with open(loader_file, 'rb') as f:
loader = f.read()
loader_as_list = list(loader)
while loader_as_list.pop() >= 0x10:
pass
loader_as_list.append(len(new_name))
loader_as_list.extend([ord(x) for x in new_name])
new_loader = bytes(loader_as_list)
with open(loader_file, 'wb') as f:
f.write(new_loader)
rt = subprocess.run(['cadius', 'REPLACEFILE', filename, f'/{new_name}/', loader_file], stdout=subprocess.PIPE, text=True)
if not rt:
print('cadius REPLACEFILE command failed')
def rename(old_game_name, new_game_name):
print(old_game_name)
for filename in glob.glob('res/dsk/*'):
rename_inside_disk_image(filename, old_game_name, new_game_name)
for filename in ('res/GAMES.CONF',
f'res/ATTRACT/{old_game_name}',
'res/SS/*'):
replace_string_in_file(filename, old_game_name, new_game_name)
for dirname in ('res/DEMO',):
rename_one_file_in_directory(dirname, old_game_name, new_game_name)
replace_string_in_file('res/DEMO/_FileInformation.txt', f'{old_game_name}=', f'{new_game_name}=')
for filename in ('res/ATTRACT.CONF',):
replace_string_in_file(filename, f'{old_game_name}=0', f'{new_game_name}=0')
replace_string_in_file('src/prelaunch/*', f'build/PRELAUNCH/{old_game_name}', f'build/PRELAUNCH/{new_game_name}')
for dirname in ('res/ACTION.DHGR',
'res/ACTION.DHGR.UNCOMPRESSED',
'res/ACTION.GR',
'res/ACTION.HGR',
'res/ACTION.HGR.UNCOMPRESSED',
'res/ARTWORK.SHR',
'res/ARTWORK.SHR.UNCOMPRESSED',
'res/ATTRACT',
'res/GAMEHELP',
'res/TITLE.ANIMATED',
'res/TITLE.DHGR',
'res/TITLE.HGR'):
rename_files_in_directory(dirname, old_game_name, new_game_name)
def driver():
#rename("SLICKS", "S8")
rename("CIDER.SPIDER", "AC")
rename("ARCADE.BT.CAMP", "AB")
rename("ARDY.AARDVARK", "AA")
rename("ASTEROID.BLASTR", "AS")
rename("BCS.QUEST", "BQ")
rename("BEACH.HEAD.II", "B2")
rename("BEACH.HEAD", "B1")
rename("BEYOND.WOLFEN", "BW")
rename("BUDGETRILOGY", "BT")
rename("BLOCKCHAIN", "BC")
rename("BOUNCING.KMNGAS", "BK")
rename("BRAINTEASERBLVD", "BB")
rename("BUCK.ROGERS", "BR")
rename("BURGERTIME", "BU")
rename("CANNONBALL.BLTZ", "CB")
rename("CAPTN.GOODNIGHT", "CG")
rename("SMURFEN", "CS")
rename("WOLFEN84", "CW")
rename("CAVRNS.CALLISTO", "CC")
rename("CHAMP.LODERUN", "CL")
rename("COPTS.ROBBERS", "CR")
rename("D.GENERATION", "DG")
rename("DARKSTAR.UNHNGD", "DU")
rename("DAVIDS.MAGIC", "DM")
rename("EGGS.IT", "EI")
rename("IMPOSSIBLE.MISS", "I1")
rename("IMPOSSIBLE.M.II", "I2")
rename("EAGLES.NEST", "IE")
rename("I.O.SILVER", "IO")
rename("LITTLE.COMP.PPL", "LP")
rename("LOCK.N.CHASE", "LC")
rename("MARIO.BROS", "MB")
#rename("MATTERHORN", "MS")
rename("MINGS.CHALLENGE", "MI")
rename("THUNDERHEAD", "MT")
rename("MONTEZUMA", "MZ")
rename("MR.COOL", "MC")
rename("MR.DO", "MD")
rename("MR.ROBOT", "MR")
rename("MS.PACMAN", "MP")
rename("NIGHT.MISSION", "NM")
rename("NIGHTMARE", "NI")
rename("ORILEYS.MINE", "OM")
rename("OOTW", "OW")
rename("PANDORAS.BOX", "PB")
rename("PHARAOHS.REVNG", "PR")
rename("PIEMAN", "PM")
rename("PRINCEUNP", "PP")
rename("RAID.OVR.MOSCOW", "RM")
rename("REALM.IMPOSS", "RI")
rename("SITUATION.CRTCL", "SC")
rename("SOKO.BAN", "SO")
rename("SPYS.DEMISE", "SD")
rename("SUICIDE", "SU")
rename("TECHNOCOP", "TC")
rename("THAROLIAN.TUNLS", "TU")
rename("ASTEROID.FIELD", "AF")
rename("LAST.GLADIATOR", "LG")
rename("SPY.STRIKES.BAK", "S2")
rename("TUBEWAY", "TB")
rename("UP.N.DOWN", "UD")
rename("ROGER.RABBIT", "RR")
rename("WINGS.OF.FURY", "WF")
def driver_phase_2():
rename("CEST.LA.VIE", "CV")
rename("DEFEND.JH", "DJ")
rename("ESCAPE", "ES")
rename("ITS.THE.PITS", "IP")
rename("LAMB.CHOPS", "LA")
rename("MIRV", "M.I.R.V")
rename("NEUT.TOWER", "NT")
rename("SHUTTLE.INTRCPT", "SI")
rename("CAVERNS.FREITAG", "CF")
rename("MOVIE.MONSTER", "MM")
def driver_phase_3():
rename("CP", "CAPTAIN.POWER")
def driver_phase_4():
rename("MATTERHORN", "MS")
if __name__ == '__main__':
#rename("MR.DO", "MD")
#driver()
driver_phase_4()

BIN
res/CACHE00.IDX Normal file

Binary file not shown.

BIN
res/CACHE01.IDX Normal file

Binary file not shown.

BIN
res/CACHE10.IDX Normal file

Binary file not shown.

BIN
res/CACHE11.IDX Normal file

Binary file not shown.

View File

@ -1,3 +1,30 @@
#
# Transition effects for DHGR slideshows
#
# Each Mega-Attract Module that is a DHGR slideshow (see ATTRACT.CONF)
# will use a single transition effect for the length of the module.
# Transition effects are loaded in the order listed in this file. Each line
# of this file is a filename (not including comments, like this one). The
# name of the next transition effect is stored in the global prefs, so this
# file should not contain duplicates.
#
# Transition effects are binary files loaded at $6000 and called with main
# memory banked in, DHGR page 1 showing, and the next DHGR graphic already
# loaded at $4000/main and $4000/aux. A transition effect has full use of
# zero pages (both), $0200-$07FF (both), $6000-$BEFF/main, $800-$1FFF/aux,
# and $6000-$BFFF/aux. $800-$1FFF/main is reserved for the slideshow data.
# $BF00-$BFFF/main is reserved for the ProDOS shim. LC RAM banks 1 and 2 are
# reserved for the launcher.
#
# Important: LC RAM bank 1 will be read/write on entry and must be read/write
# on exit. If you need ROM routines, you are responsible for switching to ROM
# then switching back to RAM bank 1 (read/write) before returning. However,
# you can leave WRITEAUXMEM active. The calling code will unconditionally
# switch back to WRITEMAINMEM.
#
# This file is converted to a binary data structure (DFX.IDX) during build
# then added to TOTAL.DATA on the final disk image.
#
DHGR.FIZZLE2BIT
DHGR.RIPPLE
DHGR.SOFT.DIAG
@ -45,6 +72,7 @@ DHGR.SLOWST.RIP
DHGR.48.SPIRAL
DHGR.RADIAL5
DHGR.FIZZLE
DHGR.48.PAGEC
DHGR.BFLY.RIP
DHGR.IRIS.IN
DHGR.SWIRL
@ -59,27 +87,4 @@ DHGR.WAVY.IRIS
DHGR.BLOOM.RIP
DHGR.48.SYNC
DHGR.FLICK
[eof]
#
# transition effects for DHGR slideshows
#
# Each Mega-Attract Module that is a DHGR slideshow (see attract.conf)
# will use a single transition effect for the length of the module.
# Transition effects are loaded in the order listed in this file. Each line
# of this file is a filename (not including comments, like this one). The
# name of the next transition effect is stored in the global prefs, so this
# file should not contain duplicates.
#
# Transition effects are binary files loaded at $6000 and called with main
# memory banked in, DHGR page 1 showing, and the next DHGR graphic already
# loaded at $4000/main and $4000/aux. A transition effect has full use of
# auxiliary memory, zero pages (both), text pages (both, but preserve screen
# holes), and main memory $6000-$BEFF. $BF00-$BFFF/main is reserved for the
# ProDOS shim. LC RAM banks 1 and 2 are reserved for the launcher.
#
# Important: LC RAM bank 1 will be read/write on entry and must be read/write
# on exit. If you need ROM routines, you are responsible for switching to ROM
# then switching back to RAM bank 1 (read/write) before returning.
#

View File

@ -1,3 +1,26 @@
#
# Transition effects for HGR slideshows
#
# Each Mega-Attract Module that is an HGR slideshow (see ATTRACT.CONF)
# will use a single transition effect for the length of the module.
# Transition effects are loaded in the order listed in this file. Each line
# of this file is a filename (not including comments, like this one). The
# name of the next transition effect is stored in the global prefs, so this
# file should not contain duplicates.
#
# Transition effects are binary files loaded at $6000 and called with
# hi-res page 1 showing and the next HGR graphic already loaded at $4000.
# A transition effect can use $6000-$BEFF, zero page, and $0200-$07FF.
# $800-$1FFF is reserved for the slideshow data. $BF00-$BFFF is reserved for
# the ProDOS shim. LC RAM banks 1 and 2 are reserved for the launcher.
#
# Important: LC RAM bank 1 will be read/write on entry and must be read/write
# on exit. If you need ROM routines, you are responsible for switching to ROM
# then switching back to RAM bank 1 (read/write) before returning.
#
# This file is converted to a binary data structure (FX.IDX) during build
# then added to TOTAL.DATA on the final disk image.
#
BOXES48.SNAKE
RIPPLE
SOFT.DIAGONAL
@ -28,6 +51,8 @@ R.BY.PIXEL
WAVY.IRIS
BIT.FIZZLE
STAR.IN
BOXES48.PAGEC
DIAG.STRIPES
APPLE
MANDELBROT.RIP
SOFT.L
@ -45,6 +70,7 @@ FLOWER
APPLE.RIPPLE
DIAGONAL2
STAR.BLOOM
DIAMOND.STRIPES
BOXES48.SYNC
PALETTE.FIZZLE
BUTTERFLY
@ -81,6 +107,7 @@ BUTTERFLY.IN
LR.BY.PIXEL
CHECKERB.FIZZLE
BOXES48.SIDES
CIRCLE.STRIPES
STAGGERWHITE.LR
SOFT.UD.OUT
ONESQUARE
@ -119,25 +146,3 @@ BOXES48.ARROW
REDLINES
FLICK
[eof]
#
# transition effects for HGR slideshows
#
# Each Mega-Attract Module that is an HGR slideshow (see attract.conf)
# will use a single transition effect for the length of the module.
# Transition effects are loaded in the order listed in this file. Each line
# of this file is a filename (not including comments, like this one). The
# name of the next transition effect is stored in the global prefs, so this
# file should not contain duplicates.
#
# Transition effects are binary files loaded at $6000 and called with
# hi-res page 1 showing and the next HGR graphic already loaded at $4000.
# A transition effect can use $6000-$BEFF in main memory, zero page, and
# text page if needed (but preserve the screen holes). $800-$1FFF is reserved
# for the slideshow data. $BF00-$BFFF is reserved for the ProDOS shim.
# LC RAM banks 1 and 2 are reserved for the launcher.
#
# Important: LC RAM bank 1 will be read/write on entry and must be read/write
# on exit. If you need ROM routines, you are responsible for switching to ROM
# then switching back to RAM bank 1 (read/write) before returning.
#

65
res/SFX.CONF Normal file
View File

@ -0,0 +1,65 @@
#
# Transition effects for SHR slideshows
#
# Each Mega-Attract Module that is an SHR slideshow (see ATTRACT.CONF)
# will use a single transition effect for the length of the module.
# Transition effects are loaded in the order listed in this file. Each line
# of this file is a filename (not including comments, like this one). The
# name of the next transition effect is stored in the global prefs, so this
# file should not contain duplicates.
#
# Transition effects are binary files loaded at $A000 and called with main
# memory banked in (read/write) and the next SHR graphic already loaded at
# $2000/main. A transition effect has full use of zero page (main),
# $0200-$07FF (main), and $A000-$BEFF/main. $BF00-$BFFF/main is reserved for
# the ProDOS shim. LC RAM banks 1 and 2 are reserved for the launcher.
#
# /!\ You can not assume auxiliary memory exists! No, really.
#
# Consider this (supported) configuration: Apple ][+, 64K, VidHD card.
# This machine is capable of displaying SHR graphics by copying pixel and
# palette data from $2000-$9FFF/main to $2000-$9FFF/aux, despite the fact
# that auxiliary memory does not exist and the writes will actually go to
# main memory. However, the VidHD card notices and respects the WRITEAUXMEM
# softswitch and will cache the data in its internal cache and ultimately
# display it.
#
# Even worse, this means that SHR transitions must be careful about writing
# to aux anything other than the current value of that address in main,
# because in some (supported) configurations, those writes will actually
# be altering main memory. Example: you want to clear the palettes space
# before progressively fading them in. Writing all zeros to the palettes
# in "auxiliary" memory will actually overwrite the original palettes in
# main memory.
#
# Important: LC RAM bank 1 will be read/write on entry and must be read/write
# on exit. If you need ROM routines, you are responsible for switching to ROM
# then switching back to RAM bank 1 (read/write) before returning. However,
# you can leave WRITEAUXMEM active; the calling code unconditionally switches
# back to WRITEMAINMEM after the transition code returns.
#
# This file is converted to a binary data structure (SFX.IDX) during build
# then added to TOTAL.DATA on the final disk image.
#
SHR.80BOXES
SHR.FIZZLE
SHR.RIPPLE
SHR.TWOPASS.LR
SHR.RADIAL
SHR.80.SNAKE
SHR.SOFT.IRIS
SHR.DIAGONAL
SHR.80.DOWN
SHR.IRIS.IN
SHR.LR
SHR.RADIAL2
SHR.80.SPIRAL
SHR.FADEIN
SHR.SOFTIRIS.IN
SHR.80.SIDE2
SHR.LR2
SHR.80.ARROW
SHR.IRIS
SHR.UD
[eof]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

BIN
res/TITLE.HGR.UNPACKED/FS2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,36 @@
# This file is automatically generated
AMER.CHALLENGE=Type(06),AuxType(4000),Access(C3)
AUTOBAHN=Type(06),AuxType(4000),Access(C3)
BASEBALL=Type(06),AuxType(4000),Access(C3)
BLACK.BELT=Type(06),AuxType(4000),Access(C3)
BOP.N.WRESTLE=Type(06),AuxType(4000),Access(C3)
CHAMP.BSKETBALL=Type(06),AuxType(4000),Access(C3)
CHAMP.WRESTLE=Type(06),AuxType(4000),Access(C3)
CMPTR.FOOSBALL=Type(06),AuxType(4000),Access(C3)
DIVE.BOMBER=Type(06),AuxType(4000),Access(C3)
FIGHT.NIGHT=Type(06),AuxType(4000),Access(C3)
FORMULA.1.RACER=Type(06),AuxType(4000),Access(C3)
FS2=Type(06),AuxType(4000),Access(C3)
FUJI.SPEED.WAY=Type(06),AuxType(4000),Access(C3)
HARDBALL=Type(06),AuxType(4000),Access(C3)
INTL.GRAN.PRIX=Type(06),AuxType(4000),Access(C3)
INTL.HOCKEY=Type(06),AuxType(4000),Access(C3)
KARATE.CHAMP=Type(06),AuxType(4000),Access(C3)
ONE.ON.ONE=Type(06),AuxType(4000),Access(C3)
POOL=Type(06),AuxType(4000),Access(C3)
SHUFFLEBOARD=Type(06),AuxType(4000),Access(C3)
SKI.CRAZED=Type(06),AuxType(4000),Access(C3)
SOLO.FLIGHT=Type(06),AuxType(4000),Access(C3)
SPDWAY.CLASSIC=Type(06),AuxType(4000),Access(C3)
SUMMER.GAMES=Type(06),AuxType(4000),Access(C3)
SUMMER.GAMES.II=Type(06),AuxType(4000),Access(C3)
SUPER.HUEY=Type(06),AuxType(4000),Access(C3)
SUPER.ICEHOCKEY=Type(06),AuxType(4000),Access(C3)
TAG.TEAM=Type(06),AuxType(4000),Access(C3)
THE.DAM.BUSTERS=Type(06),AuxType(4000),Access(C3)
TOMAHAWK=Type(06),AuxType(4000),Access(C3)
TRACK.AND.FIELD=Type(06),AuxType(4000),Access(C3)
WINTER.GAMES=Type(06),AuxType(4000),Access(C3)
WORLD.KARATE=Type(06),AuxType(4000),Access(C3)
_FileInformation.txt=Type(06),AuxType(4000),Access(C3)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More