From 4e7c832df02bec1b1028dfabddfd7ff2cb294990 Mon Sep 17 00:00:00 2001 From: 4am Date: Mon, 22 Aug 2022 22:04:55 -0400 Subject: [PATCH] sync build and UI code --- Makefile | 370 +- bin/{4sports.vii => 4cade.vii} | Bin bin/addfile.js | 5 + bin/addfile.sh | 19 + bin/buildcache.js | 60 + bin/buildcache.py | 126 + bin/builddisplaynames.js | 28 + bin/buildfileinfo.js | 2 +- bin/buildfx.js | 53 + bin/buildfxful.bat | 14 + bin/buildindexedfile.sh | 88 + bin/buildokvs.js | 46 + bin/buildokvs.sh | 27 + bin/buildpre.js | 43 + bin/buildpreall.bat | 3 + bin/buildsearch.js | 90 + bin/buildsearch.sh | 76 + bin/buildslideshow.js | 57 + bin/buildslideshow.sh | 58 + bin/buildss.js | 73 + bin/changebootloader.sh | 2 +- bin/check-attract-mode.sh | 66 +- bin/checkdate.js | 2 + bin/converthelp.js | 63 + bin/converthelp.sh | 4 + bin/forevershr.sh | 2 +- bin/makesorted.js | 39 + bin/packhgrfile.py | 28 + bin/padto.js | 17 +- bin/padto.sh | 10 +- bin/rename.py | 176 + res/CACHE00.IDX | Bin 0 -> 214 bytes res/CACHE01.IDX | Bin 0 -> 458 bytes res/CACHE10.IDX | Bin 0 -> 399 bytes res/CACHE11.IDX | Bin 0 -> 688 bytes res/DFX.CONF | 51 +- res/FX.CONF | 49 +- res/SFX.CONF | 65 + res/TITLE.HGR.UNPACKED/AMER.CHALLENGE | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/AUTOBAHN | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/BASEBALL | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/BLACK.BELT | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/BOP.N.WRESTLE | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/CHAMP.BSKETBALL | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/CHAMP.WRESTLE | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/CMPTR.FOOSBALL | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/DIVE.BOMBER | 1 + res/TITLE.HGR.UNPACKED/FIGHT.NIGHT | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/FORMULA.1.RACER | 1 + res/TITLE.HGR.UNPACKED/FS2 | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/FUJI.SPEED.WAY | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/HARDBALL | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/INTL.GRAN.PRIX | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/INTL.HOCKEY | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/KARATE.CHAMP | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/ONE.ON.ONE | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/POOL | 1 + res/TITLE.HGR.UNPACKED/SHUFFLEBOARD | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/SKI.CRAZED | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/SOLO.FLIGHT | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/SPDWAY.CLASSIC | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/SUMMER.GAMES | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/SUMMER.GAMES.II | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/SUPER.HUEY | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/SUPER.ICEHOCKEY | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/TAG.TEAM | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/THE.DAM.BUSTERS | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/TOMAHAWK | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/TRACK.AND.FIELD | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/WINTER.GAMES | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/WORLD.KARATE | Bin 0 -> 8192 bytes res/TITLE.HGR.UNPACKED/_FileInformation.txt | 36 + res/TITLE.HGR/AMER.CHALLENGE | Bin 8192 -> 7680 bytes res/TITLE.HGR/AUTOBAHN | Bin 8192 -> 7680 bytes res/TITLE.HGR/BASEBALL | Bin 8192 -> 7680 bytes res/TITLE.HGR/BLACK.BELT | Bin 8192 -> 7680 bytes res/TITLE.HGR/BOP.N.WRESTLE | Bin 8192 -> 7680 bytes res/TITLE.HGR/CHAMP.BSKETBALL | Bin 8192 -> 7680 bytes res/TITLE.HGR/CHAMP.WRESTLE | Bin 8192 -> 7680 bytes res/TITLE.HGR/CMPTR.FOOSBALL | Bin 8192 -> 7680 bytes res/TITLE.HGR/DIVE.BOMBER | 2 +- res/TITLE.HGR/FIGHT.NIGHT | Bin 8192 -> 7680 bytes res/TITLE.HGR/FORMULA.1.RACER | 2 +- res/TITLE.HGR/FS2 | Bin 8192 -> 7680 bytes res/TITLE.HGR/FUJI.SPEED.WAY | Bin 8192 -> 7680 bytes res/TITLE.HGR/HARDBALL | Bin 8192 -> 7680 bytes res/TITLE.HGR/INTL.GRAN.PRIX | Bin 8192 -> 7680 bytes res/TITLE.HGR/INTL.HOCKEY | Bin 8192 -> 7680 bytes res/TITLE.HGR/KARATE.CHAMP | Bin 8192 -> 7680 bytes res/TITLE.HGR/ONE.ON.ONE | Bin 8192 -> 7680 bytes res/TITLE.HGR/POOL | 2 +- res/TITLE.HGR/SHUFFLEBOARD | Bin 8192 -> 7680 bytes res/TITLE.HGR/SKI.CRAZED | Bin 8192 -> 7680 bytes res/TITLE.HGR/SOLO.FLIGHT | Bin 8192 -> 7680 bytes res/TITLE.HGR/SPDWAY.CLASSIC | Bin 8192 -> 7680 bytes res/TITLE.HGR/SUMMER.GAMES | Bin 8192 -> 7680 bytes res/TITLE.HGR/SUMMER.GAMES.II | Bin 8192 -> 7680 bytes res/TITLE.HGR/SUPER.HUEY | Bin 8192 -> 7680 bytes res/TITLE.HGR/SUPER.ICEHOCKEY | Bin 8192 -> 7680 bytes res/TITLE.HGR/TAG.TEAM | Bin 8192 -> 7680 bytes res/TITLE.HGR/THE.DAM.BUSTERS | Bin 8192 -> 7680 bytes res/TITLE.HGR/TOMAHAWK | Bin 8192 -> 7680 bytes res/TITLE.HGR/TRACK.AND.FIELD | Bin 8192 -> 7680 bytes res/TITLE.HGR/WINTER.GAMES | Bin 8192 -> 7680 bytes res/TITLE.HGR/WORLD.KARATE | Bin 8192 -> 7680 bytes res/TITLE.HGR/_FileInformation.txt | 24 +- src/{4sports.a => 4cade.a} | 58 +- src/{4sports.init.a => 4cade.init.a} | 204 +- ...{4sports.init.cffa.a => 4cade.init.cffa.a} | 0 src/{4sports.init.gs.a => 4cade.init.gs.a} | 0 src/constants.a | 137 +- src/fx/fx.cover.fade.a | 2 +- src/fx/fx.dgr.fizzle.a | 52 + src/fx/fx.dhgr.2bit.fizzle.a | 20 +- src/fx/fx.dhgr.2pass.lr.a | 9 +- src/fx/fx.dhgr.48boxes.2snakes.a | 2 +- src/fx/fx.dhgr.48boxes.a | 2 +- src/fx/fx.dhgr.48boxes.arrow.a | 2 +- src/fx/fx.dhgr.48boxes.common.a | 28 +- src/fx/fx.dhgr.48boxes.down.a | 2 +- src/fx/fx.dhgr.48boxes.longdiagonal.a | 2 +- src/fx/fx.dhgr.48boxes.pageturn.clear.a | 51 + src/fx/fx.dhgr.48boxes.sidetoside.a | 2 +- src/fx/fx.dhgr.48boxes.snake.a | 2 +- src/fx/fx.dhgr.48boxes.snake.clear.a | 2 +- src/fx/fx.dhgr.48boxes.spiral.a | 2 +- src/fx/fx.dhgr.48boxes.spiral.clear.a | 2 +- src/fx/fx.dhgr.48boxes.sync.a | 2 +- src/fx/fx.dhgr.48boxes.sync.clear.a | 2 +- src/fx/fx.dhgr.bar.dissolve.a | 9 +- src/fx/fx.dhgr.bubbles.a | 2 +- src/fx/fx.dhgr.bubbles.in.a | 2 +- src/fx/fx.dhgr.butterfly.a | 2 +- src/fx/fx.dhgr.butterfly.in.a | 2 +- src/fx/fx.dhgr.butterfly.ripple.a | 2 +- src/fx/fx.dhgr.corner4.a | 2 +- src/fx/fx.dhgr.corner4.in.a | 2 +- src/fx/fx.dhgr.corner4.ripple.a | 2 +- src/fx/fx.dhgr.diagonal.a | 10 +- src/fx/fx.dhgr.fizzle.a | 27 +- src/fx/fx.dhgr.flick.a | 10 +- src/fx/fx.dhgr.heart.a | 2 +- src/fx/fx.dhgr.heart.in.a | 2 +- src/fx/fx.dhgr.heart.ripple.a | 2 +- src/fx/fx.dhgr.iris.a | 2 +- src/fx/fx.dhgr.iris.in.a | 2 +- src/fx/fx.dhgr.maple.a | 2 +- src/fx/fx.dhgr.maple.in.a | 2 +- src/fx/fx.dhgr.maple.ripple.a | 2 +- src/fx/fx.dhgr.precomputed.1bit.a | 8 +- src/fx/fx.dhgr.precomputed.2bit.a | 8 +- src/fx/fx.dhgr.r.by.pixel.a | 10 +- src/fx/fx.dhgr.radial.a | 2 +- src/fx/fx.dhgr.radial2.a | 2 +- src/fx/fx.dhgr.radial3.a | 2 +- src/fx/fx.dhgr.radial4.a | 2 +- src/fx/fx.dhgr.radial5.a | 2 +- src/fx/fx.dhgr.redlines.a | 9 +- src/fx/fx.dhgr.ripple.a | 2 +- src/fx/fx.dhgr.slow.star.a | 2 +- src/fx/fx.dhgr.slow.star.in.a | 2 +- src/fx/fx.dhgr.slow.star.ripple.a | 2 +- src/fx/fx.dhgr.snowflake.a | 2 +- src/fx/fx.dhgr.snowflake.in.a | 2 +- src/fx/fx.dhgr.snowflake.ripple.a | 2 +- src/fx/fx.dhgr.soft.diagonal.a | 2 +- src/fx/fx.dhgr.soft.iris.a | 2 +- src/fx/fx.dhgr.soft.iris.in.a | 2 +- src/fx/fx.dhgr.star.a | 2 +- src/fx/fx.dhgr.star.in.a | 2 +- src/fx/fx.dhgr.star.ripple.a | 2 +- src/fx/fx.dhgr.swirl.a | 2 +- src/fx/fx.dhgr.wavy.iris.a | 2 +- src/fx/fx.dhgr.wavy.iris.bloom.a | 2 +- src/fx/fx.dhgr.wavy.iris.bloom.in.a | 2 +- src/fx/fx.dhgr.wavy.iris.in.a | 2 +- src/fx/fx.dhgr.wavy.ripple.a | 2 +- src/fx/fx.dhgr.wavy.ripple.bloom.a | 2 +- src/fx/fx.gr.fizzle.a | 127 +- src/fx/fx.hgr.1bit.fizzle.a | 18 +- src/fx/fx.hgr.2bit.fizzle.a | 17 +- src/fx/fx.hgr.2pass.lr.a | 2 +- src/fx/fx.hgr.48boxes.2snakes.a | 2 +- src/fx/fx.hgr.48boxes.a | 2 +- src/fx/fx.hgr.48boxes.arrow.a | 2 +- src/fx/fx.hgr.48boxes.common.a | 200 +- src/fx/fx.hgr.48boxes.down.a | 2 +- src/fx/fx.hgr.48boxes.longdiagonal.a | 2 +- src/fx/fx.hgr.48boxes.pageturn.clear.a | 51 + src/fx/fx.hgr.48boxes.sidetoside.a | 2 +- src/fx/fx.hgr.48boxes.snake.a | 2 +- src/fx/fx.hgr.48boxes.snake.clear.a | 2 +- src/fx/fx.hgr.48boxes.spiral.a | 2 +- src/fx/fx.hgr.48boxes.spiral.clear.a | 2 +- src/fx/fx.hgr.48boxes.sync.a | 2 +- src/fx/fx.hgr.48boxes.sync.clear.a | 2 +- src/fx/fx.hgr.apple.a | 2 +- src/fx/fx.hgr.apple.in.a | 2 +- src/fx/fx.hgr.apple.ripple.a | 2 +- src/fx/fx.hgr.arrow.a | 2 +- src/fx/fx.hgr.arrow.white.a | 2 +- src/fx/fx.hgr.bar.dissolve.a | 2 +- src/fx/fx.hgr.block.fizzle.a | 2 +- src/fx/fx.hgr.block.fizzle.white.a | 2 +- src/fx/fx.hgr.bolt.a | 2 +- src/fx/fx.hgr.bolt.in.a | 2 +- src/fx/fx.hgr.bolt.ripple.a | 2 +- src/fx/fx.hgr.bubbles.a | 2 +- src/fx/fx.hgr.bubbles.in.a | 2 +- src/fx/fx.hgr.butterfly.a | 2 +- src/fx/fx.hgr.butterfly.in.a | 2 +- src/fx/fx.hgr.butterfly.ripple.a | 2 +- src/fx/fx.hgr.cascade.a | 2 +- src/fx/fx.hgr.center.by.pixel.a | 2 +- src/fx/fx.hgr.checkerboard.fizzle.a | 15 +- src/fx/fx.hgr.circle.stripes.a | 144 + src/fx/fx.hgr.color.fizzle.a | 2 +- src/fx/fx.hgr.corner4.a | 2 +- src/fx/fx.hgr.corner4.in.a | 2 +- src/fx/fx.hgr.corner4.ripple.a | 2 +- src/fx/fx.hgr.crystal.a | 2 +- src/fx/fx.hgr.diagonal.a | 2 +- src/fx/fx.hgr.diagonal.stripes.a | 125 + src/fx/fx.hgr.diagonal2.a | 2 +- src/fx/fx.hgr.diagonal3.a | 2 +- src/fx/fx.hgr.diagonal4.a | 2 +- src/fx/fx.hgr.diamond.a | 2 +- src/fx/fx.hgr.diamond.stripes.a | 147 + src/fx/fx.hgr.fizzle.a | 100 +- src/fx/fx.hgr.flick.a | 2 +- src/fx/fx.hgr.flower.a | 2 +- src/fx/fx.hgr.flower.in.a | 2 +- src/fx/fx.hgr.flower.radial.a | 2 +- src/fx/fx.hgr.flower.radial.in.a | 2 +- src/fx/fx.hgr.flower.radial.ripple.a | 2 +- src/fx/fx.hgr.flower.ripple.a | 2 +- src/fx/fx.hgr.fourspiral.a | 2 +- src/fx/fx.hgr.foursquare.white.a | 2 +- src/fx/fx.hgr.full.of.stars.a | 2 +- src/fx/fx.hgr.halfblock.fizzle.a | 2 +- src/fx/fx.hgr.halfblock.fizzle.white.a | 2 +- src/fx/fx.hgr.heart.a | 2 +- src/fx/fx.hgr.heart.in.a | 2 +- src/fx/fx.hgr.heart.ripple.a | 2 +- src/fx/fx.hgr.interlock.lr.a | 2 +- src/fx/fx.hgr.interlock.ud.a | 2 +- src/fx/fx.hgr.iris.a | 2 +- src/fx/fx.hgr.iris.in.a | 2 +- src/fx/fx.hgr.lattice.a | 2 +- src/fx/fx.hgr.lr.by.pixel.a | 2 +- src/fx/fx.hgr.mandelbrot.a | 2 +- src/fx/fx.hgr.mandelbrot.in.a | 2 +- src/fx/fx.hgr.mandelbrot.ripple.a | 2 +- src/fx/fx.hgr.maple.a | 2 +- src/fx/fx.hgr.maple.in.a | 2 +- src/fx/fx.hgr.maple.ripple.a | 2 +- src/fx/fx.hgr.meet.in.the.middle.a | 2 +- src/fx/fx.hgr.onesquare.white.a | 2 +- src/fx/fx.hgr.palette.fizzle.a | 146 +- src/fx/fx.hgr.pinwheels.a | 2 +- src/fx/fx.hgr.precomputed.1bit.a | 8 +- src/fx/fx.hgr.precomputed.2bit.a | 8 +- src/fx/fx.hgr.precomputed.3bit.a | 8 +- src/fx/fx.hgr.r.by.2.a | 2 +- src/fx/fx.hgr.r.by.palette.a | 2 +- src/fx/fx.hgr.r.by.pixel.a | 2 +- src/fx/fx.hgr.radbubbles.a | 2 +- src/fx/fx.hgr.radial.a | 2 +- src/fx/fx.hgr.radial2.a | 2 +- src/fx/fx.hgr.radial3.a | 2 +- src/fx/fx.hgr.radial4.a | 2 +- src/fx/fx.hgr.radial5.a | 2 +- src/fx/fx.hgr.redlines.a | 2 +- src/fx/fx.hgr.ripple.a | 2 +- src/fx/fx.hgr.slow.star.a | 2 +- src/fx/fx.hgr.slow.star.in.a | 2 +- src/fx/fx.hgr.slow.star.ripple.a | 2 +- src/fx/fx.hgr.snowflake.a | 2 +- src/fx/fx.hgr.snowflake.in.a | 2 +- src/fx/fx.hgr.snowflake.ripple.a | 2 +- src/fx/fx.hgr.soft.diagonal.a | 2 +- src/fx/fx.hgr.soft.iris.a | 2 +- src/fx/fx.hgr.soft.iris.in.a | 2 +- src/fx/fx.hgr.soft.l.a | 2 +- src/fx/fx.hgr.soft.r.a | 2 +- src/fx/fx.hgr.soft.ud.a | 2 +- src/fx/fx.hgr.soft.ud.in.a | 2 +- src/fx/fx.hgr.soft.ud.out.a | 2 +- src/fx/fx.hgr.spiral.a | 2 +- src/fx/fx.hgr.split.ud.intro.a | 2 +- src/fx/fx.hgr.stagger.lr.a | 2 +- src/fx/fx.hgr.stagger.lr.white.a | 2 +- src/fx/fx.hgr.stagger.ud.a | 2 +- src/fx/fx.hgr.stagger.ud.white.a | 2 +- src/fx/fx.hgr.star.a | 2 +- src/fx/fx.hgr.star.bloom.a | 2 +- src/fx/fx.hgr.star.in.a | 2 +- src/fx/fx.hgr.star.ripple.a | 2 +- src/fx/fx.hgr.swirl.a | 2 +- src/fx/fx.hgr.tri.fizzle.a | 2 +- src/fx/fx.hgr.vertical.blinds.a | 2 +- src/fx/fx.hgr.wavy.iris.a | 2 +- src/fx/fx.hgr.wavy.iris.bloom.a | 2 +- src/fx/fx.hgr.wavy.iris.bloom.in.a | 2 +- src/fx/fx.hgr.wavy.iris.in.a | 2 +- src/fx/fx.hgr.wavy.ripple.a | 2 +- src/fx/fx.hgr.wavy.ripple.bloom.a | 2 +- src/fx/fx.shr.2pass.lr.a | 51 + src/fx/fx.shr.80boxes.a | 28 + src/fx/fx.shr.80boxes.arrow.a | 28 + src/fx/fx.shr.80boxes.common.a | 229 + src/fx/fx.shr.80boxes.down.a | 28 + src/fx/fx.shr.80boxes.sidetoside.a | 28 + src/fx/fx.shr.80boxes.snake.a | 28 + src/fx/fx.shr.80boxes.spiral.a | 28 + src/fx/fx.shr.common.a | 231 + src/fx/fx.shr.diagonal.a | 63 + src/fx/fx.shr.fadein.a | 187 + src/fx/fx.shr.fizzle.a | 47 +- src/fx/fx.shr.iris.a | 37 + src/fx/fx.shr.iris.data.a | 4004 +++++++++++++++++ src/fx/fx.shr.iris.in.a | 38 + src/fx/fx.shr.lr.a | 49 + src/fx/fx.shr.lr2.a | 50 + src/fx/fx.shr.radial.a | 127 + src/fx/fx.shr.radial.data.a | 4004 +++++++++++++++++ src/fx/fx.shr.radial2.a | 100 + src/fx/fx.shr.ripple.a | 37 + src/fx/fx.shr.ripple.data.a | 4004 +++++++++++++++++ src/fx/fx.shr.soft.iris.a | 37 + src/fx/fx.shr.soft.iris.data.a | 4004 +++++++++++++++++ src/fx/fx.shr.soft.iris.in.a | 38 + src/fx/fx.shr.ud.a | 57 + src/fx/macros.a | 24 + src/glue.decompress.a | 7 +- src/glue.launch.a | 204 +- src/glue.launch.lc2.a | 17 +- src/glue.prorwts2.a | 173 +- src/glue.prorwts2.lc2.a | 54 +- src/hw.accel.a | 9 +- src/hw.accel.lc2.a | 6 +- src/hw.joystick.a | 1 - src/hw.mockingboard.a | 37 +- src/hw.vbl.a | 2 +- src/index/artwork.idx.a | 8 + src/index/attract.idx.a | 8 + src/index/cache00.idx.a | 8 + src/index/cache01.idx.a | 8 + src/index/cache10.idx.a | 8 + src/index/cache11.idx.a | 8 + src/index/count00.a | 6 + src/index/count01.a | 6 + src/index/count10.a | 6 + src/index/count11.a | 6 + src/index/coverfade.idx.a | 8 + src/index/credits.idx.a | 8 + src/index/decrunch.idx.a | 8 + src/index/dfx.idx.a | 8 + src/index/dgr.fizzle.idx.a | 8 + src/index/dgr.idx.a | 8 + src/index/dhgr.idx.a | 8 + src/index/dtitle.idx.a | 8 + src/index/fx.idx.a | 8 + src/index/gamehelp.idx.a | 8 + src/index/gr.fizzle.idx.a | 8 + src/index/gr.idx.a | 8 + src/index/helptext.idx.a | 8 + src/index/hgr0.idx.a | 8 + src/index/hgr1.idx.a | 8 + src/index/hgr2.idx.a | 8 + src/index/hgr3.idx.a | 8 + src/index/hgr4.idx.a | 8 + src/index/hgr5.idx.a | 8 + src/index/hgr6.idx.a | 8 + src/index/joystick.idx.a | 8 + src/index/miniattract0.idx.a | 8 + src/index/miniattract1.idx.a | 8 + src/index/prelaunch.idx.a | 8 + src/index/res.cover.idx.a | 8 + src/index/res.help.idx.a | 8 + src/index/res.title.idx.a | 8 + src/index/search00.idx.a | 8 + src/index/search01.idx.a | 8 + src/index/search10.idx.a | 8 + src/index/search11.idx.a | 8 + src/index/sfx.idx.a | 8 + src/index/slideshow.idx.a | 8 + src/index/standard.prelaunch.a | 8 + src/index/title.idx.a | 8 + src/macros.a | 201 +- src/okvs.a | 316 +- src/parse.common.a | 135 +- src/parse.games.a | 113 - src/parse.prefs.a | 61 +- src/prelaunch/_FileInformation.txt | 1 + src/prelaunch/battle.chess.a | 2 +- src/prelaunch/bop.n.wrestle.a | 2 +- src/prelaunch/computer.foosball.a | 2 +- src/prelaunch/dive.bomber.a | 2 +- src/prelaunch/fight.night.a | 2 +- src/prelaunch/formula.1.racer.a | 2 +- src/prelaunch/fs2.a | 2 +- src/prelaunch/hardball.a | 2 +- src/prelaunch/intl.gran.prix.a | 2 +- src/prelaunch/one.on.one.a | 2 +- src/prelaunch/pool.a | 2 +- src/prelaunch/shuffleboard.a | 2 +- src/prelaunch/ski.crazed.a | 2 +- src/prelaunch/spdway.classic.a | 2 +- src/prelaunch/ss.baseball.a | 2 +- src/prelaunch/ss.basketball.a | 2 +- src/prelaunch/standard.a | 2 +- src/prelaunch/summer.games.a | 2 +- src/prelaunch/summer.games.ii.a | 2 +- src/prelaunch/super.huey.a | 2 +- src/prelaunch/tag.team.a | 2 +- src/prelaunch/test.drive.a | 2 +- src/prelaunch/the.dam.busters.a | 2 +- src/prelaunch/tomahawk.a | 2 +- src/prelaunch/winter.games.a | 2 +- src/prelaunch/world.games.a | 2 +- src/prelaunch/world.karate.a | 2 +- src/proboothd/proboothd.a | 284 +- src/prodos.impl.lc2.a | 181 +- src/prodos.path.a | 217 +- src/prorwts2.a | 1243 +++-- src/textrank.a | 85 +- src/ui.animation.a | 4 +- src/ui.attract.dgr.a | 124 + src/ui.attract.dhgr.a | 117 +- src/ui.attract.gr.a | 51 +- src/ui.attract.hgr.a | 110 +- src/ui.attract.mode.a | 200 +- src/ui.attract.shr.a | 108 +- src/ui.browse.mode.a | 57 +- src/ui.common.a | 10 +- src/ui.credits.a | 117 +- src/ui.font.a | 176 +- src/{ui.font.data.lc2.a => ui.font.data.a} | 0 src/ui.font.lc2.a | 221 - src/ui.offscreen.a | 164 +- src/ui.overlay.a | 90 +- src/ui.search.mode.a | 19 +- src/ui.wait.a | 11 +- 444 files changed, 23853 insertions(+), 3048 deletions(-) rename bin/{4sports.vii => 4cade.vii} (100%) create mode 100644 bin/addfile.js create mode 100755 bin/addfile.sh create mode 100644 bin/buildcache.js create mode 100755 bin/buildcache.py create mode 100644 bin/builddisplaynames.js create mode 100644 bin/buildfx.js create mode 100644 bin/buildfxful.bat create mode 100755 bin/buildindexedfile.sh create mode 100644 bin/buildokvs.js create mode 100755 bin/buildokvs.sh create mode 100644 bin/buildpre.js create mode 100644 bin/buildpreall.bat create mode 100644 bin/buildsearch.js create mode 100755 bin/buildsearch.sh create mode 100644 bin/buildslideshow.js create mode 100755 bin/buildslideshow.sh create mode 100644 bin/buildss.js create mode 100644 bin/checkdate.js create mode 100644 bin/converthelp.js create mode 100755 bin/converthelp.sh create mode 100644 bin/makesorted.js create mode 100755 bin/packhgrfile.py create mode 100755 bin/rename.py create mode 100644 res/CACHE00.IDX create mode 100644 res/CACHE01.IDX create mode 100644 res/CACHE10.IDX create mode 100644 res/CACHE11.IDX create mode 100644 res/SFX.CONF create mode 100644 res/TITLE.HGR.UNPACKED/AMER.CHALLENGE create mode 100644 res/TITLE.HGR.UNPACKED/AUTOBAHN create mode 100644 res/TITLE.HGR.UNPACKED/BASEBALL create mode 100644 res/TITLE.HGR.UNPACKED/BLACK.BELT create mode 100644 res/TITLE.HGR.UNPACKED/BOP.N.WRESTLE create mode 100644 res/TITLE.HGR.UNPACKED/CHAMP.BSKETBALL create mode 100644 res/TITLE.HGR.UNPACKED/CHAMP.WRESTLE create mode 100644 res/TITLE.HGR.UNPACKED/CMPTR.FOOSBALL create mode 100644 res/TITLE.HGR.UNPACKED/DIVE.BOMBER create mode 100644 res/TITLE.HGR.UNPACKED/FIGHT.NIGHT create mode 100644 res/TITLE.HGR.UNPACKED/FORMULA.1.RACER create mode 100644 res/TITLE.HGR.UNPACKED/FS2 create mode 100644 res/TITLE.HGR.UNPACKED/FUJI.SPEED.WAY create mode 100644 res/TITLE.HGR.UNPACKED/HARDBALL create mode 100644 res/TITLE.HGR.UNPACKED/INTL.GRAN.PRIX create mode 100644 res/TITLE.HGR.UNPACKED/INTL.HOCKEY create mode 100644 res/TITLE.HGR.UNPACKED/KARATE.CHAMP create mode 100644 res/TITLE.HGR.UNPACKED/ONE.ON.ONE create mode 100644 res/TITLE.HGR.UNPACKED/POOL create mode 100644 res/TITLE.HGR.UNPACKED/SHUFFLEBOARD create mode 100644 res/TITLE.HGR.UNPACKED/SKI.CRAZED create mode 100644 res/TITLE.HGR.UNPACKED/SOLO.FLIGHT create mode 100644 res/TITLE.HGR.UNPACKED/SPDWAY.CLASSIC create mode 100644 res/TITLE.HGR.UNPACKED/SUMMER.GAMES create mode 100644 res/TITLE.HGR.UNPACKED/SUMMER.GAMES.II create mode 100644 res/TITLE.HGR.UNPACKED/SUPER.HUEY create mode 100644 res/TITLE.HGR.UNPACKED/SUPER.ICEHOCKEY create mode 100644 res/TITLE.HGR.UNPACKED/TAG.TEAM create mode 100644 res/TITLE.HGR.UNPACKED/THE.DAM.BUSTERS create mode 100644 res/TITLE.HGR.UNPACKED/TOMAHAWK create mode 100644 res/TITLE.HGR.UNPACKED/TRACK.AND.FIELD create mode 100644 res/TITLE.HGR.UNPACKED/WINTER.GAMES create mode 100644 res/TITLE.HGR.UNPACKED/WORLD.KARATE create mode 100644 res/TITLE.HGR.UNPACKED/_FileInformation.txt rename src/{4sports.a => 4cade.a} (84%) rename src/{4sports.init.a => 4cade.init.a} (77%) rename src/{4sports.init.cffa.a => 4cade.init.cffa.a} (100%) rename src/{4sports.init.gs.a => 4cade.init.gs.a} (100%) mode change 100644 => 100755 src/fx/fx.cover.fade.a create mode 100644 src/fx/fx.dgr.fizzle.a create mode 100644 src/fx/fx.dhgr.48boxes.pageturn.clear.a create mode 100644 src/fx/fx.hgr.48boxes.pageturn.clear.a create mode 100644 src/fx/fx.hgr.circle.stripes.a create mode 100644 src/fx/fx.hgr.diagonal.stripes.a create mode 100644 src/fx/fx.hgr.diamond.stripes.a create mode 100644 src/fx/fx.shr.2pass.lr.a create mode 100644 src/fx/fx.shr.80boxes.a create mode 100644 src/fx/fx.shr.80boxes.arrow.a create mode 100644 src/fx/fx.shr.80boxes.common.a create mode 100644 src/fx/fx.shr.80boxes.down.a create mode 100644 src/fx/fx.shr.80boxes.sidetoside.a create mode 100644 src/fx/fx.shr.80boxes.snake.a create mode 100644 src/fx/fx.shr.80boxes.spiral.a create mode 100644 src/fx/fx.shr.common.a create mode 100644 src/fx/fx.shr.diagonal.a create mode 100644 src/fx/fx.shr.fadein.a create mode 100644 src/fx/fx.shr.iris.a create mode 100644 src/fx/fx.shr.iris.data.a create mode 100644 src/fx/fx.shr.iris.in.a create mode 100644 src/fx/fx.shr.lr.a create mode 100644 src/fx/fx.shr.lr2.a create mode 100644 src/fx/fx.shr.radial.a create mode 100644 src/fx/fx.shr.radial.data.a create mode 100644 src/fx/fx.shr.radial2.a create mode 100644 src/fx/fx.shr.ripple.a create mode 100644 src/fx/fx.shr.ripple.data.a create mode 100644 src/fx/fx.shr.soft.iris.a create mode 100644 src/fx/fx.shr.soft.iris.data.a create mode 100644 src/fx/fx.shr.soft.iris.in.a create mode 100644 src/fx/fx.shr.ud.a create mode 100644 src/index/artwork.idx.a create mode 100644 src/index/attract.idx.a create mode 100644 src/index/cache00.idx.a create mode 100644 src/index/cache01.idx.a create mode 100644 src/index/cache10.idx.a create mode 100644 src/index/cache11.idx.a create mode 100644 src/index/count00.a create mode 100644 src/index/count01.a create mode 100644 src/index/count10.a create mode 100644 src/index/count11.a create mode 100644 src/index/coverfade.idx.a create mode 100644 src/index/credits.idx.a create mode 100644 src/index/decrunch.idx.a create mode 100644 src/index/dfx.idx.a create mode 100644 src/index/dgr.fizzle.idx.a create mode 100644 src/index/dgr.idx.a create mode 100644 src/index/dhgr.idx.a create mode 100644 src/index/dtitle.idx.a create mode 100644 src/index/fx.idx.a create mode 100644 src/index/gamehelp.idx.a create mode 100644 src/index/gr.fizzle.idx.a create mode 100644 src/index/gr.idx.a create mode 100644 src/index/helptext.idx.a create mode 100644 src/index/hgr0.idx.a create mode 100644 src/index/hgr1.idx.a create mode 100644 src/index/hgr2.idx.a create mode 100644 src/index/hgr3.idx.a create mode 100644 src/index/hgr4.idx.a create mode 100644 src/index/hgr5.idx.a create mode 100644 src/index/hgr6.idx.a create mode 100644 src/index/joystick.idx.a create mode 100644 src/index/miniattract0.idx.a create mode 100644 src/index/miniattract1.idx.a create mode 100644 src/index/prelaunch.idx.a create mode 100644 src/index/res.cover.idx.a create mode 100644 src/index/res.help.idx.a create mode 100644 src/index/res.title.idx.a create mode 100644 src/index/search00.idx.a create mode 100644 src/index/search01.idx.a create mode 100644 src/index/search10.idx.a create mode 100644 src/index/search11.idx.a create mode 100644 src/index/sfx.idx.a create mode 100644 src/index/slideshow.idx.a create mode 100644 src/index/standard.prelaunch.a create mode 100644 src/index/title.idx.a delete mode 100644 src/parse.games.a create mode 100644 src/prelaunch/_FileInformation.txt create mode 100644 src/ui.attract.dgr.a rename src/{ui.font.data.lc2.a => ui.font.data.a} (100%) delete mode 100644 src/ui.font.lc2.a diff --git a/Makefile b/Makefile index bf603ea..a32e76b 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/bin/4sports.vii b/bin/4cade.vii similarity index 100% rename from bin/4sports.vii rename to bin/4cade.vii diff --git a/bin/addfile.js b/bin/addfile.js new file mode 100644 index 0000000..42ef5b5 --- /dev/null +++ b/bin/addfile.js @@ -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") diff --git a/bin/addfile.sh b/bin/addfile.sh new file mode 100755 index 0000000..3b70c79 --- /dev/null +++ b/bin/addfile.sh @@ -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" diff --git a/bin/buildcache.js b/bin/buildcache.js new file mode 100644 index 0000000..37df818 --- /dev/null +++ b/bin/buildcache.js @@ -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) diff --git a/bin/buildcache.py b/bin/buildcache.py new file mode 100755 index 0000000..776e8e8 --- /dev/null +++ b/bin/buildcache.py @@ -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() diff --git a/bin/builddisplaynames.js b/bin/builddisplaynames.js new file mode 100644 index 0000000..7d6eba9 --- /dev/null +++ b/bin/builddisplaynames.js @@ -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) +} diff --git a/bin/buildfileinfo.js b/bin/buildfileinfo.js index 4ca6bc1..27ad8de 100644 --- a/bin/buildfileinfo.js +++ b/bin/buildfileinfo.js @@ -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) diff --git a/bin/buildfx.js b/bin/buildfx.js new file mode 100644 index 0000000..066e9af --- /dev/null +++ b/bin/buildfx.js @@ -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) diff --git a/bin/buildfxful.bat b/bin/buildfxful.bat new file mode 100644 index 0000000..34db8cc --- /dev/null +++ b/bin/buildfxful.bat @@ -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 diff --git a/bin/buildindexedfile.sh b/bin/buildindexedfile.sh new file mode 100755 index 0000000..bb82191 --- /dev/null +++ b/bin/buildindexedfile.sh @@ -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" diff --git a/bin/buildokvs.js b/bin/buildokvs.js new file mode 100644 index 0000000..2b3105a --- /dev/null +++ b/bin/buildokvs.js @@ -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) +} diff --git a/bin/buildokvs.sh b/bin/buildokvs.sh new file mode 100755 index 0000000..08d768e --- /dev/null +++ b/bin/buildokvs.sh @@ -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" diff --git a/bin/buildpre.js b/bin/buildpre.js new file mode 100644 index 0000000..94627a4 --- /dev/null +++ b/bin/buildpre.js @@ -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) diff --git a/bin/buildpreall.bat b/bin/buildpreall.bat new file mode 100644 index 0000000..3f7b8ea --- /dev/null +++ b/bin/buildpreall.bat @@ -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 diff --git a/bin/buildsearch.js b/bin/buildsearch.js new file mode 100644 index 0000000..ea092b3 --- /dev/null +++ b/bin/buildsearch.js @@ -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) diff --git a/bin/buildsearch.sh b/bin/buildsearch.sh new file mode 100755 index 0000000..9a651b2 --- /dev/null +++ b/bin/buildsearch.sh @@ -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" diff --git a/bin/buildslideshow.js b/bin/buildslideshow.js new file mode 100644 index 0000000..8ecd9b0 --- /dev/null +++ b/bin/buildslideshow.js @@ -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) +} diff --git a/bin/buildslideshow.sh b/bin/buildslideshow.sh new file mode 100755 index 0000000..b67c194 --- /dev/null +++ b/bin/buildslideshow.sh @@ -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" diff --git a/bin/buildss.js b/bin/buildss.js new file mode 100644 index 0000000..2b770aa --- /dev/null +++ b/bin/buildss.js @@ -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) diff --git a/bin/changebootloader.sh b/bin/changebootloader.sh index bb0417d..851d2d3 100755 --- a/bin/changebootloader.sh +++ b/bin/changebootloader.sh @@ -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 diff --git a/bin/check-attract-mode.sh b/bin/check-attract-mode.sh index bc9bab1..f0d9a90 100755 --- a/bin/check-attract-mode.sh +++ b/bin/check-attract-mode.sh @@ -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 diff --git a/bin/checkdate.js b/bin/checkdate.js new file mode 100644 index 0000000..4e85417 --- /dev/null +++ b/bin/checkdate.js @@ -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)) diff --git a/bin/converthelp.js b/bin/converthelp.js new file mode 100644 index 0000000..aebff7b --- /dev/null +++ b/bin/converthelp.js @@ -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)) +} diff --git a/bin/converthelp.sh b/bin/converthelp.sh new file mode 100755 index 0000000..2bdf999 --- /dev/null +++ b/bin/converthelp.sh @@ -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" diff --git a/bin/forevershr.sh b/bin/forevershr.sh index b2bb508..08673f0 100755 --- a/bin/forevershr.sh +++ b/bin/forevershr.sh @@ -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" diff --git a/bin/makesorted.js b/bin/makesorted.js new file mode 100644 index 0000000..34d3f70 --- /dev/null +++ b/bin/makesorted.js @@ -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")) diff --git a/bin/packhgrfile.py b/bin/packhgrfile.py new file mode 100755 index 0000000..5948009 --- /dev/null +++ b/bin/packhgrfile.py @@ -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 + diff --git a/bin/padto.js b/bin/padto.js index a191dc7..233549c 100644 --- a/bin/padto.js +++ b/bin/padto.js @@ -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))) diff --git a/bin/padto.sh b/bin/padto.sh index eb4deb7..273ec6d 100755 --- a/bin/padto.sh +++ b/bin/padto.sh @@ -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 diff --git a/bin/rename.py b/bin/rename.py new file mode 100755 index 0000000..45b1842 --- /dev/null +++ b/bin/rename.py @@ -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() diff --git a/res/CACHE00.IDX b/res/CACHE00.IDX new file mode 100644 index 0000000000000000000000000000000000000000..0a7236291550bff434398be6d730aa01775e91fa GIT binary patch literal 214 zcmYciSdb>Qpjd7}iOGU;mjw(8j12jK3(7-*EM^7<1y+XS$OY-K3o_CdWacd>C|Xcj z29)7pNNiq^F=0W;lm+E8fP7wtjflKwQz literal 0 HcmV?d00001 diff --git a/res/CACHE01.IDX b/res/CACHE01.IDX new file mode 100644 index 0000000000000000000000000000000000000000..948848554b98e3899eff2c31cad7f6f4ef7f195e GIT binary patch literal 458 zcmYL^y-EW?6os$<8cbq-)C4RRv{lf;!otGB!oor;3ya;wogJcVOg2ssv9L%XC@3f> z2={_^Vq>A8U}5D8_zu2+wP!X97Ki(tvom+jdL{O!Ihf_zJL$o`G@1x)xxeKBf;l?OhlGZXPPyUL8tDq5_$db1v!MfBp z5M(IWlE$_)RdPe^OV}2DBzqmHpCKxdx{&xv%neML+&eLn#5)h79>qMv6tT2O`UO}8 zPC}Ueo76s}@re|#>O4}b0#Pv3otABP+uK7CTi*%=Q}<7~WJ6?c;BN{PTIz<{Vz)yw V%{V-y%9LO_(ln`P>s6_S@dp$^ZVUhb literal 0 HcmV?d00001 diff --git a/res/CACHE10.IDX b/res/CACHE10.IDX new file mode 100644 index 0000000000000000000000000000000000000000..c2f1aec72439f571a3bb70eab68521dab7cc09a7 GIT binary patch literal 399 zcmX|*D^CMa6oe0NXnB{?0u?L3LIMdS2m}IAQGtR461Lm!BQ5NP?q&r75(I+3fS4l@ z2m}IwLm>DA2m~63Kp+Tn3q^dHGcz~m-0A|HCDc~nuE8%OsGzZfa1YS|S~bLHNUtDP zmxR|yZ#eacSiPiAoLe;S5ZSl}qhws17r3wR-r&C@_(1rH z=nKg=-_3}f)oM{|C3P+J=k<6|<7G`(RjfI2*0r&r;U-Nt7a0agKN)Ciw8hFq**0ET zql(7cD$QLM6AW`=?`vSwG&tW>FCDMB`IU&uNNm4YO^vFSLHi m)VS$CO4JVK2bo{Ij6`PS`oNqb?ie-qZ#!dWkY|xAVGyhhm-;-MG7i}?#{Un+2JnsSqBmYMG9Jw zC@6rLK?qUu51^o+OOYZ)3JQb}1x1P!DG+bYjwqhq$Ly^3t=D4zCU=%NxXaN4j(zT~ zak9?okOz-Bd&Bu>CTEh|P4>4q+2(u){xEspIrzcRFHUwj-$OJ_5fnUukl z49h~!3B(nOs`9V~SA{zToCa#-HN{_$pe^BbiEc@JN0MbpS7dNcvW^Vbv9LhyhIr4V z^HNsdO7Kp?4-$Qn{ujxMJEe{yOQonwvTXzs5hbHoTa1$nk9Ey<1*AGN~$`nLDk7WuTi}?M9w+f zaFM)*1}#k&5zbI>P5U==aJ$$Fmo!?|ctzLlYuZ87q%hK~r+Er<8QTqVGxZ+9HQ=rQ z^W;9!{An?FH+1!xhA%XK1#eTQK>QlE4S5v+`=Z_V+W)AOTi=7u6=)!=P-@a%dx0pf zgAH>;!I=@8w)!^rPy%Gq%8lKBHCx<}*am)Mjv`Z|Fg7`Q;)tyxkhj2wCXtIjm>(r$ NIv83ZE7PVf=pXyatUv$& literal 0 HcmV?d00001 diff --git a/res/DFX.CONF b/res/DFX.CONF index f8bc6c3..70828af 100644 --- a/res/DFX.CONF +++ b/res/DFX.CONF @@ -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. -# diff --git a/res/FX.CONF b/res/FX.CONF index 7b8ed75..756de41 100644 --- a/res/FX.CONF +++ b/res/FX.CONF @@ -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. -# diff --git a/res/SFX.CONF b/res/SFX.CONF new file mode 100644 index 0000000..b8a3cf8 --- /dev/null +++ b/res/SFX.CONF @@ -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] diff --git a/res/TITLE.HGR.UNPACKED/AMER.CHALLENGE b/res/TITLE.HGR.UNPACKED/AMER.CHALLENGE new file mode 100644 index 0000000000000000000000000000000000000000..01bfe55a8eda93a03a81f54bd413779dc48aaa8d GIT binary patch literal 8192 zcmcJU&2Qtz6~M>a8UcLir9SkK$jHf159xof&Y|bHfQ25LTY#Jjqy?H_yBdnSqC%*q zrCk?tq9s*hff_o=Fc3HZD^iscZvc1gEmkOcDJUy&(e^T0A2LE{Pv4Lnn-nQ8cV&-Y zk|qVculc?AW|+^X8kt@*^ijQQ{}{gC?5P+dG4NGGd?}Umd_E$7-ItjtAE9h+E|<;m z-_K$yxy)b|Hg&>`bHioy3}amPqryXsxA;`FHG7-LJNB?uS6bykXQw7RO08A=S8&4iot1mj% zUUjojDpjg@qjI53*nT1JigScN2(TCH1f5jzyNu=Ymd%)A&=Heu1uJ#JMh213F_9fv z7xrHvGyEtb|0~bpf2h6x#xzjT68P-r+1xDz0AN=-_xNwO$=M^|-{SnQn&dBr&@(I~ zxXvWqi%Dws@R6rS+H`ET?<0s9a3pIV&%?N!_=4F;V5Vy#s^*pKkfDf`41#(mHKLIa-u zHYxumYT@(0#;t$J2pn)hxJUXN=n*W$0OI{v%SKti2di{`z?DkDF$RR$fS7 zUK9VDp6zOa2crBtjCBo{GRaYFMW-+eNT10BKG(p1kcGzLkCx|_vhP9z28_?m zLDlE{w>|!M1O8>a$~Cz${*Rho1^^MZYBQxxhLRcZZ!6~(WwPgpN%l|6zxU(f;M8on zRs{ZcikRTR7o7i9&i`SUf4|25-ec|qIA*-7ivy?dZtDC4_1AJ~iw=4H6?!C`h5aGM zdB~vG_yI!ibK#-tpUb``{|^e)D)9es(=KfdEBHSZY?@F1z42l+IsO-RM=qlFzY71F z>jM88=ihP}@UPKn`G4j!pO}Bp$}I%^FK5vr0N_frqiH_!kJ^w1DCJY1jx=xn=XsYB z8*jw!z?_KZx@T(7_d_@Xsl4r&U3?eP076SBA@IR15&yWXwETk?wqjbTV7|xy3M_%3 z>f6wP>AHz2b}i?7UBOOJe<$+)!T9|5G)%BRCY$>~#m@`438|@o@pBcQOPBmx)K*;W zrui3k@w4UBu+I74-Z_B+G-w0=tup8Tn-Kr+`26SYazo?%`&IbOL~Fy5_pjCO4mNg* zWm?<8Cx5$W_CnKOw^XPfKR7c*{GT*Xl| zTO-f_5w@?*>Yxt%6NB^r&&&D$ zt4ji5ogd@>wx1o+^LOw$@DE8~0{?rZ!sF^%r6}ybl+Le!|2LO1`I$T6-k)obT7Jag zL_2o+oyU7?dYgP&A)kNK-!SW64=T^5t8xB^m;C$T3Xb`YL7z-W zCy^ae^Y_04W5+C)H%{e~Ls6%~Zg8Rg|9x1g3;SdI&vO2M7SZap`40<*YrZY;EbF-?|U{KlgS4*T<$`n@U_qz?K zzb+ZVM(C$~$*cd>N<-Km(~J#+uh$49gz{3IOwl5@oW>%7zA zuX+4)_z3G?Sa+|yJXukPpg0 z`BSjrNWfotQLLRFf_zwk4N3!zm4SaQ zU)VoJ+HXLgOaF`N{|f#0;Na1Y1O0!C^Ixh}tDE-rUgh%r+aA>)A6F_9*8jl&{LS(& I{3GoDKd4u*9{>OV literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/AUTOBAHN b/res/TITLE.HGR.UNPACKED/AUTOBAHN new file mode 100644 index 0000000000000000000000000000000000000000..89bd2e64efde97aefd15bd76a68b67412ffa1aa3 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/BOP.N.WRESTLE b/res/TITLE.HGR.UNPACKED/BOP.N.WRESTLE new file mode 100644 index 0000000000000000000000000000000000000000..4154365d83ac0000c66a0f27aa39b6e45ec911a5 GIT binary patch literal 8192 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 S-M9RzFzb}=UUI*A^Z!5cZqJ$k literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/CHAMP.BSKETBALL b/res/TITLE.HGR.UNPACKED/CHAMP.BSKETBALL new file mode 100644 index 0000000000000000000000000000000000000000..c7fd83a59ac76710cd8b6ddd77b331fe920f3f2f GIT binary patch literal 8192 zcmcJU+ix4k6~_Cg52*_YMlvlRi#86RCFmDo3sg;mI8I@St58Y-w*aMdx9o#aQ7~*h zu!vMMsws-(^!v_Sc9xBugTdC#UTw$vP2N z)X9=#yw2Ol$>&%fzA^FhLH=4XUm<62t+ZgJ%zB%@MK&}*-$RFdO?b>jg&4(3(rmNn+nV~#YaTLjHEoP1cj zcBS?CXA2$AbaSCEwC>@$sYJi1iIV+E71Zo(qieaiMF4{23(hk1`<@^7)N^j9K_6@}d46`J?(v9}j_iC<#S7 zR6Bo-&#j%N*MCju=*Wy$3;EPrwA8SJ=+5_8Nexf;%kPZ_v6Zja)D>dyiuynHa`LfO zI-B7Sx8Pmtl&i=3p+SRM;61}n{S?OEmH43x{jd(t1^lmmqtu%EJzl)!=lf%cj~{O2 z{x4w0in*hZPYEIg^05NgNaRzt$mjaSJSmZ@0#<2x!c;~+}nlg4LON%pO-KELw=+je-VP@w4QfJ zM8nSaOI-r26nL(cw){}ds9L~QDjI>c+s zzo2x4_gSZc(G4$O!A*$K%qn?hb)TM#}hwaSOd%TH&6a0zUkd^oqvKsUH#3IJNkE`C#(23 zxj}N{V$I~nSS>hTU-UPTlQZA2VVt z|6i!Iu(z@6t}fLc+V>mypM1+Ti*-C2^cy+anFz7?L1x2Hyt@9+z#QdcB`fRyviyZA zJU% z2iLpZK5C_{^=hSlRIjw2w%5IU;a}<>)~?bs%$GC1?zU1T{(JGn+oPy~oB}S8_zY^( z1?DSq)++uHGQxj?@aQ01lhY3QKSi=y$^Y8I&lkvMsK0~5`FqSMt{?l$3UFJaJzvL4mw^y?NzQiB+b^SN^m$|?{NS3Y|RF?UZnirei z*Yc09AFpEM1=L3HSnI9ge>M$kkK+&DgCGz*gCy_|>R?dMKXS{GeAoYze_W5|e|J{w z!GuGTf4~ZOq1%%D1NirR+{b@j#r-z^^91cEU*r31;O^&N{4e?=FQdND50zK{2mV1m z*0jXG>p9Oqo(tbr{}TT_;UMJykJuZm;{Sxf23-$r{~xh^h0LrWR^%Aud;SaFuFuQy zNB))PU+TZ(e_i;GEdNFRDf2J<-t#Zqe;@Q~3#;?>$k)J2$j9|YmIMM2lLm4f7Afv5zPG{ z|L6DBfA4QAuQqtF|7YztH5&56{eR^BpEJ(k5XL`UgdTve;dYZ3gbb~m0w|Dra1WSl(naUdLd|EsKu3_wXG{v*e~jO9=)IDffpPKx;o zIb#0=?!#>2LY}`(uWwC0D)aBp-#D{e>1f57ha1E*_|x=ns!jZVLwneLptV2w1GWMG zPn4X$E#iv$FZut(`PN}@7(JZU<|;Oi5xt?%xghs*ukNW9sjx&)*hBp7lNFW>fZp&i;%KNR%3{wxsR^{C})q z=P!E$tgVnwdu5XMPAvbhfysXju?1~|`tSMoyy5(3JCrZ{qvwBGKWrV<4gWuI4;(+2 z{(l1_NA;bh{@?SDWw2GW4>1ckVr~%rT+Sm?qwbZ{Ijn)k*mBkp)F$zj_I=>NoVPjs zQS;3idsJuDji5UF?+r)=u`M~9KyJV#a>WM=wHUbh0y*=g{ddm&_a48h((?WrVd&+{ zxKgh^O+ThUtj#sfN9{WFcd&!o2SN_*f&F)x|F_+7%xWIr#_u_@s{RY%a_&{C|FNn6 z1^;*V-$T}X?*}8l%s<9E;!xZd^xq}^x&NRPrZ(iR34++|KV%Kuf6#k(99rU^`oP{n&)FMw<+m;82dIbhKTyu|zxCE}BTD{$ z!?^gmowZJ?JP*w3JDr{OvDY8!|Me)|b(V8DM+ zoA#NbF7X?n^V4enpMZbJH~a6D{I_u&B)y5S`QH1vHZ0}~&K?gxyF3^0HXeOja0vZZ TOp+eLsa*r68D5tsXaD~IC)p;# literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/CHAMP.WRESTLE b/res/TITLE.HGR.UNPACKED/CHAMP.WRESTLE new file mode 100644 index 0000000000000000000000000000000000000000..18ff44b160f4205e2530e0de67308427cb971c9b GIT binary patch literal 8192 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 YzD{3_9wiS5*1>slqGz)9m&pGA2Ti--j{pDw literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/CMPTR.FOOSBALL b/res/TITLE.HGR.UNPACKED/CMPTR.FOOSBALL new file mode 100644 index 0000000000000000000000000000000000000000..2433cb5f913f040fe90274bbc364eae055b6f04d GIT binary patch literal 8192 zcmcIp&59#85LN~!5ym9TFbjKV93#v!^u@5}(D;@d_prX_5q#J=j|XO9kG}YvKKd~d zmbyo+4G%lB!CQyW5_fHds=rR9{J5pZ@y(e%$koq36$kyEOa%y_2lJ&uWT- zZIG@u^=29h<@9~MsqZ{~S%anPRjT+GRvuWR%iRURY6u+_KM+1y!XjCF!W{Mb@Bd7N z1(dI$Ka}tNgZ_m2Rmg;t?FI>^GbxRlRn#?Zavyw3ipZw%n;uQz2VDPKSb;~b|74BF|0F)?F}~6x-+ucElU?#qRr;6pD^=*qivLNkPvI9V zO)?qr|8*u7f?LUdi6wO6{C^4md(jc(EdHm~p3nlV)0puOuYapekolC~D_4~G&vBBj z|AYL85xon>v-e-Zhq&&gbTHQKKQ?u*2i^M&O)~sYq0MMa z^Zmc7jfK4bu}Wpm9)IHhh(9Tt zha>z7-7+fvX{O?1n~c@j!%ytV~9QLa(+(C`=2Uy?lXfhi@#8z)6why z*!$dIek{J%lWSctL1~Cn1F;U|w-Y#j3{EuUuc1rT!RnE@l&*uNvS^tsyp8xRu zty}-!vG*CTIIdWU_dg^{_^#o^Nbv!4>V literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/DIVE.BOMBER b/res/TITLE.HGR.UNPACKED/DIVE.BOMBER new file mode 100644 index 0000000..f74c00b --- /dev/null +++ b/res/TITLE.HGR.UNPACKED/DIVE.BOMBER @@ -0,0 +1 @@ +€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÁªÅŠºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ÄȪ«×ªÕªÖªõ«ÕêýÿÿŸ°æŒž¼¾æ™¿üÀ׫ժݪվժÕüÿÿÿ€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€ŠÕŠºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€Ô¢ÕݪýŸºøÿð¿®ÕûÿÿÇøÿÿÿÿÿÿÿÿ¿õªÁúѪզթ×ÔªÕª€€€€€€€€€€€€º«Õ¡ÿÿÿÿ¿€€€ºÀ†Ðÿƒ €€€úÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿŸ€€ €€¨ƒàÿ‹ÀŽ€€ÐŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕŠÕˆªÕªÕªÔª€€€€‚ŠÕªÕªÕªÕªÏê󪵪ϪժÕÔªÕª€€€€€€€€€€€€ºÿ¯ Ò¢ÿÿ¿À¾€ºÀžÀþ€¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ÿôß›ºÿÿÿÿÿÿÿÿÿ³þ̉ü™³æ¼æ³žÿÿÿÿÿÿÿÿ¿×誩ÕÕªõ·ÕŽƒ†¶ª…€€©Åª‰‚‚ùÿ¿ÿ¿ÕЪùïîÛõ¨½¨íÔÿÿÿ€€€€€€€€ Õª•ºÿÿÿ¯ •ÿ¿À¾€ºÀþ€ˆ€º€úÿÿÿÿÿÿÿÿÿ¿×€€ÐªÿÿÓšºÿÿÿÿÿÿÿÿÿÿÿÿ¯ßªõëÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿç¡Á£…ˆ€Š€Ž˜€€€€€À€ µÿ€€úÿÿÿóϪíÿÿÿÿÿÿýÿ€€€€€€€€ª…ª•ºÿÓÿÿÿÿ¯µ€€€ºÀþƒ€À¾€€€úÿÿÿÿÿÿÿ¿×€¢‘‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßêÿºý¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÕÿ•€Ð€ÐªÕªÕªÕ€€€€€€€€€€€€¨ÕªÕªÕîÕª€€€€€øÿ€€€€€€€€¨ŠºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×€ªÕªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿª½úªýÿÿÿÿÇþÕªýÿÿ¿×üÿÿÿ½†Õþ¨ÕÔ̪ÕúŸÔþ…Õ¨õÿÔÿÿŸõ‡õÿÿÿŸõÿÿÿÿ¯Õª€€€€€€€€…ÕŠºÿÿŸ€€ ‡ ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ôª©©ßþÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÕþÿÿÿÿºÕªÕªÕªÑ¾×üÿÿÿÔ‚”‚„ˆÐ Á€”¨Ð ‘€…Š‚„ª„ŠÔŠªÕê§ÕªÕªÕ¨ÕªÕª€€€€€€€€€€€ÔªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª€€€ÕªÕŠºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€Ð€€ô€€Ðÿÿ¿×êÔ¢ÕÕªÕŠÙªŸÊÕºÕþÿŸ³æÌ™Ïùà™ÿùÌתիݪժժ×ü®Õª€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€•Ô”ºÿÿŸ€€ ‡ ƒ ŠÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€ÕªÕߪ՚Šÿß¿úÝúÿÿÇøÿÿÿÿÿÿÿÿ¿õªõêժݟõºÓÔªÕª€€€€€€€€€€€€º¯Õ¢ÿÿÿÿ¿€€€ºÀ†Ðÿƒ¨€€€úÿÿÿÿÿÿÿ¿×€€€€ Õª…ºÿÿߪժߪÕê×êÿ¯Õ®ÕªÕ¯ÕªÕ®Õ®Õþÿ¿×¨ÕªÕý§ŠªÕ¨ÕªÔŠ€ ”ÒŠŠÕªÕªÕªÕª±êö«Õ©ÍªÕªÕÔªÕª€€€€€€€€€€€€ºÿŸ¨Òªÿÿ¿À¾€ºÀžÀþ€º€€ðÿÿÿÿÿÿÿÿ¿×€€€€þû¦•ºÿÿÿÿÿÿÿÿŸ³þ̙̙³æ¼æ³žÿÿÿÿÿÿÿÿ¿×èÓêÕÕêû€†°þ€„¥¨ˆ€Âÿÿ¿ÿÿ¿Æªùï쨕¹ôŽÅôÿÿÿ€€€€€€€€¨Õª•ºÿÿÿ¿€•ü¿À¾€ºÀþ€ˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€€”ˆýÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿëתÕïÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ£Õ«ÔŠ„¨…€À€€€À€Àª•µÿ€€úÿÿÿøߪëÿÿÿÿÿßüÿ€€€€€€€€Š ª•ºÿ—ÿÿÿÿ¿µ€€€ºÀþƒ€Ð¿€€€úÿÿÿÿÿÿÿ¿×€ªÐ¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßêßþõ¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€Àª…€€€€€€€€€€€€€€€€€€€€€€€€ª…€€€€€Ð‚üÿ€€€€€€€€ÀÄЊºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×ÀŠÕŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿªµ‘Úªýÿÿÿÿ¯ÝªÕÿÿ¿×üÿÿÿªÕªÁŠÍêÕŠ ýë ‡ŽÐ¯Õþÿ§õ«þúõïêê©Õÿ¯žÕª€€€€€€€€ÕªÕŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ôª¥‹õ«ÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿתÕÿÿÿÿߪժժ×êѺ×üÿÿÿÔˆ‘¢ÄˆÑˆÑˆ‘ªÄˆ‘¢Ä¨”¢Ä¨ÄˆÕÿÿïêÿժժŪժժ€€€€€€€€€€€ÐªªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª•ÕŠ€€€€€€ºÿÿŸ€€à ‡ ƒ €ˆÀŽ€€ð€€ô€€ðÿÿ¿×¨µÑ”ÕêתÕêרժÝûÿŸ³æÌ™Ïùÿ™ÏùÌת׫ժժµª×ÔªÕª€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€À”ºÿÿŸ€€ ‡ ƒ ŠÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿× ÕªÕÕªÕŠ°ÿñÿ¿ÚÕëÿÿ×àÿÿÿÿÿÿÿÿÿÕªÕªÕªÕŽµ·×ÔªÕª€€€€€€€€€€€€ºŸÕªÿÿÿÿ¿€€€ºÀ†Àþƒ¨€€€úÿÿÿÿÿÿÿ¿×€€€€ªÕªŠºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×¨ÕªÕÿøÓŠªÕ¨ÕŠÐŠ€ ”‚¨ŠÕªÕªÕªÕª™šÕ¨í¯ÕªÕªÕÔªÕª€€€€€€€€€€€”ºÿ€Õªÿÿ¿À¾€ºÀž€ú€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÿŸºÿÿÿÿÿÿÿÿ¿¸þṜ¼¸æ°ðƒŸÿÿÿÿÿÿÿÿ¿×¨Õÿ×ÝÿûÀö€€°þ€„娀€Åÿÿ¿ÿÿŸ¿¨üÏÕ©Õ´¥«®ôÿÿÿ€€€€€€€€ªÕª•ºÿÿÿÿƒÕê¿À¾€ºÀþ€ˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€‚•‚ÿ¯ÿ‹ºÿÿÿÿÿÿÿÿÿÿÿÿëתկÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿŸ €€ Ñ‚€†Î€€€€¨€€€°ÿƒ€€øÓª•üÿèþÿÿÿÿÿ×ü߀€€€€€€€””ª•ºÿÇþÿÿÿÿµ€€€ºÀþƒ€Ð¿€€€úÿÿÿÿÿÿÿ¿×”‚ŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßú×þÕ¿õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€Á€€€€€€€€€€€€€€€€€€€€€€€€€€à€Ð€þÿ€€€€€€€€¨Õ€€ºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×ԪѨÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«õÕÞªÿÿÿÿÿ•¯ÕêÝÿÿ¿×üÿÿÿþú§ªÕŠÀϪÕê˨է¡ÔŠýëת̊ý›¿ŠÊªÕªÔªÕþÿªÕª€€€€€€€€Ñª•ŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ъ¥‹Õú÷šºÿÿÿ·ÿÿÿÿÿÿÿÿÿÿªýÿÿÿÿß«ÕªôêתӪ×üÿÿÿê ‘‚„ˆÐ€Ñˆ‘¨Àˆ‘¢„¨”¢Ä¨Äˆ•õÿÿªõߪÝÒª«ÕªÕª€€€€€€€€€€€ÀªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ‚€€€€€€ºÿÿŸ€…€ ‡ ƒ €ˆÀŽÀ‚ÀÀªõÀ‚Àÿÿ¿×ÀªÑª×ª×ªÕªª•ªõúÿŸóùÌ™ÌùÿÓœÌѪ֪ժժݩ×ÔªÕª€€€€€€€€€€€€ºúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€ÐŠºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀÀ†Àþÿ¿×¨ÕªÕÕªÕŠº‡þÿŸþÿÀÿÿÆÂþÿÿÿÿÿÿÿÿÔªÕªÕª·µ¿×ÔªÕª€€€€€€€€€€€€º¿Å¨ÿÿÿÿ¿ÀŠ€ºÀŽÀþ¨€ªÕúÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×¨ÕªÕŸÔŠ€€€€€€ €À€Å€€€€€€€ìúÓ¨ÕêÔªÕªÕÔªÕª€€€€€€€€‚€€•ºÿ€Õªÿÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿ«¥‰ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿÿÿûŸÅ€ð „õ¨ÕªÅðÿ¿ÿÿÏÿãÿ¿ÔëÕ¾ÔªýûûÓª€€€€€€€€¨€ª…ºÿûÿÿŸÔª¿À¾€ºÀþˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€‚ШÿªÿŸºÿÿÿÿÿÿÿÿÿÿÿÿûתտÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿߪ€ªÀŠ€€€†€€€€€€ˆ°ÿŸÕª½…€þïÿÿÿÿÿÿÿ÷ü§€€€€€€€€•Õª•ºÿÇüÿÿÿÿ¿€€ÀºÀþ‡€Ð¿€€€úÿÿÿÿÿÿÿ¿×€Š€¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßúÕÿ×¾õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ŒÂÿÿ€€€€€€€€Õª•ºÿÿŸ€€€€€ ƒ€ô€ÀŽ€€ÀŽ€€ÀŽ€€Àþÿ¿×ЪъÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«ýÿÿªÿÿÿÿÿå«Õ®ýªÿ¿×üÿÿÿЪժєúϮժÕú쀈•€×«ý«õ¹Õî…¤…Õêÿµª»ú–ªÕª€€€€€€€€ÕŠÀŠº¿ÕŠ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†ÀÖª½×Ôª¥­ýïýŸ¹ÿßû¿þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ª×º„ªÕªÓ®×üÿÿÿꈑªÄˆÑˆÑˆ‘ªÄˆ‘¢Ä¨”¢Ä¨ÄˆÕòŸÕªžÕþ¯ßæªÕŠÕª€€€€€€€€€€€€ªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ€€€€ÔŠ„€ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×À‚Ô‚÷¯ÝšÚîãºÕªÕêÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÖªÕªÕªÕ«×ÔªÕª€€€€€€€€€€€€ºêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€ÕŠºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕªÕ‚ºÑªÕºÞªÀ¢ÕʪªÕªÕªÕªÕªÕªÕªÕ«Õ©õ¿×ÔªÕª€€€€€€€€€€€€ºÿÀªÿÿÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ªÕꞺÿÿÿÿÿÿÿÿ¿¸ðáùœ¼¸ð°ðƒçüÿÿÿÿÿÿÿ¿×¨ÕªÕÓ •êƒªÝª•ª…€ €€À€ÁÔªÕªÕª•ÔƒÁ¢Õ©Õ‚€€€ÔªÕª€€€€€€€€Š€ •ºÿ€Ðªÿÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿýÿºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü«ýÿïÿû‡”Ï€€ð À’”¨€ õÿ‡þÿçÿÿÿŸíÿ™Ý”¬¨ÕªÕª€€€€€€€€€”ª”ºÿõÿÿÿЪ¼À¾€ºÀþˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€Š€€ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúתտýÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€Õª¢€ü€€€€€„€€°˜€€ð¿€€€ÿïÿÿÿÿÿÿÿÿ¼¯€€€€€€€€Ôª¥•ºÿßüÿÿÿÿ¿ÕªÕ¾ÕþתտժÕúÿÿÿÿÿÿÿ¿×ԪЪÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿߪÕÕÖªõÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€°†¶ƒàÿÿ€€€€€€€€ªÕ”€ºÿÿŸ€€€€€ ƒ€ô€ÀŽ€€ÀŽ€€ÀŽ€€Àþÿ¿×Ј…ŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«ý«ÿêÿÿÿÿÿå«õªÝªý¿×üÿÿÿѪՔլÿ«ÕªÏ×ö• ÅªÕº×šÓâõëÔŠ¥…ÕÐåïõ÷Ϫժ€€€€€€€€Ð ÕŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ô‚•Õÿ«õ‹ùî׫¿úÿÿÿÿÿÿÿÿÿÿàÿÿÿÿ÷¾Õª…ªÕªÛªÕüÿÿÿÕ‚”ª„ˆÐˆÁˆ‘¨Äˆ‘¢Ä¨”‚ĨĈĪժժժժªÕªÕʪ€€€€€€€€€€€€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×€€€€Ô‚‚ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€€”€ÿúÝ«ÖþôïÕªÕîÿÿ÷ÿÿÿÿÿÿÿÿÿÿÕªÔªÕºÕªõŸ×ÔªÕª€€€€€€€€€€€€º¨ÿçÿÿÿÿ¿€€À¿Àƒðÿ‡ €€€úÿÿÿÿÿÿÿ¿×€€€€€Ôª•ºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕª•ˆŠþÿÿ¿þÿ€ðÿ‹‚ÿÿÿÿÿÿÿÿ¿íéÔªÕªÕªÕª×ÔªÕª€€€€€€€€€€€€ºÿÑ¢Õúÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€êÿÿŸºÿÿÿÿÿÿÿÿŸ³æÌñÌ™³æ¼æ³æüÿÿÿÿÿÿÿ¿×”ÕªÕ”ªÕ€„ªÝª…ª…€¡€€ ‚Ъժժ•ÔÈÕ¯µªÓ½…ÿ¤ÔªÕª€€€€€€€€ Õ¢•ºÿß‚ÀÈþÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÿ„ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿªýÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü«ýÿÏàƒ€Ÿ€€€ô€‘€Ðª€ õÿ‡þÿñÿÿÿÏÕûýïÿÿÿÿÿ€€€€€€€ª•€”ºÿôÿÿÿ‡¨µ€€€ºÀþ€À¾€€€þÿÿÿÿÿÿÿ¿×¨€ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúߪõ¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×üëÿÿ€€”ˆ€ˆ€€€€Œ¨€€€€ÔŠÕ²˜€€ð¿€€Àÿïÿÿÿÿÿÿÿÿü¯€€€€€€€€Õ‚¤ºÿŸúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ÀªÕ‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßú¿Åú¿õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€˜€€€€€€€€€€†€€€€€€€€ÀœÇ±ðÿꀀ€€€€€€¨Õ‚ŠºÿÿŸ€…€€€ ƒ€ô€ÀŽÀ‚ÀŽÀªÕŽÀ‚Àþÿ¿×ЪժÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿªýëÿÿÿÿÿý«õºÕºõ¿×üÿÿÿ……ÕªúßþԪю€×´Õ¢€¨Õª×ªÕªÕªÕªÕЪ­¥ÕªÕʪժ€€€€€€€€Õª•Šºßª•€€€ ‡ ƒ€€ÀŽ€€ÀŽ€€ü€€ÀªÕ¾×ÀŠ”ÊÕªÕ‹™«Ý®•úÿÿÿ¿¸æŒœÌ¹ê™Ÿüá߮ݪõªÔªÓ¦ÕüÿÿÿÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªªÕêªÕª€€€€€€€€€€€€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×€€€€€€ÐŠºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€ •ÐßÿÿŠºÿﱪõêÿÿ×ÿÿÿÿÿÿÿÿÿÿÕªÖêժשµ»×ÔªÕª€€€€€€€€€€€€ºªý«ÿÿÿÿ¿€€€¾À‚Ðÿ‡ €€€úÿÿÿÿÿÿÿ¿×€€€€‘Õª•ºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕժŊðÿÿÿ¿þÿ€ðÿ‡‚ŸÿÿÿÿÿÿÿÿÍâ֪ժݪýý×ÔªÕª€€€€€€€€€€€€ºÿƒ Åêÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€êÿÿÿÿÿÿÿÿÿŸ¿æÌáÌŸ³æ¼æ³æüÿÿÿÿÿÿÿ¿×ØÒêªÁªÕüÓêͪ…ª…€¡©… ‚ÒªÕêÕª•ÂŠ˜×ªÓ­ÿ¿«ÝªÕª€€€€€€€€ª•ª•ºÿŸˆ€ªõÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÏšºÿÿÿÿÿÿÿÿÿÿÿÿÿתÕÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü¿Õª›à€ÐŠÕ …Ü€Ô€€ˆÕª•õÿ¨ÕðÿÿÿïÓªµ§ÿªÅ¾êÿª€€€€€€€€ª¨¥•º¿ñÿÿÿÿª±€€€ºÀþ€À¾€€€úÿÿÿÿÿÿÿ¿×Ј€¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúÿªý¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×ü«õÿ€€€€€€ Õ‚€€€€€€€€ÔªÕª€ð¿ªÕªÿïÿÿÿÿïÿÿÿüÿ€€€€€€€€Ð¢•ˆºÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×„¨Õ¢ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßê¿‘ú¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿŒ€à€€€À‡€€€ø»Àª€€€€€€ž€þЂ€€€Àí¶ã€øÿª€€€€€€€€¨•ª•ºÿÿŸ€€ … ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×”ÕÚŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¯ßªõûÿÿÿÿ¿ÕªÕêÕºÕ¿×üÿÿÿÕŠ •Õª…ý‰¨Š¨ÑªÑŠ…ªÔ¨ÑŠ…ªÕª¨ÕªÕª­¥ªÕŠÕªÕª€€€€€€€€Õ‚ˆºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ÀªÅÊýîÕŠÖªõªÕîÿÿÿŸ³æ̙ϙ֙ÏùÌߪժժÕêÖ®ÕüÿÿÿÚªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ¢ÕªÕª€€€€€€€€€€€€ºÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª×€€€€€¨……ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×ЪÔÿªßžºáÿŸ®Õ¾ÿÿ×þÿÿÿÿÿÿÿÿ¿õªÐúÁªÕªÕª×ÔªÕª€€€€€€€€€€€€ºªõ©ÿÿÿÿ¿€€€ºÀ†Ðÿƒ €€€úÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿŸ€€€€€ ƒ ÕŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕժЂªÕªÕºÔª€ Õ‚‚ŠÑªÕªÕªÕªÍêÓªÕöߪÿþ×ÔªÕª€€€€€€€€€€€€ºÿÇ„Õèÿÿ¿À¾€ºÀžÀþ€¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ŸÓ™•ºÿÿÿÿÿÿÿÿÿ¸ðÌÁ¼œ³ø°æÃþÿÿÿÿÿÿÿ¿×èÒÖÊÔªõøƒÿ®ª€¡ª… Š‚ҪվתÕШ›íߪÓꦭծժ€€€€€€€€ª…ª•ºÿÿƒ€ªÔÿ¿À¾€ºÀþ€ª€º€ªÕÿÿÿÿÿÿÿÿ¿×€€€ˆÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¿ÕªÕúÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÕ®³¬Ô€ˆÔª…ÞϪ•€€€À€ µÿ€Àúÿÿÿ÷×õ§ÿÿ¯•ýÿÿ€€€€€€€€Šª¥•ºÿáÿÿÿÿ‹µ€€€ºÀþƒ€À¾€€€úÿÿÿÿÿÿÿ¿×€¢Ð‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúÿºý¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×üÿõÿÁªÕ Õ‚…ŠÀ€€€€€€‚€€€ Õò÷‡€€€îÇÿÿÿÿÿ€øÿ€€€€€€€€Õª…ŠºÿÿŸ€€ €€¨ƒ€ýƒÀŽ€€Ð€€ÀŽ€€Ðƒ‚¸×„ˆÑªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿª¿‘ú«ýÿÿÿÿÿª×úÿÿÿ¿×üÿÿÿÿƒàƒ€ Ýñ©µõÿÿëÿýë‡Ààÿÿûÿªÿÿý¿³öýÿ³¦Õª€€€€€€€€Ð ÕŠºÿÿŸ€€ ‡ ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×”­êªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÕþÿÿÿÿ«Õ«ÕëÕºÕ¾×üÿÿÿŪժժժժժժժժժժժ¥ÕªÕª¨Õª•ªÕŠÕªÕª€€€€€€€€”€ÐˆºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ԪՊߪÿ®ÕºÕú‘ê÷ÿÿŸ³æ̙ϙڙÏÿÌߪݪժժ֨ÕüÿÿÿÕªÚªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕÔêªÕª€€€€€€€ÿ \ No newline at end of file diff --git a/res/TITLE.HGR.UNPACKED/FIGHT.NIGHT b/res/TITLE.HGR.UNPACKED/FIGHT.NIGHT new file mode 100644 index 0000000000000000000000000000000000000000..be74685d973daf3bc6853f23baf53f06ac2ed70d GIT binary patch literal 8192 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 L2g5Q$6aW7J^nz$z literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/FORMULA.1.RACER b/res/TITLE.HGR.UNPACKED/FORMULA.1.RACER new file mode 100644 index 0000000..89bdae2 --- /dev/null +++ b/res/TITLE.HGR.UNPACKED/FORMULA.1.RACER @@ -0,0 +1 @@ +€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ À€‚„€Õ¢Õˆ€ À€‘ „ˆÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€‘¢Ô À ÅˆÐ€€•¢Ä¨Ñ‚ԨѢĈ•ªÔ¨€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€€€€€€€€€ž€ø€àÇ€€¼€€àÇ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€ÐÚ®¯•€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€ ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ª€‚ĈтÁŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ €€€‚€€€…Š€¨€ Á‚€€”€€ Á‚€€€€ˆ€€À€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€ÐÚ®¯•€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€ ÕªÕ‚€€€Š”€Ð€À‚…€€¨€€À‚…€€€€¨ÕªÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯…€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€€Õø¿ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€ÀŸ¿þÌùóçÏ™¿€ÃŸ¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ ÔŠÕ¢À€Õ¢Õ¨•ªÅ€ÑªÔŠÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ø¿àÀçÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€‘ªÔ¨Ñ¢ÅˆÐ „€•¢Ô¨Ñ‚ԨѢĊ‘ª„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€ðÿÿÿƒ€€€ž€ø€àÇ€€¼€€àÇ€€€€üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€Ðâÿ©…€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€€Õ઀€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€À³æÌ™ÃáÀ™ŒàÙ³à€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€ À€¢À€ Àˆ€ À€‘ „ˆ€€€€€€€€€€€€€€€Š€ªÄ¨Ñ¢Åˆ•ŠÔ¨Ñ¢…€€ª€ªÄ¨Ñ¢ÅŠ€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€‘¢ À Àˆ¢Ä€¢Ä €„  Äˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ðÿÿÿƒ€€€…Š€¨€ Á‚€€”€€ Á‚€€€ ­˜°€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€Ð‚¿¨…€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€À³þ°øÃáÌŸŒ€ÃŸ¿ø€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€ªÔ¨Ñ¢ÅŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€Ð À€‚‘€ Àˆ€ Àˆ‘ „ˆ€€€€€€€€€€€€€€€ €ˆÔ  ÄŠ¢ˆÁ €€€ €‚Ĉ‘ „‚€€€€€€€€€€€€€€€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€•¢ À ÀŠÐ€€¢Ä €„  Åˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€€àÀÁ—€€€Š”€Ð€À‚…€€¨€€À‚…€€€ ­ÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€À³†°øÀáÌ™Œ€ƒ˜³à€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¢Äˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€¢ÅŠ¢À€Õ‚„€Õ¢À¨ ÀˆÑªÔŠ•€€€€€€€€€€€€€€€ˆ”ˆÔ Ð ÅŠ…¢¨Á €€¨”Š¨Ñ …‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€•ª À ÁŠ‚€ªÔ Ð‚” Ð¢ÅŠ‘¢„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€€øÿ×—€€€Àªø€àÃת•¼ÕªáƒÐŠ€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€ÀŸ¿†°˜óçÏ™Œà˜¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ”ªÔ¨‘€‚Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€¨À€‘€„€€¢Àˆ€ À¢‘ Ä€€€€€€€€€€€€€€€€‚€ˆÔ  Áˆ¢ˆÁ €€€ €‚Ĉ ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€•Š À Àˆ‚Á€¢” €‚„ €¢Äˆ‘¢„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€€€€€€€€€Š”€Ð€À‚…€€¨€€À‚…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯•€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€‚”ˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€ À€Á€„€€¢Àˆ€ À¢‘ „‚€€€€€€€€€€€€€€€ª€ªÄ Ð¢Äˆ•ŠÔˆÁ …€€ª€ªÄˆÐ¢„‚€€€€€€€€€€€€€€ \ No newline at end of file diff --git a/res/TITLE.HGR.UNPACKED/FS2 b/res/TITLE.HGR.UNPACKED/FS2 new file mode 100644 index 0000000000000000000000000000000000000000..a39a6e93888c7cca80d7a0df3e54763604af7e6f GIT binary patch literal 8192 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 A5&!@I literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/HARDBALL b/res/TITLE.HGR.UNPACKED/HARDBALL new file mode 100644 index 0000000000000000000000000000000000000000..22929f34d633d6f3fa1f44f65e521a16f98edc9a GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/INTL.GRAN.PRIX b/res/TITLE.HGR.UNPACKED/INTL.GRAN.PRIX new file mode 100644 index 0000000000000000000000000000000000000000..faf6a147563a17a7145a5a9b5236ecc18fe96c3b GIT binary patch literal 8192 zcmb_heQZ?0D@#6+d_168B_V;vt=$G7XgtYinLRPf$}n`9LGNRD9NAZ{SG^f71OdT7=_3-pxW_pxj*(O3LylRD zN+gjWBvm3xlE{puMBMr)8r>v9w|MGuMdh1IaM_$###mm00aQ6OadYb2QBR9qy|V;4 z%@5f5OkEAP5g1WhK$d{YKHE%ofaLzG8max(@;25 z$)1~PG@AKw{s+`HbubFesNUj^c$UwNXDku&#=+b*wk1EUD#_4-UT z`?2HYZ^RC-i+^WY& zf4ubieb@WnthUrNB7NMf=fQthQd^_+q%kl4liCu1CHi+`@<9KH|CE9Ms}~xV9Ukxf ziRlmD#lnA&49?^pSz(7_Pyx20%JRc9;%{=eeq{XE=%VwFXy70FE9$cvCOO$ufeh_Y zlgWp{vt9!JhlT+EP$+fAqoDs_*UsrJyPv&iDCsZE|I|Sxk4N%WApQl1N1_f`ZoQmb z;T1t}2S`m#(C4%1{CD{;@4j)@fxm0)pwXB+{}+ybk0cq}2@kAa4#^{V))I;laXt9- zwW$loPXBa-V-};LC<-C{4v|uk9ZSg(hH;fhwKjJNadmBN_pMp6==C4E*rx*it*^Ai zKCe2w|G;;DUy&8RF?JjBnC+5R!U|^($Wnk5m-%t{PpZw(0?i=XadCRnnKI|3r3S?=|H1 zaq>*X+Mq>wz#v=J`~&9IxU9t0S=f6+>K#Z84FUe+>NjEi+otXReW6w7FRn>7=C_sID#FSS zn8f@738oQ9;`NI)4F2~4{&CU4@`RE9u@iA(Y)9fvVAeDBp7=n^B)9$%%>NZ44Z^t6 z3PJ_IzaZQm{(VkL!ePI|XA5Pj<8RNdZgfR8w%=$hLjD(opqc+^5Q2eF@En5?aXonC zE7gMYO8NU7vltbnTgSf(K2K&WeKhO{P$5V<)X{&`Cc2p0b&H~#xJ zYL_T5noH5Itr(7>=)brmWdI0!GcpCV}c@2k6F_ZlX0sQ01Ln{&gc>afCP%-hZApVck z?0)K{xfSNlTkiqp|7x+ON}xenjrgY;{_6>8FuJ(d{O_QEf0v62_Va(~bH5IF&ffZ= zX4iyf?);Bk#%DqQf>7o2X`+O#gma`=LjAcIe3*l3;^2i@9-Sf{0 zUOnwK>v{5j0(Ur&efWS(MK1sH_{aR;X5{}HAH81pwXx9}OAUxZ@elVOPN&lgU%HCc z`+#JPkj&vD9=GE^t~MLzkH5Sd{?n0?nQNSCQ7VxC5&uuX0RZxU3R7 z27sUOktdpy7i>;%v8;ha3GV$|A=)d1h=dWDHnjJr->ZD`&YiD*pJNuIqTT-sf>Z|Gpw?Kz zzX9(1uqP(|-}Zkn?77rBXLs3Li=1fg-8UhfJsTOzb^|1p8~8>Get&oDqs!G3yKMU( zz<*jZn9hTLMNYu}-yV?F4>teW@gGwkH}JoHi|=TyYx)sO4TwVVpV07+UphqHQWpN1 z`1$j{)d0T6#N*FBzWkDhUf2C3<_jFsLC*Ui2qmrczW&0 z{YOqO)|o`zA%XU~T@vke0YqV13xbQC+k2DR{l8XzVuh>@TKE47W|yeAq5gx*ujeE4+m!d0#%cmC(Z3awblY#xQ-meD=?n_6CG++=^T~5kVCLnWXOznoXFujWu=zjD zH)U#S7$>mx7y(&zz<=h4=Wp#X@84lBs-6Fx-#T|{*U^r5%yxViivOf`JQ7${hUTK? z{97#`z2^+A9WQ^4JO49AZiBSEAYq)p@&29RgLP-=qm>ig|2TUaj&i8x*#9wU0r!9R M_f@vtYP!GS|Jf;%^#A|> literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/INTL.HOCKEY b/res/TITLE.HGR.UNPACKED/INTL.HOCKEY new file mode 100644 index 0000000000000000000000000000000000000000..da8dd0b303b98092c44302a3646a180debd8d6a7 GIT binary patch literal 8192 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 TsQ)wnj;!>9`roBOQqcYb&PMp( literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/KARATE.CHAMP b/res/TITLE.HGR.UNPACKED/KARATE.CHAMP new file mode 100644 index 0000000000000000000000000000000000000000..3220abd8971cd0181224151a8a151e41f1f5c684 GIT binary patch literal 8192 zcmb_h&u`l{6yBds3lU)G6c^^sng$mNH78iHUIMJK3;R&@Fgp|D%|(#YfK@@UQ&1p7 z>V1zQWs0UGr)z{*(&OX%9)Em%kCYVhIaj(A(}~=QpRHPtvfQ{f7!%n?aW8(b^cp(i zEc}fLP_z%sk1BVTx%+k zRjYwr%ijqZ`AgcR^F-F8NLt32t`T$i+n85Ip?QxnPO`YEt2ayOEnTLgcoi(taS{$k z@j6-$7myFqb-Ko=7Q?x!gSkmW&f7iqmGCqa(}&$%HBXgBxx3#yJ~;ft&{zC70lJD=BO{ytmX`;X zS6HWx<$sr*fW`9W6~ERx0ZTJk9`K*}_>X1NxZi00z98;ptE~6^fHywJxicHrRub=iZdJ=jO zYfAgx!2fEV8u|+G?_zWLS-8DT zlp+3`?(0BkqSx_1s^q4krIi;|N??k7cgj;<=cO>~mQTkk8>CX@T^9c-_T(BLYZLOC zE?!qwiT|7H2l3wW+lyz)DX;ZiM(8VRm+_S5DcrXC@0tG`=CiY`&OZ+=I`}d5OaJOy z^WUtSwEpZq@868s-aFa=ow|2|87!6gOOp?@)%WrL;_i*R{!x1s|0jnnHVl;@l5*2wgI%73i$#6$ioFAyWOH%Nt! z=fC&{{MWd~XY{L@SLPje%KwW){+A*I|6BK!j@{ZG;y?2LRXmR>jqmiIX+NSS_&@2H zNu13Pr?*>yP~CDl@z-dD@hHX|gBR7DbMPr&2LJQi=(pS{Y(0zrEp~*1-_{yO&V}^w z|MuJ$|FX0Dj&<6>KbHRiQg+(5?EPwu|4%!gSEfH4d>XZFdH1q!{FR@^hQ61ZM@OQ( z>*jwGpRx*!e_6Fl$N$t9|3jDmSGPzT?!IiU4){+_>3&)!vt%TY|1%lQA}VO&)4KW` z{wM!C{yX^S*I(h5y{~EEKb`Af2juJV=g1s<25ug~|Bw}>kk?z$-u`$#JjMR|1ivBv zXV`zM6Nh+)9XQqirgi~t{{w#-VqWJxZBYEbd=S6)=;?89*K*q5tG~B24cRLHrG5wh zyyst~nA~@alY@UW|3h(cB>#!ZMQeXL_!R$d& z`M=pVoAKJm|4SeLD|_`=nOe9z?T=2t|BqI=uMWv@Y(%%dJV~ikCvBCb0jvKMN)w+W z{~=1%c@1>@{0H|bPkuK4d+-r|C35<+p7CGC$UWpu$Gn!q#c-4q*tv|8Wi%4&Xg*Xu z5HHd-mEc5`-ka^0<~XizUr}#ct6u&3Uk6|Lbd0s4ioZwkziXX#@B@l~ldN|KfO9&^ zlf>TNw)l^65^|NdwaLZD{-0EP#vfiLV7#pbd`O)04>E=G_p+TQO?>RktIq-CG~#r1 z{&yJvaju$5`AS}!^LNevyK{g1xB1lUi6*|Jew}VOoVvqW z6JPZ!s@gTY{8tu_`TDWL*&I5CM+;{#NgQ z!gz-B_W`m$PnkWcGv*1tfAsyWeVz^%=_pz2_`gcl(Ma)sP5D1Njf>$(`QhSg S{@c7lOgZ2c&JeyW|NjH*df$cs literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/ONE.ON.ONE b/res/TITLE.HGR.UNPACKED/ONE.ON.ONE new file mode 100644 index 0000000000000000000000000000000000000000..a29809b8c64e237c1e6d55c5b770b0e6cf59d730 GIT binary patch literal 8192 zcmcgxUuYCZ82`-0Bqzb7k{5~H6}=wzo|J`ZNy#m(MtuoEDwINL3k5-nQ1V)uxp*=0 z{FAdyz+hUp{;6kP8Y&6V#`FsItq&*UO8O!x_90L9`qa~k_M6?Ce|xj{C#Rje-TmhK zzM0?5?)<))+0D=7OFwYa#(@}Y^u*Gc+7(5$j0yXIkW&OExF;z-ND!Wr1ypCRCC3Oj zsI~EbB(@2lO}LOm@(Q)po=kWPvg1Xpc$gJBb7yXZ$?6sH7ba389N)9b_y9yLQde#g zAd>*dr2wMMx{?H|_kM2w(*R>i|21XAeT9tQ+}r#%G#x$^4#U<+rvRKl{N6|e;yYrm zzZN+l^-r$A21w^petaUkP`MI5AW-F$3pU%aqp?4KeK&R#hk!^#h@K?jug&1i^{1p? zA@Yt8gCr7U;Ccx^v&6OkpCItb*Q=AHAz&Q;-p}!>Dd+#=`A6T^1u^8N4uEAITk=ny zAdoKIygy9&pSyA$tu`L-A8%5|fBpRT@P{@?{7>JR9MPczDE+7SZj$&x0B_LxQ+6g# zqY&l4xmi~YyZ;1@HuA4Q{zsepq3PhEP2ue2ZJql#Amx8_TLgCYZaExzsr)aCNW2Xt zL5yC%#mzr`?pG7PLaJeHNyGmN5vFQ%@?+`p5`Jdd=djxf8I}QY(=zrLVC*p=WSFJ} zCZ55dnm8U{_=?q)75L<~bAi-V*6;i{@f1g3;TC-7S<3l;ZvN6$f2oRjI{%X7d3pYa z#W~G$qP3h(4CkDYRC@RtW^6n({GV}9UwfkKkJZrv0`jMwTbLZxSMaj=UqW5sP4PG5 z1@pg!&i@AvwTJE9U7a=uoBjr%r3?ALqbVGT^hxoJyP$yn>HN%TCH`u{pBR6TA#!;t zI{^=x`vnAIX1{ogN$g6Pz^)Sh+Vhi4D_sL`c7@0w6|W`=e6se)H#;Ez+bs)1mPId? zCsN7Fq9%j~Sk*8B>?BKMUOB(7-X{UBwW+60&f*B1J;nInH4xjrK`DBBsZRcT^RKC_ z6Bp-n&k1pm|Jh`6Oz{7`f@VB#(&ix#8b^)L-5^47MzhCMfcR|5M z`eNu-?!Tt{V*G3P4^{YGEj|=~l3PS&;#WxcYcslW6^K!#ZGNDDyuc^LzY}WnT>gh# z{_jPm?{z}~<9`T=?`qe@|DmDy=N&eZQ{dlRaen?Xpp~_$r~aMA5m>nO*A4Wi`>%~~ zRNa65v99_5{IndW;O<<&{CgVL|CIlH{ogqMP1p{FM1c+rHWwupCeJ`rcSmaFKYL43 z>56-O7~&w!TtZ=a*frUMveK3D?w5Yv{M+FAf2h}NJ=lHhgTaqKJF!o!|BH)=f1>}L z!8Z=R+CTVdYgsc~g^lMt-BBy?fw(s5B*veP|B_WI!$lsGxkeQV{uOm){*USSFEK=^ zyc)LR9Gnq7B*kYs{u_Wx{`MZ^e-GuqX`-SXHvyFYJtiLO;y=z`Awm$3cHFS{Twvf%t0CduCfyEnT_(lk5xgG z8UF!>KWf^^%>2sm32N-d_y73*K$n)rg*I???DqfJ^9K2!6-YX1Sf`Y9h09XL6^UQL z$3MW@KP<#6PU6k4tk!E~kJ@B`Po|3_L@Bg~uK#yKr~?=LJrJks|9D47JFfpbEWl{c z!1~`E*B^ysUXhE1^6;p%r&{Lm6i(DQ|3AEep0@AzkV;{ES z{JUYZ@x_}=3zYvYMt^8$TT^(yb)uCU+~`Ad1P{A${)>B#^+|~cIhcVqI=TCArTcT{_y667 z*#CETQ~q~T@;AbNx~?VUq%{8nDX#d|AHL=&eHtZ7*3Dq?W#?XsfB({bf2;HTTWS8~ z>_ePP;P*Ft|4+ZaiTD3y^FQ`k)9&(~a1GrjVH@xR1b`bkmI3)+0M|N$Y`|rfL$d&`Fgv;1pWt3jMPB>duU4f6j#`QD;w literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/POOL b/res/TITLE.HGR.UNPACKED/POOL new file mode 100644 index 0000000..3f866f4 --- /dev/null +++ b/res/TITLE.HGR.UNPACKED/POOL @@ -0,0 +1 @@ +ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€üùÿùƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ‡øÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿ‡øÿý*uŠ€€€Ó¶åøãÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©ÍŸö¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€ÓÆŸÓš¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‡øÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿ‡øÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü±å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€ü€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€€˜Õ׌€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿðÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿƒàÿý*uŠ€€€ÓžÕ°ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©½ê†ìÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€üý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŸüÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿþÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ü±åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ€àÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿý*uŠ€€€üùÿùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€€«¶êøãÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÿÏŸÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«ÆŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ*uŠ€€€Ó¶åÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ï¿€Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý*uŠ€€€€˜Õ‡¼ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ïŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý*uŠ€€€«ÞÊ°ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+U€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕ¼åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ÓÆŸÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï¿€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€ÿý*uŠ€€€ü±åöíÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý€€€€€€€€ï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý*uŠ€€€üÙÊùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿ¿€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€Ó¶åøƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©ÍŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý*uŠ€€€«¶å›ûÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€€ØÊ×¼ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€ÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ÓžÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©½å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÿÏŸÖŒ¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý*uŠ€€€«ÆŸó™¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€ü±êÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€àÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿÀÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€üùÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿŸüÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿþÿý*uŠ€€ÀÕ¼åÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©€››€¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€Ó¶êÓúÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿðÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿƒàÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€˜Õ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«žÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ \ No newline at end of file diff --git a/res/TITLE.HGR.UNPACKED/SHUFFLEBOARD b/res/TITLE.HGR.UNPACKED/SHUFFLEBOARD new file mode 100644 index 0000000000000000000000000000000000000000..6a502bccb9395e83fa528ef4b41b9815522e5280 GIT binary patch literal 8192 zcmeI1v2NQi5QZ=B&{Qy2X^G;`qxkWT6p<|*y()GR{$(M9-<;_10Oh)rjqvw_x2V@`XSF}pYt9rydT~za;~#D=CbO=p zBiNsZapj+=Kl*Yxk3V&bIooIZ9UIFDgXi=5t*PucJ+0#-&y`{Pt+%|LGq7K!9sDO~ zX9ImxJ5`~LS@1vo1^&t_9?`~yGDzt(3S@{&TU zzB0v{y{O~AvqB;37w{`z67YYf`Tqg_Yg(Sl{{Q^fboT10rOVL&(W}oUoBcYN9>JE#L+v#&9L>JrmFG5#a z^{aZ#xw{qq<;GPCMZY^jUzBmBch>&srSg6K|B2%N62W6#%Tw8JeO{t(7=LwbZ{r;F zRocu|l7901BOGi${^mIMURf5iKK`9PDE`_1>{{1Y`zh)GzmOFF&ar-faZNXT_3|`H zzl!i(#eX&bh<*m|KPVfQPM=f?j<{xvs>oNb{PWJwKPARRI_zRbK zVbJor))=p`{g&|;8{BdR`YQcP{+F(YuXX%c+Zm0)YEvOto(6oLzo`TNK|fEyKk$>p z>u*^GGYwJynyzs5abS-B%i0?Jywvm0H5AoK*xLUMghSEijQOkfA8>x1Le^jOMs!#5 zSMHl=R`Y%Q|D4zTk$?97deyPdz1^>WL(i;Cn56*q!UDZpto%Z{+)TQSv`d>Z&;Bu~3!s+yBA^x}I zUs_c|VJdyZTu$s~VfOxUX(=sQ!kw|CaHm zDr+^{q@4-)Pq+WBN3id)$e;NCi*bSY!}DkH|Hk!Pd^o@_@>lUM@BiTcaVDR2P#FE6 zWc|tbt?a+~_iuz9c-1#D{;~f48scw%O_ktCWv};dMR@aZnpqe#h6?1Rs+gNikD*#upL$Qp?*v+A)`D+D?Mg3FDb-CpKetnm=yle5udO zr2pU$-;pa}S70KbgoR*DO{{o{phn(w0vAuGkPucF6HJa;=Ax~yGft4>U}c;%64tqv zjI7u1@9kkBFC6XWdJvr}i!4n`-2vkdi?DT2)QyX(XX(OpsJMoUUtSS-e_>d8=>G9EQem%lL2FdLlfZo}W*L7v?7};}g{DQiK*J*SSrxuCi8_+?$$Mc*I<~udxuD zo`|xHKlsrZ+rAw6wI0#UF4$+VTebJ)1LX&*_C7BksKRgc-lKW@@tBtz4C}LZ)s&$q zbm!HU)b54(j_!_*@ynMmBB)p1tQ=hV@Tb`1w>186z}y9W zmfN4@_to30p4$F%SJig9mj6MMoVPzRULiHXq&C?8rlLfDPUhWD9PecV0|PN!W?}>Q zgzQ%<3cMHj7gN8Yo98@-Wf}c{E1X_H7=+JXj%7xDn%#f&pxx|Rg8$QuH{ijGW51s< zS4}BKcCOXO+LS1433cwD%4}rH3dHNwAZ}kSQT7$sZ$_PyJUI9hxO^Q;#uY2Bm3@M8 zVo(rH@Owq+=762@9e|5W!Y7 z9lWekTnR!G>u*(}9z_X+s7tCwjPchkQ=e6tZC_E8twIPtO3r>~-^IZ2i9knZXWtt) z3hX27ewWuR@SkGUb)qCn?qfZhDr}+6c5c~(eApcXH?7-F<@V}=*0{=DOKbd4E@y`(d zDJ_-B*yG=)tgPi<5nkK%np=8YdZzC0|6C9X{GV$-_>U-Of`$C|_b0XfbdG_?&3koT@hs(x!*{E|8a}|ux(%K?b?WcOib(eH|+UtPB$;S2ma+o-lBxIFyLQU z4G(nV%HvN{lujq?;{!2<44^%x=0`^@c^>Rr`Nxc*Qt4nh#H#irZ zJ)L;hw8nEzjfXMy%;RU`^1Llq`CmrZZcy^} z`%|UT%hZCA<);v~#abfaegs_mast z-dRNvnhZg(hnt0C>do_KVk4KsVJ(c1%J<(BVzRroh%M@Oe$zPptJ`e*$NWfe8-|M>jm>r>sTs*T(% zw4Zz8|Na|aCHb@YZ&0^^Lh@2LgV^w%!MLf{ZcV5At$B*M1fj*|-`B+3xd{G`yQSTv z|E}PM{Ga3eE3;TpP%)<7KYJEGHz&^Cr17UZZT=rG2LGiN|M0%Wf6_RU=YN;dH3GjB z=&$Se*5j4OAD8~J?y(=VpgzGaV9P3o?u+Ol=%rJ%{(nko{YeZlk3TMdyCvxFHaF>S z#bKtYrhW(d>&<+``S<1cuRiJU=SDS>TXpJP94_g4#=tvbzpoIovXJ(s&8{;Cy< zrUL!Xu-MT3rRzEUPx!y$`pXa~@~1ieE&X-u=icP|Z}e;2NPp0$dX)&~T9nwxe}}`E zf9B`s2Nq7l1F$cb2#C2KlLCN#sZ@|<=>La>{4d%1&ty%fsO&QJ<($Q`pKUqXT=w0g z5C4q7$=jb#e_wi$Y>q4gaLn-#WU=Da1@3mb=wRa-H}bi!sg2cuC-8LE8DM%(N(Y z$CPVe*600aav7GjEYgkjN5Jg#WKl8kKZ+ReDp_Gc0Y)G6<&+u1y)e>R@{$IxxLR+O66#oOU~)|`R~hKE3i!|2R~`|Rc442R|MMp=28U0)L;8R5;)%X*1-m%$kC`r&Xv;<| ze?NGQuaf-1QxeE8+Gp|qs;p)+%t$VP)|>x%%b$e(RT*C;sd|9_)*2D|%k}?zG@q@v z{}nb1T_?wS5l~c&shf#0>;Z0$eTxx@uTq`NRSEC7pLn7I?Rc&TYvnY&Z}ER!^QY2j zvJXcMh4kSE`2W4?A3W1sDg9mD=HtLE*;49!1i&IToK|L&4)@SNEiboh@O;Q>S+FAJ9b8j65ut991@m?E1{<2lN*P z8T&M1>;EinQL3JL>V-zv_HtaSUnp-X;E#<@anvrJ^Nrm7T(S6HN!qKDoHNL;ULhpQ zt{neGxB>t7coVS$QxcxkRcHNg=-7L$;lKXKkt5Bx?5JPM|Cj9X+8>gcp=DVifyF9M z+}5n2(*=dc6<-}V`fu@nkFWnnE_oKxSpVndU&g|b3%c1G>B5qUmxu}LWpmUFZl5nf7rV_M@vqRvGMzS3im88eMSlm~ zML5QtHhY8yO;GIVo`u6BH_uPqJWu-HhPlld|I>nkU8S_MA$;p<>gcGMB8>(AsX1^! za|$yu=WPCEVsNNkNx<9fQR-GW<8jmz(J<9@F}`rkHv?Y}nS zf5v|*__{UzR14K_72L#EN&am9MTz#`k_i5%F#lQnCqFoYoh1B(@T{{+}(9Stj#tj{j-ZpThjR z%K6`K4M?H>*ULNPS1OM;z0&ju2F3Aze*O#ku&pfMf57kmCao@X;>yRL@BYdpcZl@A z>!7+`tN;X#&m6TK!wb1(e0B-aCUp4G52HW3PNc*||-<2`^ z1%>=dyFYel4gWV-);P5R|8kyxYY5BBUFD6g^76(V{94Gr|Hpp?Lq;m-^WObD&ecwR zDVAn4Z%+@fnVEr^xAAYXUq%@ijkF)X6|D}6?0@y+-6W)|b{4<(=SdjRK{~i6W zf9}Y`E%o(BcI;on|A)8PuG&(3ft{OW3h~F-esNoiL15+!k1L*marno^68dlL|GhKm zh2$FkmlnH%?H6c0Z#lrz_Hk$b*-Z3C#^Z%+o$;q>=8#yC9mx#&ux|}<{!4pkCZgxe zt}KK{vG{ip&o=+>aQ>6YnO202$GnHd;~h1V$?w05gx+33DdKue`aewie~#R?y7apU_%Kt&P>gB(Yn=4;y z-qJ$(E@%85{!i;BJo!Oh|L5nCf(z3I*y5k>{#>;G-{#(g{eN)-!~XLY=Ra)o@9e)L z9YOHlMe_+9ShW}B`CR^Of7RY+^8Wt^m3NRC`f`G_hVTE45bNpo`@8+$e0}T_I=+?d>+3` z?|0XQXDI(Rz>{zT_=N0p`P14Da{iTe@E?v{eG7Et%B0WfKRY*QjuQVX6hKr;zJFwg zynD-$9lO`?e>x3oB1lUIXOUv%{2vk@l^H}DGKVqeg~t`oz&QM4V~PCBRJ83fi_Ohp z|F67Pp#QEA;1_gwj9ZsiZd@e(Q#Ufd?17h^@u&LtLvcquNc}8%1f&D7x5U2gIcQ|J9Iwe-Zri*3zX-IE?uscN?BNPx?PW z`rmJ?;UD9;8`-R;!P&+zV;KR2Az#jZYwavh!7}b(AB7mS*VQ)vD|?U2DP$?3u&~iS@zj6BS#6Qy_gJxHx)n^NjF_uV-CB{bMV=>ecU*+<5i1S~1kod2~ zDk%(m;Loc}M$xfTn$=Ehp~jo2otUS5G}^K{-Bn@h|G}5Or=y+g*8j#WAEx}JUPd!A zFB;FkIs0#tKbiBt&HWtsFAm9U@*2(_!2j3aKj9x=&hcMn22QNyUv7|pBEPcr$(Cch z?)CO(i2rs(oNb+9=i3SXJ12WA{<-{t|J?qc_#ZLvasJyTqitD#(20LJa!D`Xzp-lX zLsic=Zbt6C@c?r054rO8S7T9b5&S3FDTE{SUppmV#@?HXlYg@gAoBb}Hz@!9#)JIB z-AtZYn}3(f8_LU%Vg28@nbT_Goi#pl@J?rICd1!+$CM zTngmRh_t$)|AOwp0yG>$|MR6V|3383=ENHQY3VQ5A9?t(`ZfIjDg*xA=ysbv%RHpl zv>pfl^Gu^X$h1{GkAI$lDdfNU4C$j&M*lr`{sM{xA&ZPL0!GCx6c!KZ$)k6NM z{Rc#3+z_hSrMLeSzOR&isJ1I9%_49btvX5lXEH5o*-Vi0-yu+~u@Q6heiwA(-cr|~ zdJ^YPmi{7)wg`hAg5crz$o~(vBL9AI82j&2lZE>KAsuQ!^J|KF#u|E<{P0%12QM02 zg0(G9SBzOLr~k;nIQ%3139hd1sS&p+9g)Gxed24A;0oWdUOoXS2wH?~_*!1aA5-tp zlK~TksnGcwm0bRf%b&%+ef|diasIYM`it{7EoPs;(U+CER4)HcX%bm&7xMaFM*du9 zAN-Hqo${TeuUkdye-rul9RHU5eW#{KDy?wWip63v&fh5gc@Osg+B$z*&W*on2HJUN z?DIb~p%K439(%gQs(ZbC9E4n<^EcVVW{1VbN(6HL#6&m z@ndq?(H&(+U&Ec#|B);!s}NsB#-huI6Gq~HQymCk{fzsCI6$F#u^zy`9sV;o5uExh ztB9Gmr5@}uQF|54>Y}< znIXMeg;V(ww0|)2l^OI6a{j}ZHcVQk>vu-m2Yp(B{v!FV;-JYc>f8YG?;lUn{`-8W zK>xvi#yVG5HXnN8=ju5&=7M-7Nn=%B=CV}$a7#h+tovdc#K%79b=~X;LZ5VKS?*h+CxN)#G=iION zBstY#B+AjpefR6#bI*IKs;tsE$c{HWZse#&c$`Uv`~=T$`Qlw3jg!=*9LkFrHJHjJ zHSu^a|6xZ+hze@7gE~*NUsi*`6K)RsYEj=E7VG(Dv3@v|>k^V`S(Fs*ThUh)1OFQ` zg8@Se`@3~n&ripy+~TS#hi;$pus^TLEUv1oRUdz0Fbh%!QuD>rBPQMHx2AJ z4eeKqiU&j1bC@oxrdj%9OG|Z@VS~YRQplj;?7g_2z7;pqr@_!vc%ITsCi{#Z(c`S{ z>p8B~ews`l91e~3Y9ygxhBQYqEM&q&|l&mC6*#-N%wc2OGd3e}E)wNkP_swy8 zTsQTyzCZnF{wa=0h4hn_>_Z!?q;BvC`8N;4{w0sqzN&bh<@s+(4_%ocBzGAxTbwIY zl+?aXZwyKH*N>>{hts)vJVE>W2=&2flIV|z{dV5$e@oG{t_mxrn6eA?hmge;wLfvl zB>S1hf49QRUX)eq#>9THhrfqemztC-l_?CM9nF6v{IyI@TtVmW4pQ4A@xNZ4fdA9t zfU<85l@Wh*9~Iy1N&bSO5&sVO%kb|pUYW<*`gG< zxcd(t4M*P~F_}RgSC)sYPf@00ANWUYo0?y%aGHWR8NHn_hO3d>QKxjs2GA|5*`yH3 z8{ogXeJQTX)$NUrgQxWKp2H-T+9#?xcHs~+mR&HS(f1MDULqBi9}%T)Lw+Ek8tG7rOk$Yp+KvsFG%E&tMU zKAO8tb6B3F3;&8CqS%IxvYATwr_?$5*|RVB{{Z?G|1*fk3@qyZuIGpIXZUAkQ2{cq z;)B+fxucO$Cbw_1c`<(W9Y2U^^_uNS>033%FZ;CIXudL@?BRd(HU5uArfrJVy)MzS zq#5okuBb7X&qAg1bVN{BT+d`oKuIOh3@w(3zk`1m(?epC+>SN+m#drED<<;wYBGDj zx|uR9kqR;k4kqoUc)eQPQf7rKZH*I?q?A4h`$>ge`3fXnc$4P?*vGHp-&6_u;kNVt z^XR>J1O9JrSJP)zGV(m7nGE}~{%P?)6UoC-5EogpsW<2Up3|AEE=%MARDYfSHBp#Q zb>y@J{=oo-{~c1!7bnKA*-uM`s`SCKe52eK`CpPM;cLZWA#40EJ*Ql&eaWj81|pLI z_>r2EcOL&sX$5zZE_H$bx8(mh(0^tdeJB2@P6Ale`)b~tqak9NEq|)t4UPuW!+G;@ z_*43l+m^pb4IM(6v-?58PwG#4Maz9x1=aw`?Vw^&m77JiI6y4i@=B>(JmKH?H#(YX z&-kDCOY7f`ockhu?QGfu|N8dGwAo3fTFqX7y6>}aN?y7I{>u1N|84%CgsyCaaOMm7 z|J;E8zu!I)|Kh83cBDp6`bqr11OIQ+VZuM(Z&XIvH0gzyFP^mG3A^^dLp zyK|uSHxI!7aSQ&fmskP**wRlmANk*fBX5BdR;l^PJeh}|<^O$#6(TOpzSHUF5%{T&Yx~qvsWw#$p5cc3$*!P9p|87F*g36a3vtt#+E1A*U8Q7i-c!R_=@&Z zqxW1=F2}$6h#cVs`uY_AXl7VcvH!RAf8^<>{M-2cTg*FAU@IHt*!FZJFJK=f{WJbg znwT=H-_PThVCaIIHU8f$fd2*g7i)k;1uRNpPN7nI&wZDV<73OqC{m;e`)_iIr2a7-{${J?@p9v@wf30$-*no!;$^h%k66P?XTv3 z!o3Ce|HA)5KodHyN~K`N|GoI5{|NqFuNtu5Px(I@16G%NuK)Y|pH``|b%aLAK-6E$ zkhgK`zA|a|Y=@BA^85RFyvOMHJvbdb(T7GmOkuF>(I^RG0-u)k}6e`o8HgQ^tU z_5s&)C$NJ|qsbd>61b}wzq);&J>`Db`h)zd&%-{7qs9Le;gN=Wlcm1A*^Dw7rHocO z@>~opPgJhY!@lDG!uNO7ou0W?d?O3|YxXfmm{8=%`QL}7zd<^e_;=TUePsV1-`}hX zJOlk%RmXJyt@b5l_{no_*I-GB{t*uSfBdh>lkfkF`naCgJNXtjm;Bd6pRT_0Npt6= zN|_4Xe}{*W|8m3icN_nr&fFhPZT@Zl|G1qW7KZ;=qj>lZhh~5JAVPR{_}`{A*;lFj z7a8+1;p6m~q3rU%&n);~6!`ul(`HqQ4#@6D)dHH!_OpJHslYf?$YGB*n*RR{-{1TE zpYb#X;q|`pKQ}L5pyZj^hZ{xo^2Q6okUgZDF{4eI^3z&Hr@h5$8)#87A!u)JjF+lSl4(iiZa0$m~lY3cuApP10lT~k;Bd-aJnWv?D2xO1hhchh0 zxaU09eV?SV)V90hB_XSJ+iF>=uc}m^N_JaYE$obMwP-DhQ8h1vlC6D%#^poxt^2X4 z_&M7y9`Mt=a%~CDpF){~?fbM^vDC%dsyCh8Sk-3DK5ud~T3hg>Vatc=>Sj@$|9kNa zwEkmn@4W^*(_+C7cEy`hHO)q6KPy|{t4q5N`2S;@FT^+185Fu8x{CO&Cf%rk;5)e` z4Vx+$f#x0L&ezkZAAZPJ)qQ20^-o)eowemF{0=G%@Fyn~U3105`xQFRn=5LpzU@69 ze4u{$hkCHk~Z0@vGd;D4Jby)IRQ(Bfg5 z@}j;gyE?yA4JE<|M${nIPJ1lc zKW~JKKWI4_DnU&*Pl5lpe%{Y4cxY|;+G`rIJ{2E4@hqwHwdtc#K=1M zfqn}7e~DQ4k?$h0+a@zeEd+l)uM+-ehWyXEyxkY=i2q!WuHVsqg_TG?XFobmh#v&s z@gIxVbm{UAH)_~5U(W&m7Y|F0R=<3ya3z~iX7ayKUA6`ZUHrwlI~`dd(-i;x`m?C+ z{b;e@*##V}O!HQ^pgoS=#+H|D_Pg@m8}4i$*$)#tWRNc3SsWYi|1Wpsztzgky0gC* zFsh`U8QmN;_}*fF$Saw$HCDj2Kdf$wHw_k|z_tuRJ z{xuC&a8J}s`5)q*xsWBqe#H7zeE7+;q{-IWn$CWSZ)^80b41GjtH;IPRCQjxMy9z6 zS}^MzuY^1OD5JNzC(qK`Qj+6?a0u9Plr5TbRCET4~{1r5en?_+KPUUNu{d zDmMA*-BZZ_u$^nM`gukEBm1%(;3MxyZuEEibBQeuee2>c&fV$AauX6g4{Uz2I_Lgl zn*YFo-pxk%e^(%7bl|_+)d8Ox&BkZv6UEDk@kfS(`xcnkcJOfg$EKvVP>f51v;Vlr zRI}r~S^=SXR5fXnHV42bT zVi<8Del%Kr{x^QsFV)3Q#a?;Hy$f!aBr_t z_WdUQ!{W3g-f(eJVbavf<^K@-)ZwL4=QknyayFvqq#HZH!2#6tUmg<>Fko z8*u)j1M@xqzi7cf==}%qp9_%i|7R>i<@a~s|IV!o#HYr`OX`*5z2uJXE%r127Yezp zj}7UED;`PQFX9_nyV+8GR{kHVisdn=>DFn_f4Aoh-197OhWHabAoe3O%_tn#dX~Hi z{J#eK@%-=dzeE=Ow0sANKb}|TH+b_9p8)K#>NPmT=lcIEMKjuCzoGs8X!Nu8LA6ar z{#jsp+j0K0Qm@~J>`Q54Kj;5A|G5LjBQWer@q4^sMY93?ud@|){YKCqP+R}&y~0X$ z#nozLKNt0>qSeZ=R`VuD&G{l~Bh`DUm^>fLL6X=X_>UQM{0I3J`EQ!Sg8w?AgK3D#SQ;ewLug~xv)-Q&T#@F-zMY>v{btzAts1M?A2L0VEw65bCA)&ed$AY=H zAE)^L4IT(yRExL$ZkL!?KYQA8jt2gBU5=hKb&eC1WPHd?Mxh^`2h=6_hxdP2vE%wf z{=fW>^d0d3s0(%^lVbi!@kPq$s@Y=Hn)_uO^L=Q&~DkpF#H9EweUQLgR#Z8i9BfZ6k3G7INvSzUPk zzkDs|;hJRMA^-iO#fXM@kgs_Q_$mKhq#aXlI6aNJ!2a96e}BL@|3UtHRh`iemJ$Db z^YDz=bBO_V&EF@{GwP84opt;F@3xOu+yya`4&pC|5s3756&^s_jZxRgz!rwmx0;I0 zjcl-4vHxMgqHtpUCCSQeSJ(oeg{=!+Z_KLk3q!y^l$ZWWHA~y4>%O3F2Dv^KBBEGBL3kIzc`(anH^On)N!@}7Iak1e*^!NB8W_(3ICNsW&^ZW-= z@PdE;wGU&4{73jt6@;Hl0f@i({I`rI@;{ZhRPR^nd5bj}Q#G*P{m+Nas+Jef$bEPn zm+KnF(`-#qF&0kOA#TDPh^7!%M);0rrTc4_|G#+3&~|2unEHi7@e+!1hH zLV^F?HJtgAY literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/SUMMER.GAMES b/res/TITLE.HGR.UNPACKED/SUMMER.GAMES new file mode 100644 index 0000000000000000000000000000000000000000..553ae4d2c3ed5d50e10f618980d181a6bedccf85 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/TAG.TEAM b/res/TITLE.HGR.UNPACKED/TAG.TEAM new file mode 100644 index 0000000000000000000000000000000000000000..51d7cbabdd54cdfe786f2454e5b8097af8428a00 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/WORLD.KARATE b/res/TITLE.HGR.UNPACKED/WORLD.KARATE new file mode 100644 index 0000000000000000000000000000000000000000..0e0404a446bb8f985dec948de974d55e4821d9a2 GIT binary patch literal 8192 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 bhniUXmsmTouO8?q{xZCS6;8I22giQ_wa1Qr literal 0 HcmV?d00001 diff --git a/res/TITLE.HGR.UNPACKED/_FileInformation.txt b/res/TITLE.HGR.UNPACKED/_FileInformation.txt new file mode 100644 index 0000000..00a5107 --- /dev/null +++ b/res/TITLE.HGR.UNPACKED/_FileInformation.txt @@ -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) diff --git a/res/TITLE.HGR/AMER.CHALLENGE b/res/TITLE.HGR/AMER.CHALLENGE index 01bfe55a8eda93a03a81f54bd413779dc48aaa8d..766730eb362fd993c1c006e3136195b9cbba1ca3 100644 GIT binary patch delta 775 zcmYk4Jxc>Y5QaVV%*M})@r>~UyD0t!3;#k6Qd^xLorT2~f^!NQM9`f}Pxn0nlQ>NqY0v$Q)$|+K= zdzA*=34XOE-f!Crdt_P@Sio0MsW(VB6TUWlpqxDA-B8>{@V0XTK;TNjmqq~lfPGS2 zG^2XsuJ%K~u-n{kK|S8Zj1-N>-}=|%Lqw4IH>Nq!QN9snXNz*~xbk`_pAD5WNtj(> zZ}#tBO?3$RjW`aNn!o}bVlWNC(j0;r{vRD;C}i#eh?^W@h{gBf?^hPbVJRZ^uC|VT z2^bD*aV-(Y5h)fb?L}Z8+T9Ya)-c|qFPl5rwVXfil?9Rs}H5_ z2^czIu+XXJD+CGn8?)P)#GZeKi6A|w+ZpzCyJBcfr)b1+($oYN;8ePCK)_(e!tJK* OG4a?e#u;;#z=A)jC0Azv delta 1043 zcmZ9Ku}@l26vjo0eY8bOk+!H!H)CA7bnHO?18c(CPVNpJ*f>v;!eCPGxiNVTLSh;R zCkSf?8X1jsaVL^=ZsOwh{NBaGJ-$mAe);bA{oYF+eWL0?J(znqCbMo%w}bfM0PT8a z+r@+{mNNBO$n(Bu2_P-b>Hr{tn|m^yON0rZf_+}HrQFW!X)NV@nHTgbKwA8?9wZN! z97_NRoGwV|z&?jAuXTA}=4V<5kQP7J0YCz$dy&$CUEYXelYy?Fbp>DMMZF4;RbJ8o zKmwA*gRuB>%sU*^|(6(B8sqXU2hPWLvY z1N$7hiq=(pnOF2GKw7-21Aqihx0cd@CFgg#2#^3D{+ACSUF{tbon4=WL@nx$!@;oM zyK9bH6B`xi$&`ga+&Bj%G~e`HSf+HJ#hWN38P`E_H=Z;?Nmt8LUa N%a&Kan%!XbO81YWzq0@U diff --git a/res/TITLE.HGR/AUTOBAHN b/res/TITLE.HGR/AUTOBAHN index 89bd2e64efde97aefd15bd76a68b67412ffa1aa3..f78e234cf9ecce976769ab6bb2323299afc10b7d 100644 GIT binary patch delta 411 zcmYL_y-or_6oq$2_Kz%VRs{KVfEYw5G}IQ5m>4@7Kte-p1>MF-nC+|(_B_A_N(*DM zFJNmdtZXdQSKt9a7Z&7Bb2G*HzI%9;pFRH)(zU6HEGy%UM8?AiUg?QgCiN0`=d@2G zUaAW>MaC{@@KFRiViX%@cw{CC*xpD z`UiA!Wzd*7ApgQkB6vz^{LV?vaK86@pYOHyEaPFy^;@eb@HKp?CwS&}MBDSsmAM9UU#r8XX!M zbC{~@7$y{S#Tbsl+pfZ!9j>7vR&gBJ#io#UJ?x0-Nmb;PQ~WFxVYAos098%2wLFaY zl5?w8IcWy$nd;H{9MrL+r#!yZEeu5kS6URdDx(s=_f2TR^mnooXB-(M8{XIy8=HJ% zu^hqT#JCNzTVA_kNO9LJDM*5 diff --git a/res/TITLE.HGR/BASEBALL b/res/TITLE.HGR/BASEBALL index 4560b70aa91c57a6203a1261cad366eb7eced32f..7a019f6a8d622ca418aeb2dc7bf94dc36a15fa8b 100644 GIT binary patch delta 646 zcmYk2J4*vW5XX1#@>t^|8Wp2KEd3Iq`2;>bfu*hGYD{)~q1b3Hg4P;^FNXJ%;X|-gru&$D;aj_wUMyXYjzpfCo z1Ps|JvC2?DXFZlR94iElR#n?R2k5TFpDk1v30zGu6?HGGwkW4*ICXAXK7kLm`t{brlvdxh!`u6cJtkoAmggND z?p70o07vo;0GW}dgzNlhPSU&+mlnsg+7&`TdA~@&aK>V*0!2*gsHe{;pU!oSjtA|3 p-gtWqjoZe}p53hCgjV*{_dvkV`L#?}6J+u{{Wk+rrpZi#gg--vH!J`E delta 1019 zcmY+Dzi-n(6vxkToH%I{r;ekhaS>xC{s1HdY3HiIU%&!lLMpJhi1e;NXhjCdJ#|1V zRV$(Bq>7;vQbm`-f{@G)FNmsQU~Lc#MbKidPS5u^%X;tYd+&4KvwiFwYdr}dG%aXP zmV4bBNqXejU>Ub+=T?MBR}<7-7tY0CXPKxqYZ4dp)0trb6|ekAe(=EW*7wMDF$&ZM-4)p zxjeZ`NZ`m@?&N&yG?|lefshuJ<9Z~L>k;`RSUAi@v=NB~`cbJguIwMZ+8Zp9wC+XH z`*|a+h=lr=DZNN%g5xFdxZq$#-^^1wH1KT@-|v6zFrrY;>6JZ|ClTH^n$t|-clwL{ zr~l1M&X;ZcWc9)N>*a+0V>kY}|9ERV6e}T2WjuIij>A>I3KhF>cDQ~dIugxxmV0aR zz8A72uE}R=K8c6BgM+PumrG(X5-{af;Zi0mk6sS0`K~;TIk&D1GD7~CZ{uh2KU`!^ AFaQ7m diff --git a/res/TITLE.HGR/BLACK.BELT b/res/TITLE.HGR/BLACK.BELT index 539c20b74cf1bb0d0cc9f6d5ad85157e013f8c00..08c1a6911887c4c58480b607886f9c241442acf9 100644 GIT binary patch delta 255 zcmZp0Xt3Gvn{l$V824s2rV>Whg8IsO`-zMalczJM0Y$|p3MfoAVR2>pe|&N^OZ{XS zKAz2Nti>#oC7F3Qw{ey*vZ?VhFnH91bVzU~a4<3eK|@2sKPk0305(()$=njBmhm2nmkJ=j)NU!0z<l^+e3RKE rzp&K+jb%`n$S6HoS}K-Nbn+bug~>CeQYK3aiBFc~)m~R+<-^}i)Ew%mhlhNcPGTURFM@$lTR)k2dW6j>tJ*PzMRDlU8{$Gt~|qh`&!U|6)OoEXLnE%WjI05O7O5C8xG diff --git a/res/TITLE.HGR/BOP.N.WRESTLE b/res/TITLE.HGR/BOP.N.WRESTLE index 4154365d83ac0000c66a0f27aa39b6e45ec911a5..2179aefe955758eab6ab9673bed52c9ad62c8ed7 100644 GIT binary patch delta 749 zcmYk4O>fgc5QdlX5mUa>mhX=XH~0-m6p258M8!{G%Yhv`F*S))k{zm?5N;%-bSsr! zxR67QGm+6FDEOV3yof0W9J-Ntr4LKXug*99z*Lz4lRfiT zsXpl=NQCce!U-HEK#%g8DWi`{OW}KPb0=m3tQpsR`rY}Uk4dZhX6j=%UD{v*Z0EnJ zHKR*NtYif-0XBzdwUw-D3yGOQTpuK81qf=hwXXPL>*LaL)5PsVkqHo)7$N2uEvyr~ zU_d~_A=mGBp6e6RG7Fv0LNt6P06A6RdcApl60Jhd7D9BG0Q-fHVXRL<9P5}%lRYND zN}9y=H2I}Z=L6Q8?S~1(0XzG9svZ7R`V7S1=GJEeCO};*1zj(3by=2{TcYN7Y*yuI z%ZFIucI@w>^O$LDy5xAa9d;r;4zqo;YUY$;8kePK3wN)VMU}JhM#Q6iucYX;MLp@L6Au$0=RKePm(wCukXVjR=4aaEbx92>`l;0)Q@~ z0H7-<0O%?T0J??(fUctepc^OvXb#0(o~M7ezwS%F)Y>ga-N4qupzy1!Z7g*RZ$EtH zN#*{=a-A@GHmiA^mh(-12jm#dA(p*-jx@rKKP zj~ejbCk-q+W!7?RGc-2ptYkGcW~ppR`SfMFscCN0muFU6&bTMrm4mY zdeL%3g(dahy5^3p3LnP(J-gnkHe8Yae{8<)_jtX*T{9kCL0Tf&VMot?#PREfV}Adl zAdcf+kX(^^9pRa5a3=+IG?nhwgQ~bs?K%*SLiVeMOhw17ItX;^K^@;T zl}2eY6@i(U{W6j76b?BRqdO=tw`P}VjjqF{TMh)^^exp)>~Y^^+zcM~?`1X$yc>rM z@|=85-Ff^03Jw8^=<5ysu;%ZL4!cbUq1x`3bV!-Erigk@!#fb-tw9#vYlk6_#bIFx zWJv|ye@I2BwhwyY>n_K*58V?7!fE^gWF-o0>OdGY|M^}!5bFQ<AF?39P_i>Rs;yJAix3(0xYs1z!D1r zEVCfM3JU@RSrA~A1pz`V2oPpLfHf8bh_E2QItv19upq!D3j%DhAiy>Y0z_F5V21?( zc3BW$j|BntSrFiW1p#6#2oPsM0E-0y5-bRiWRc9I%nz<*jpXWUeL0f6FwrITtM$9q zC2c1|iL*j&ocrmvE1$LTu&!iv^zhM({_6P82i<#|df6F0Y&^@?sGpnHka*$e=D0sw CZ5ONn diff --git a/res/TITLE.HGR/CHAMP.WRESTLE b/res/TITLE.HGR/CHAMP.WRESTLE index 18ff44b160f4205e2530e0de67308427cb971c9b..adb7b911395fd8b4d055e33beda43637f76acd49 100644 GIT binary patch delta 744 zcmYk3O=}ZT6o!+SG}ri*XsY!K18yYv16;VsqWu9~_+Ktvy_qzzj48I~CSXxvaN{t6 zQV8NAV58EF7??nYF6_|hLaiD{MM`$+xs$f$-pzSn&OOh02PNEHk-{s^6>^zDW)%xl zRl93cZHi0b+OFL&8&F_qSXI-t%AkZ4CDSYB?YW`?L+~Z^TU(n0Iw6JgYkkK=;3+V4 z{=7Q)_Br$^DaD7;*YB;-y05^{x{v5kN(#7+r>_D-R5pzgO-Ui9fu9c%C@^f+>Zky9 zN^{4?xLbi?zL+b-ZzU5Xq)5fKB6S4@z(s>Eoz&|6NL@ig=AO0Uqy%N8us%Nb9z??# z#vVbBPHFY9zd!oXQ(*YL9r~S@L!VAdaWi!^oB^;ScRHiHpLxbAI4cJ2t`D8nAB~T~ z1kgDtUS~>)SS%S=U|7WBl4~>_%JR>!n(*M63R#)qlqGyiLa z8L6xrf-ZC5o-=URT7kjrFL8Xv4qefv9RDcf6(Sfe1BF?-D#h(XYXt`VypEi%Nnsq% OWf1dYqU)1$C*U6k$Ypx~ delta 1243 zcmZXSO=}ZT6ow};X~yv@(bSJ>A>c-WKfr~HEZQH?g2fK6mbY4>NR^a%*{63dTAu zPK`>AOjfG|z)=(cd%y_$&$lK8FH; z&!Yg~3n&0Mi6WU#1RtjQFS!`jl$vbfi<7!a0DK7r0H;v^@H7elzKjBZub=?nt0(~Y z8VUfOK>@(mQ2_7_6aYMnVm7}t{=4n$d?uyz6iF%>EwyBH#H?vGs_7-IqZcTr+1a!) zpLM@`PGe`gXa3#X)5x{0<2Oe?zj@9l|HrR}zv(m{(r9!{JDhbjCr=aoc}(thxk5#v z3T+LyJ)m)bg={JlxfP4XrJZ2_q7I4cMS$)wKux))ubFXK|MJp)6dvuitz)ly;QwwP z?s|^(y6@bK2LZ?kcD=CG_3Hh^OxWvNB^Q;XSY(-&S2}9lwDmgKWNWrjFk5CplClvw zor%lj?ynkM(M3-jRe$GLN8bK{=+*MQ=Tpd)3q+#Va=G=n z|77cHrRb68%I6yOi5BSE$iZHQv}euE20;5&+KIm2r&XE^R94HnP3IqHH$*Np4 diff --git a/res/TITLE.HGR/CMPTR.FOOSBALL b/res/TITLE.HGR/CMPTR.FOOSBALL index 2433cb5f913f040fe90274bbc364eae055b6f04d..47b8a74c148a1d065ed074fd1a1156c29eac7ac3 100644 GIT binary patch delta 370 zcmXw#Jx>Bb5QcA;V{bg+6y+l-;$>q{OpFPMoiUV_hbDgfi!1jqm)n2^g~jD2)Ldc# zolz2N3V#5F4gW+!ME4+0HB-#zCYja3EJ$6@>wqhul_V~KP2Lkyf59nwc17IZpBf33ZA9GebG zsyOD1eJ1!m2J9T4%`#5bUx|w{GiR|>bOW2^Dh{&E6<;|bOMo(IhoG4#Ex~jEuGev4 zwUo|d4=T+m{%*9`S3>T+1e;`aSk6iE2t$XHOH!3&#H(p;w4?rt-u}nv PY}X-pWY$K*y?goxd6IG1 delta 516 zcmY*WKTE?<5PwPY=QT+ajkTd^)sTvaBGJxL>moP^6`_dWH|PgQi;}1vIyfY`(WT&E zx1ycgoShUWzeB-Mq+oq%LmCeryyNco=kDBHx9ZtYOJQ&s=CM7ZU@Tp2)G1&?r=%~5y!(56Od!4ym@AFgi6E)2LoZXC$;q*t+~B6B;8$+N4dBui^p)4B zcJItlA>q9Jzr#|G{384}cKoW}AN33I7(xGl3i=<2hv2Dr^HS(VN~c2EH$h`aBX-}hHnE4q zEkfBt3u2sJkKkn|J+MWYZh{x)ezXIb`r=AC7q{msx#x;`bv;MmB} z;F$lmNm4wxGBJF|xa;R0DJHHNhT$I_Rs`@SF%jThQd}POUKklt1h_SD<08fLE#57~ zd)n0ZjmIHHfUkBrv=VZ|yhjSxqVLPOrK%!8y8PO$ud~g)Xhgo*h56}4MZM#FLE9lp zt?*tcJ}0u_hZHL-0<8VZIuX-yxKE16wB~qICw}1}y7*I50dQg$dP<)hxmV#IUWoryojuwxd4z_jgSZpcH!cBR3PO@j2A1Qwx)g q`YS~M9n929dFY;R>sAmpthOK)*K2&iOFe(Dneb8vcqiu*R{aOrjA`)z delta 1210 zcmY+D&1(}u7>B7^lWITws2|l<#N!J32UO7iKs*Fbtv4@1FH%~CvXe#AC0#N5*4o4# z5;q884>7t3LWGUDNks!y=z^eYQx6+YAy70egp8ZCNq+7y@ILdv{N^2I*%fvzGV9mv z-J!B>O+DRukpa*?6acgz1ppmD0YJSddhhx6&Orxp9e{i&0LYI5fcj7X&><86bQlEy z^`iiw0Tci_?&=C{>bQA>u9YX;?$58;#FbV)VfdYU|q5z;%C;;d*3IG~G z0YGO^0MJjTl&)-qxQoJ?{nDsW%o=wdSAV7Gp*u6J-g;w#s@iY3XV*FUO2dUb|r-&>3p~z+%GZ zpHym<%~dY_e8}RO^|#_=y~w@!=ySXnudYOXh3jeA4jVZhSKO2r==Il(4Aq}IlGQL9 zMV>6k>TB!&$V&mCM}0Lqc|IU`cd2@Ne<&LX#k-K~I)vsR2;Lle>0;sl_=j}%)DKXC0qCT5nB5PD1P7b diff --git a/res/TITLE.HGR/FORMULA.1.RACER b/res/TITLE.HGR/FORMULA.1.RACER index 89bdae2..3d5cf68 100644 --- a/res/TITLE.HGR/FORMULA.1.RACER +++ b/res/TITLE.HGR/FORMULA.1.RACER @@ -1 +1 @@ -€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ À€‚„€Õ¢Õˆ€ À€‘ „ˆÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€‘¢Ô À ÅˆÐ€€•¢Ä¨Ñ‚ԨѢĈ•ªÔ¨€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€€€€€€€€€ž€ø€àÇ€€¼€€àÇ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€ÐÚ®¯•€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€ ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ª€‚ĈтÁŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ €€€‚€€€…Š€¨€ Á‚€€”€€ Á‚€€€€ˆ€€À€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€ÐÚ®¯•€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€ ÕªÕ‚€€€Š”€Ð€À‚…€€¨€€À‚…€€€€¨ÕªÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯…€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€€Õø¿ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€ÀŸ¿þÌùóçÏ™¿€ÃŸ¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ ÔŠÕ¢À€Õ¢Õ¨•ªÅ€ÑªÔŠÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ø¿àÀçÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€‘ªÔ¨Ñ¢ÅˆÐ „€•¢Ô¨Ñ‚ԨѢĊ‘ª„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€ðÿÿÿƒ€€€ž€ø€àÇ€€¼€€àÇ€€€€üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€Ðâÿ©…€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€€Õ઀€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€À³æÌ™ÃáÀ™ŒàÙ³à€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€ À€¢À€ Àˆ€ À€‘ „ˆ€€€€€€€€€€€€€€€Š€ªÄ¨Ñ¢Åˆ•ŠÔ¨Ñ¢…€€ª€ªÄ¨Ñ¢ÅŠ€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€‘¢ À Àˆ¢Ä€¢Ä €„  Äˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ðÿÿÿƒ€€€…Š€¨€ Á‚€€”€€ Á‚€€€ ­˜°€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€Ð‚¿¨…€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€À³þ°øÃáÌŸŒ€ÃŸ¿ø€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€ªÔ¨Ñ¢ÅŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€Ð À€‚‘€ Àˆ€ Àˆ‘ „ˆ€€€€€€€€€€€€€€€ €ˆÔ  ÄŠ¢ˆÁ €€€ €‚Ĉ‘ „‚€€€€€€€€€€€€€€€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€•¢ À ÀŠÐ€€¢Ä €„  Åˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€€àÀÁ—€€€Š”€Ð€À‚…€€¨€€À‚…€€€ ­ÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€À³†°øÀáÌ™Œ€ƒ˜³à€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¢Äˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€¢ÅŠ¢À€Õ‚„€Õ¢À¨ ÀˆÑªÔŠ•€€€€€€€€€€€€€€€ˆ”ˆÔ Ð ÅŠ…¢¨Á €€¨”Š¨Ñ …‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€•ª À ÁŠ‚€ªÔ Ð‚” Ð¢ÅŠ‘¢„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€€øÿ×—€€€Àªø€àÃת•¼ÕªáƒÐŠ€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€ÀŸ¿†°˜óçÏ™Œà˜¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ”ªÔ¨‘€‚Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€¨À€‘€„€€¢Àˆ€ À¢‘ Ä€€€€€€€€€€€€€€€€‚€ˆÔ  Áˆ¢ˆÁ €€€ €‚Ĉ ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€•Š À Àˆ‚Á€¢” €‚„ €¢Äˆ‘¢„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€€€€€€€€€Š”€Ð€À‚…€€¨€€À‚…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯•€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€‚”ˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€ À€Á€„€€¢Àˆ€ À¢‘ „‚€€€€€€€€€€€€€€€ª€ªÄ Ð¢Äˆ•ŠÔˆÁ …€€ª€ªÄˆÐ¢„‚€€€€€€€€€€€€€€ \ No newline at end of file +€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ À€‚„€Õ¢Õˆ€ À€‘ „ˆÕ‚€€€€€€€€€€€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€‘¢Ô À ÅˆÐ€€•¢Ä¨Ñ‚ԨѢĈ•ªÔ¨€€€€€€”€¨ «Õ‚€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š”¨¨€À‚…€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€èªÕ€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€€€€€€€€€ž€ø€àÇ€€¼€€àÇ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€ÐÚ®¯•€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€ ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðúÿ¯€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€•€€€…࿨€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ª€‚ĈтÁŠ•ª€€€€€€€€€€€€€€€ ÁúÿŸÔÿ€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿ¡ø€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õþÿ«€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ €€€‚€€€…Š€¨€ Á‚€€”€€ Á‚€€€€ˆ€€À€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€ÐÚ®¯•€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”€ø Á‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¨ø€À‚…€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€¨€ €€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€ ÕªÕ‚€€€Š”€Ð€À‚…€€¨€€À‚…€€€€¨ÕªÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯…€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€€Õø¿ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€ÀŸ¿þÌùóçÏ™¿€ÃŸ¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ ÔŠÕ¢À€Õ¢Õ¨•ªÅ€ÑªÔŠÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ø¿àÀçÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€‘ªÔ¨Ñ¢ÅˆÐ „€•¢Ô¨Ñ‚ԨѢĊ‘ª„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€ðÿÿÿƒ€€€ž€ø€àÇ€€¼€€àÇ€€€€üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€Ðâÿ©…€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€€Õ઀€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€À³æÌ™ÃáÀ™ŒàÙ³à€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€ À€¢À€ Àˆ€ À€‘ „ˆ€€€€€€€€€€€€€€€Š€ªÄ¨Ñ¢Åˆ•ŠÔ¨Ñ¢…€€ª€ªÄ¨Ñ¢ÅŠ€€€€€€€êÿÿЀü‡€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€‘¢ À Àˆ¢Ä€¢Ä €„  Äˆ‘‚„ˆ€€€€€€…€”øÿ¿Áú€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿŸ”€Ð€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿë¿€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ðÿÿÿƒ€€€…Š€¨€ Á‚€€”€€ Á‚€€€ ­˜°€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€Ð‚¿¨…€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€À³þ°øÃáÌŸŒ€ÃŸ¿ø€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€ªÔ¨Ñ¢ÅŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€Ð À€‚‘€ Àˆ€ Àˆ‘ „ˆ€€€€€€€€€€€€€€€ €ˆÔ  ÄŠ¢ˆÁ €€€ €‚Ĉ‘ „‚€€€€€€€€€€€€€€€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€•¢ À ÀŠÐ€€¢Ä €„  Åˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚”ˆ‘€‚€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€€àÀÁ—€€€Š”€Ð€À‚…€€¨€€À‚…€€€ ­ÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€À³†°øÀáÌ™Œ€ƒ˜³à€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¢Äˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€¢ÅŠ¢À€Õ‚„€Õ¢À¨ ÀˆÑªÔŠ•€€€€€€€€€€€€€€€ˆ”ˆÔ Ð ÅŠ…¢¨Á €€¨”Š¨Ñ …‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€•ª À ÁŠ‚€ªÔ Ð‚” Ð¢ÅŠ‘¢„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€ À€Á€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€€øÿ×—€€€Àªø€àÃת•¼ÕªáƒÐŠ€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„€€¢Àˆ€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ À¢‘ „‚€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€ÀŸ¿†°˜óçÏ™Œà˜¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ”ªÔ¨‘€‚Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€¨À€‘€„€€¢Àˆ€ À¢‘ Ä€€€€€€€€€€€€€€€€‚€ˆÔ  Áˆ¢ˆÁ €€€ €‚Ĉ ‚€€€€€€€€€€€€€ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€•Š À Àˆ‚Á€¢” €‚„ €¢Äˆ‘¢„ˆ€€€€€€€ªÄ Ð¢Äˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€•ŠÔˆÁ …€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ª€ªÄˆÐ¢€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€€€€€€€€€Š”€Ð€À‚…€€¨€€À‚…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„‚€€€€€€ \ No newline at end of file diff --git a/res/TITLE.HGR/FS2 b/res/TITLE.HGR/FS2 index a39a6e93888c7cca80d7a0df3e54763604af7e6f..21864e3032558f8047bc36b834e69beaf9be490b 100644 GIT binary patch delta 756 zcmYjP&r2Io5Z-l@%|xR{O>JUry$Ib(3!z>;1iXf1Tm1v-C8z!Y4@+S-8-N-Yh^)o|W=TlH|w&IIre2^Gk#bm{^)iXG>0>fcdFJI=`eygbXAMPhHkFHDytb ztb6-ENRH~%j%ZLd?Z!8+<%WrPgchUI0KE#g9f(phs;e$y+g|B$boHLn*vGnjhd!u! z>D+FG8i`n^hNGXF$M~>G^NUxYFxCphMZmt%DbCCA5~%z^Xf3y?HqgCz1x^Gy5_j z^MHfXV4#b*VO!yVgA0n)D2FYE?nY|c-#_)n8!7_TTF?An{<dvSDD+q0CtJiq62&)V`dyR@S_9W`Jywg*{F#)D& zdpj?Y&GN&~q*!AQcX8Kf5vGLdnTW1Q=c#2NJTbc1un4aSc)oV%8{3^@XI#K))jY(5 zwRb(8@gf__O-WKB?OYcy`zRli(pg>$2HBFr8zNYRD#$&Hk^s4O8ay8k0uuSx>Y)#ScWRv%rsoW8~+wBRG54i@h>he2q%SH Zqu-O|Xvg|^{FCse0Pm!Ba@0I({sk-m7cl?; delta 1193 zcmZWn%}X0W6raszH%6nT8g-*-z4VZVmIiWc4gn9ngc=(E0KMdISXxS7vLRWh!e)n- z^isCg7MoLAVbALa(u0&p4G6geDtKwZ-YgW;nO&0^;w;O&-~0N#_vS$wGKM+=*9Qy! zM6K~;fK7q30S8PUZ}6#D6_Y!0aYgXcOjwX|xaE%z@_34%AFoJvIi){=8&Xd8$X%bD z{6HkICfviH5$39g zF!MHVF&P5~%qeDY>83ck>F1I=atzbVi!KFDM0lcz+JCgG$g@GU7-m?MIm=|1XO`oc zV>S#taH$lYN@1>Ml*t%4V9vi7Y|VV$M}~Se&zH5p#kmZzr{11IOcenCjg|Us-&P-9 z?;Ic`-pNK&g^Z9w*)@cSEN7!jL=p>WC0STn3@O<)5iiducy&ffZ`nt`E1FUNX*Vrz zBvuQ+0%#fQZqE7(YMX{q`X;%a@Wx+7FfHQ?Yu9+ddY#^ z<2P1WubISq#|jt8bzxXVntI#N2?EgTC3;o&etpB$<}2sY*`k;plKQ2uO{I&P>ul(| z8w7O^>t%8|P5b;@(+qq6Em-If4&b2Jv^7#V`7v~gXHeH)Z=N{Cz3%BoMLU7x&5tx2 zJqTqM5eg}()ocJMNt7&zWH{MqQVx+1DJgkU4i(ZO$~SOhZsAb{paKRVEn0}iUmvH} X>s9-JRHlDD{bP5kopz($=&Sz&ze4pI diff --git a/res/TITLE.HGR/FUJI.SPEED.WAY b/res/TITLE.HGR/FUJI.SPEED.WAY index 8463f596febf570522568ecf95798a4629d7fc7e..1fd8dcc73c8db442d7513d374e149e738d87e1c2 100644 GIT binary patch delta 254 zcmZp0Xt0@3F^P#|BBSxd&8}bugj=zQiD|L`6UQVLsPyE`EcoPgC$Hu3#-kr7&qF|7 TfPlOR0eJ}m@-is$K(_(_W5Pw! delta 186 zcmZp$X>gcOF;T#J;%3*00vTXrvG@lg($Hq=X1L2-axU%)6(v+8@-H61qU@q(vs=vym{0>19dhjU&= zM~phqjn?Xv2aE!Z)L$jIn?!9z2=b; z#e@A1pQ0#Z6o`_K)PELr>6lUdc;{REcGzSTSPDx)Db!_}bm~xhzGf7#*_U;Fg^t_k zkE-E}C#?j&=!RLH^ngxC^!r!rxMfCx@!sg75;1$r-fgEzw_&>8vEu!`C=qrjr;+5(yy`&sh>(AnaH zgC)CmkETaKHmpJ*j|)Ja)Rl(-^Aqx5VRY!6t4DJP7qMz4R}LP`aILvg9lH<}mYlpSN!w!xoZ-rLq+XbfQw| zp1G%cJ}dxm5Cs7Dq5$AN6aXAT0l@tz062^SfFmdXcmM?e5266zArt`o00jU)L;=9V zC;&K$0)R(Q0PrIe06dBUfFGj(;4u^cY@h((aTEYNfdYUhQ2_813IKkB0)VGc0Ps^3 z06c?Y#(L@h;6irR?y=o;sdN*FTI;`3=jHG}`n;o7d>?Doy?J$b);~*Wk@nMiPt)4- zJdwFb?Z`#_mU{QEc_u|FmWmnl?)3Xl+jedBgR6UXv0ATO*S|Ki2^mZWr3mRdDGXC= z%^M;qQm;+%Au1;g_fll6)j@+YZxKGe~dtZO_8{V@gNM9%nZ-7nk;rB#y0Z8aNz5EwwH{S5PySrai zPTf)4YUk*8{jaOD*=4U|yRY2PFRJ6}q*iRGhH{GbY0k^gwE4m-l%h59rgH9Iy1Db` H&H(=b&QcR8 diff --git a/res/TITLE.HGR/INTL.GRAN.PRIX b/res/TITLE.HGR/INTL.GRAN.PRIX index faf6a147563a17a7145a5a9b5236ecc18fe96c3b..68d9a737fe5ffc12835e225ea9eb4bc989b951b3 100644 GIT binary patch delta 615 zcmYk3(Msb$6o!*FZ6~!!qir*(ZoM?%<*uTj$RJyAA*`g}GpuU^3b`;)Va5w@ma;hc zU!>3%&^Ope+S5$24q@PgpYMG9ql7wtEwu0uv|D43|x{a4`2>ys#WT|E|RVsT(_%diz7k z6D-}a7G&8b%Rc7qjJ8@2k9Er`w+gyzlsd*@%kVnH^YGHiS8mmT%~Paa%*-fnpgd}Z zqwD{!b{Y#4w{?1)xwv)l(Kegy!(mODK zo&ofy_%~uu{q+ti#8?etmL#)To?OqM1_hhtMzRbyHc%nytigN@<^~*9X7t3EN7+Yv zL$ZtTI=o#yfxm0)b~ko=YslUemGn?;EWdoHQ5T;Fn@=zq9WeQ1)SyNt+M=fZ11fyP A)c^nh delta 998 zcmYk3ZA_C_6vz8K^yRd)Qn2(58;X-Yf=UqT+z5lw2t2`NmKrVFjIc-)$b#F9=5D_9 zZYff?GRnP@g)M5+ES+0yQ$Q04Zi{AdNCsnWBsB&DiK2X%Zpk(QBkZ#0!@M7E@;fKz z{?0!am*ZE%2p||x*%$5K^k4+q07PW{vN`&vyq?x`0`QH{KcmrIqa0UC2f1qKiY+BZ ziPc4T1deA>Ps8tfJrwirt6b(Pt9m6$(hwL5xzRmKrDir%Op|FMa8tQ8X0L3D$Ps*H zUa6UC;>Rdva3d1rDk}GRB%eZn=5yPcx{KZtB%h)hID50d7bWBRCu7 z*V~}@nIudXAxWKAJO<}MqD64KA%4BC@p=Kp43eKWRCFBsc&jAT39u#KeO3v$nc_?* zy{y{-d~nROM!cIx)*zTro(p{Imtj^FSkvk3Qm+s!VD3tiQDk9 zE1n{H1PR}*(|KijH^mHgrf2cmdDW~W%oHG^>Ls5ko-QyU```=8r~D`K5XnODZESo~ zpJsM~Vg|k^zK>#Fjh~HqsduddoQ2|HeeWv;l5wpFVME*DFIJ2t#DG9?X0XsYy!-*h z491#rltq&+yJXB3ptCDCe)V2gkm76vTu%7==`D9+#E4+=!Ij*Nk&uC620xEi{21oO zo=8TM1ERrsZ^piLRg%#p!oi|=)%5b^T4F|!SDQTfVZ!h=#S9+5p=-}2pE;ynDwT{m4!HQkz~*E}ctA4d zh~S2oHr)SvcOO~DV(H~`$4Vw2QOqFV3LWjJbe)onHUY$k?en4c23jb#Avo7EbaF;B z{E!%}bcr+4VqU@dX}jD+$N3lZN8E0=UnY}jUmNXjCBB<1{WfJ9E6DhsttRT_9dLAL zy(Ox;RKB`dk^lL_hL0aV;@-us=gO^>Sx?>w66j>1N1<6Phqf{uBQCg%}LQtj1 zN=a|D(pEgccDvUO^4MLK-=lpnv z|EUYrbZ~s?LFV{j?Nl$yLqvaG7y>P1$xWCgw4~KdABb)dGX%ace2K$2qGhe7_k&En zta-GhXr)Y)_zKW!Rj^=a&EA?J0IyMp=YrOY5o)gE$_N5YZyt@B482iCNv}XT^v_a| z@(R#qRj^=a%eol?-=7cU+BKsBv|S2PzODIeLD5dRC%qM*-9m6&iDgV7Z!ol17#Vxk zN&9xqr~n<5f>h>^n#=37H>N}RC(#~vJI^CV4p)JX2Ln3N%An^5lj}={0Q_zz_!Zzk DF+W8J delta 1059 zcmZ9~y-vbV7{>9UB8ZCkfug`H>7p0l0J{S*uz4Xk`L;zunnvNRBqcgjCS)pMHKB=- zi2)PXOH7=+05?TG+9#f-$@!n(=}DWE&L~|e1cmvik~e3cH`fV*mk=O$83BS<5Fpr( z0KuyW5F9{&;2=V<5SV|G{u8`%zfY$%Zx@HWxlRzgjsU?M2oSu90Ks7d2;M?~;0OW) zZzDkP4gv)4B0%sS0t819Ab1}Ef)5ZNIEDbhhX@dSgaE;D1PD$bKyVTvS-4*O;1ab) z)9XzgG$g^6hjedBDm87gxJpPz-%!s=EbZah?!7M$fbNjUZ7M)bRYOTSRw7RT_VT2 zRVH_bNV_BBi~4OtF*HSg@}I>1pGsmnL}HZmNc_BdnQ;I6YBsJv#KZct|M-+_vskuU gLz&cJqtYD6H?l-ElT2z!@~B)SsZo*NWm=s53shU@EdT%j diff --git a/res/TITLE.HGR/KARATE.CHAMP b/res/TITLE.HGR/KARATE.CHAMP index 3220abd8971cd0181224151a8a151e41f1f5c684..2f8a620d1807f7906d18698ca0e1b7ae60f4fff9 100644 GIT binary patch delta 593 zcmX|-yGq1B6o%Q0$>_St?8f`Ov=XtluoAWMMZ{zanQ{!o~vg)rpAPY&uW2ja$s$I4 z`^yCQ1S1deW$&?@_T(fZZ(Y&REr9DwG>G5$MI@&f$vOf*>mPVA&GSf3n1Zq)A%a`GL|tKuii<6`EC>zCs_OWL3s=a|whRt?YXvTAvv9hRizW;A4GevTbR^rFF+{VupU#4@N`;(2qJ3OPl0Yzpy8>2iJLC6Ig)G0Ud07vcwJJ#Al`^umCr0!2;Z}1sh`L zkPf#$SV7yyiqB0=U;)0c1q-ld3pVKUM9uoK6;wA?Y?zwB0^G3$3vkyKY{-K4?4Uhk z#eGu~?DM1fPGs9D)v3@&{P!f?!1?IId64L%zc5^VmW3M2sPpP=sA5Yz3u3qp;^4+l zvbT!?B5gF5LWFcus!?mLvNWWT^M-hJy&)I9$`cc*^ko=QXX|xACHFe6@xDC>y8g%? w1n2&(8~Y=-+fJ7@^7_FDI$qN5K9Z}vo9yz*YdWddR_E*W`t)=6W40tWnUT`UOaJZX8 z!3Pj@sSn_$4vuPVYgz{nob7z)Q;}+3Od%>}Co8jgPKb>e{NOfS$1eTA_r`A7Dvpd8 z2E9rGL!DMA(0;B@%?UsUV`G1@&?Bn}pspu2EMd3$54W5cpBoG#;CSmCz>EHJGJq?c zu2O&j-g`_JYi|aQYYdCpAywV-c4sMW)%T!}k9@PFJ-n$u*g}Lt2oj>&NNni}DTtIk zmRJD^rIapaEVTk510n>@S&B!2uM6*$n%N?#{KP!A2)V?mpHuaTs*%ufj!&GIj^NMA R?`TKqZ{7xauJCND{R@QnXIB6K delta 441 zcmY*UJ4?f06iu2oiD?>5+NRo?uc(WHf*K!CYLkwFKfuAkt%C}J4h2P1!A-$0M|Vfj zL1;IJfgf+y%3utC!c;Qd#h_y=OmB)*i$GV`@>QbJkuINYRsVkw>wok_m#FS@z zixXHDRTQE{Y^DaO8^&pLn!0jTEi*+MDzOhVwRR?}QSDK{oR|bPmV)Jfx_Ay1!Ny7a zf;wz>qD=F$AL+q+r;eO%z}02UBnMH}XK|VA$F-7xYA)i+>R|RYYCeP_ToCZO%4k>y zl=Lbs#6i;~Y>07R8VEi>A#;YCj9l$r=R<6G!`i}~r9d$!gk#nhl_5N7z32<+3>JS+ zM^cG{KjW5kg!8oNOQV5j&f7WM_F8B{96|`^*ebCJXWLm;+P2DN2`d>vY=?m(!O!Mq U5GxYL?f-jtZw;JhCWA|V0oyEroB#j- diff --git a/res/TITLE.HGR/POOL b/res/TITLE.HGR/POOL index 3f866f4..79701ff 100644 --- a/res/TITLE.HGR/POOL +++ b/res/TITLE.HGR/POOL @@ -1 +1 @@ -ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€üùÿùƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ‡øÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿ‡øÿý*uŠ€€€Ó¶åøãÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©ÍŸö¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€ÓÆŸÓš¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‡øÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿ‡øÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü±å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€ü€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€€˜Õ׌€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿðÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿƒàÿý*uŠ€€€ÓžÕ°ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©½ê†ìÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€üý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŸüÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿþÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ü±åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ€àÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿý*uŠ€€€üùÿùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€€«¶êøãÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÿÏŸÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«ÆŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ*uŠ€€€Ó¶åÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ï¿€Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý*uŠ€€€€˜Õ‡¼ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ïŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý*uŠ€€€«ÞÊ°ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+U€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕ¼åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ÓÆŸÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï¿€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€ÿý*uŠ€€€ü±åöíÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý€€€€€€€€ï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý*uŠ€€€üÙÊùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿ¿€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€Ó¶åøƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©ÍŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý*uŠ€€€«¶å›ûÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€€ØÊ×¼ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€ÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ÓžÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©½å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÿÏŸÖŒ¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý*uŠ€€€«ÆŸó™¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€ü±êÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€àÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿÀÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€üùÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿŸüÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿþÿý*uŠ€€ÀÕ¼åÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©€››€¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€Ó¶êÓúÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿðÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿƒàÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€˜Õ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«žÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ \ No newline at end of file +ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€üùÿùƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€ïÿ‡øÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿ‡øÿý*uŠ€€€Ó¶åøãÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©ÍŸö¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€ÓÆŸÓš¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‡øÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿ‡øÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü±å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€ü€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€€˜Õ׌€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€ïÿðÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿƒàÿý*uŠ€€€ÓžÕ°ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©½ê†ìÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€üý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŸüÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿþÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ü±åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ€àÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿý*uŠ€€€üùÿùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€€«¶êøãÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÿÏŸÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«ÆŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ*uŠ€€€Ó¶åÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€Ô+Uï¿€Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý*uŠ€€€€˜Õ‡¼ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ïŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý*uŠ€€€«ÞÊ°ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+U€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕ¼åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ÓÆŸÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï¿€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€ÿý*uŠ€€€ü±åöíÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý€€€€€€€€ï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý*uŠ€€€üÙÊùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿ¿€€ÿý€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€Ó¶åøƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ*uŠ€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©ÍŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý*uŠ€€€«¶å›ûÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€€ØÊ×¼ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€ÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ÓžÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«ž*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õ€€€€€€*uŠ€€À©½å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÿÏŸÖŒ¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý*uŠ€€€«ÆŸó™¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€ü±êÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€àÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿÀÿý*uŠ€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€üùÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿŸüÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿþÿý*uŠ€€ÀÕ¼åÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©€››€¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€Ó¶êÓúÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿðÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿƒàÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€˜Õ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€ \ No newline at end of file diff --git a/res/TITLE.HGR/SHUFFLEBOARD b/res/TITLE.HGR/SHUFFLEBOARD index 6a502bccb9395e83fa528ef4b41b9815522e5280..91341d8b52979accdfd530c5a79535bf32d972e3 100644 GIT binary patch delta 286 zcmZp0Xt0@3#rB|`;m`m7lLMJFCO3#{PrR(k*5A+Y;bY@OM!Cr{j4^Ee3}E>>#u}D} ztE(C(|6}~cuEoI6#LzTh@_(jE=0yx0ldG9)ISw>3fIuU}BzfJ*p)AWL7AtO+VZG19 ze4u>~P+V(r16W*{t^fc3{~#;WCokm)n><-gbh7|w1|!5=h6$7FxvCjECjaJYVQie- z!2Nq-vDW6LJi)AR`Tv3-`D!7c{3PMulf9XAK_+hw6gcOHMxog@G6yToR%vC;7fNL@fclG3Y zcD>1Kxz7QmwKgy131$U}GYM5p7U1NX+#*!X$S_IxH^`jL8X^~%CJJy&60e)6rZ;(w zcrZ{@bFzlSWmb@L7$!+pu!9*ur`1bV1659DlB%63z%sd6>c>O@)`=QAo7YH(Fj+A$ zJZNY5^Z$Q;Kf{NQjSLL^3?LpzYs1x5Kt2p;F)%bSG)-Vw#Lxj2I?y=Tip^8*K>Hq` up8x;+=uFBR3M_JB|ucT zVN7E_<~>@yYfU|G(T|2DKq>e|i<= z*fe75L z>jFfUDs{}xr`_mAq(p0$0J7i)#6LfyRq?JH-E9uIFy>zwz1G{$XSI5q^B=sJb>;xH XO@oJBPF|0v;gQ0&aBk-#OS@nT7onjO delta 1246 zcmYk6PiqrF7{)h^v9M}rwgeiW^S&kDcSHI=qaC1*57lsSnY5zTkRC}iq{ovOW9*?Iaw*C zuGfTUuBo@}+_Sd)-Yi%@WxZkt&k3P7yv!?4tt#i2#&F!a5j!j5i!<@X#{ql&0Bb#t zPnr*zKQC8ARJQfrNXlFgT;^RpXWI{I7=UwuZoN^?M@Ow^eIYKt`>j(AM!nPVIP50a zHH;*zi#Q4ljA7?o4wd}&G2w6R-~fS5Y)8yNTrv=d9|079Vt0B$@6Mku|H4#3t4&MMid z)QXjfqMj@vq3mY1kdQ)n-`T0-ljVDN-}k=vp7lL__l+W#XSPV4J=BUOc9Lh~A~k^` zIs4?SV+~-jk!2d?UI6Qc;s-&OZ-<08;sc6!xU@@EEee)EZ{0WR@|g)0&E%N~B|t@) znrptuL)HtxL~?N?Y%|sXzCA;GFN`^EJ|YW=vRF42--&uq5ptXMc_)bZ743T^LSR}7 zcLVNh62EUfB>UC6pJ+78i?f$&JKdFMz8N(I>y>J@FkPQ3&oLIDQ~;{B3cmApknllU zdL_EQGt*gg-BAsjLVd!k-KVI@&fJ&clyz6p^bAWBttz@azOe3x!~}pdzf4a>es=5 z&ubsCc#=u~kUGFTb(287WWT|C3GusRukP8Xb6{NopZjKI;8G^ffrI25^Nu6L2ypSS z^l1iH7c#5#GT5zS7%ILMjri^GF~{LLPa^W)t68JPH8Hpa7sO3IJL_ z0YHl=04Rq7fE*M6ln3G1ZmXH(i@fxMVo1~=>kuX}6dzhLyGl5M3Y zC8M8)!>ecQC#gR8J65V|ISkTaP|t&)!p9eW_g40zS|$5kbw7L^f@_Z_RS>{tJq)2dKM9ml6l^LECyuKC2P@w4r$ PO4T!U;r24<8`b>-b>I9L diff --git a/res/TITLE.HGR/SPDWAY.CLASSIC b/res/TITLE.HGR/SPDWAY.CLASSIC index ec6f4a65b04a510a7899b44b4accdb9f85ea1f45..95721570a7154c7e1bd76c77586e824766b0c1ec 100644 GIT binary patch delta 741 zcmYjPJx{|x3>BrcM=9ka<-6<^EX;@jIxl$n7W zBLo;b*V2m=-Ftbl{cImx!o`EFPx5c(1n4R{ea!oYnZXTVgiF@QF@$2w1VVUNB$>Mf ztXKmQ!WoNDv2-0ZsIq)ho_BKgqBH7NW9mmIG+j27S2gP-*B4hLkvz#%gJ(oPV9g7P z34};(#f)_?Xgqjr1rLEhiKfaVTO%wJ z5L^p|HCxkwNlus2M7J5!i!{;`oHxr6smiz>#smagq0pL*XyZm&*TJc$4O^S?`+ebj zh0Rzkx^ysb1e?|*-;T!&Q{0+m%ESxIiPql!FOd)kdCPy)6Jz8BKd;D^E9gaC>b7H< zonHh&TLokR_>B~+@JdvM+bsG_{smR qM4s2*$sHbw?XORz?*u{=mAB+bvG+%C6!g#ud+03e;qd|!1mq7XWY5R| delta 1000 zcmY+@KTpCy9L8}GR8;%}RZx+^k!YMv)Py%+9DOT{KkUGWJU2_@ii2;!q$Ios;t0$R z-q;xQ=apFcaJix1e(u^ETDg(NQ!~HvKf01$Ba>bmp};Bw1+okj$feMgbMur1-2L{u+2b$0s{qh7$~sIK!H653hXmbpvXXh5(5Q11_~T7 zP~eb(0%ZmYR2V35#6W>#1`3=oP@u{{fl~$w)EH{b%j6p$^=GQSs2gHK8O&!iR1G6P zuq_eC8kmN6aqrem;&sczZCKnG^;MT1tSyHfvF(AzQ*Ar2!{9yAP^@_=J=Bxcs_}b5 zndr0=S=D&9dp+yVtPa)PHfPy#&L8)G%(Zu0O18~U@6IQYDP}zLTrE^S^({Hi$M5KI P{QVW@)C{s$i@)p-w`%v3 diff --git a/res/TITLE.HGR/SUMMER.GAMES b/res/TITLE.HGR/SUMMER.GAMES index 553ae4d2c3ed5d50e10f618980d181a6bedccf85..d2a8176a5d5f3bde143e01fa4046c00d9a4c8c33 100644 GIT binary patch delta 713 zcmZXQ!A`+M#*?j^_XC9yjE=?bTCSEw2 zCiFo};9z4}XWLquxJ@(j?Z2}-^UDW$H{~qcDF4TGB3p76M1i%oVg)72m2yKb+@K^- z{_=AX1rZopaHwSIp(I$VbiocC$`;B3K)EPv!GqmxHA;fNa;R)`lm&olF3{ryVWeg; zwGNCkM+NHJihYy>OXYaFcc^jp<*$?zISOTsR|2)5n&}OW%U3wA&|hLG_c#+mn1Txd z`$z?CKG8OdUTW zVZNF<+VLjkmafr`H|br2!EtT`ja2|>6@?bBW}e!m5k8e^>PwpTgtNzFlFwz^e!Z+3H~cqU3R)g)^LKy?%Vw2A_N8Ylp04Fv$L zqX3`{6adsj0YIB50L(MCq($43wE{5j(UKPJNY)B~c2NM(9tr^S9{bXw1Ibze&>;!{ zIzjk8=G#4!7M)Ah3V<$908j@7fO*EHw8)aIm1WkG!F9VVm`~K?B`jJ+I@ZB=ss5K5`Is!b$+(u%S*!r`$4|$BmCt5 z=`3r+!P2cB$F-|m1ji|Yo?G1(GY94V)OqMTgJ*Z}R~U^Q_hmSIa>s5ldClfVzkYpH RZf2ZQo|%<-QtMTJ_Aip$**gFL diff --git a/res/TITLE.HGR/SUMMER.GAMES.II b/res/TITLE.HGR/SUMMER.GAMES.II index f73916cb827153b16dc2790b89090c51237fea12..ca772addd4ad37280a07c84843c5c8381ac35734 100644 GIT binary patch delta 608 zcmYk3F=!KE6vyv!&E1#t63^D7i3JhdzFtc%bnK9&E>@_}uR4YlcgGj2`Rg*FKlX-KlZmzFJJifH1e%DWf_6YWmPu7rmbsh-#nDZ* zsET?51Q#DzRaGZsVb4ddY0_B`?epCaZ(p4JA{>b~y_4ts;4%@1Wm)eCS$sPB-cA1w z2igPg<7uy(_K=z$dzTGdKGxzAJImfI)Gg-D@C-TdRv23`cr(}F$+)3H!`zcGch!vM zbG`4BSA(+DS3qpX+?%K(A&WKB5ImGR0LOf?5j+#^LBE?Gwhwh4y!Ls&yNOJbZ%i0u z`kj9&zWvzV+8OlU6BfYT{LHjS!vb3d784{f;nhptrQ15>e4Z`q_kF?;vJb{<4*y&8 zwTm^gfu0=iX8*X;B4lxNV0`zF^%RIsYpe*TfKMjqrxT{(^{*L$wN>mG08L(6e6?mOyM7E9|uN4G?^%Q4q4|v_|ra Oo&j-o@si>UX8r+f+1acB delta 693 zcmYk2v2W8r6vpj1IbVXEI3!kW(p0UwAU6tj2c`~LpsmDEq#7bI5Otwrx*Y|n*QIm- zQQzB8`5Qp8geRLe&0e{sO@DpL6ITBSc(+HM%QKA}&$_`lhZP|U8A5#jFV&8!eh4qP= zp=>82VvtVsF%0(f=aPlTEZm2U8fHbI16m{~6~c9KcY*|3l9(I98Bl%+H^!J?q%L&O z%^e9bNnSwUkNGl#C{NMlU8$?297}K%qCAq(+pnJwPJSn&Ps5Xak)f3Tm@jAV ze+}Y)*H_<8hl6-1QfW{>^g_=BU7NeRtSD07;i;15ZyLV$x@F%F13rd}LZi#iK=vh9 z7lZgXIZj3w@I-4aOmK#RdR`zLd+yS`MZ3-Ww;q-rgWGt@H!^8&lfzMZ!kflo)SZX# Js1E1#+5eG2xU>KO diff --git a/res/TITLE.HGR/SUPER.HUEY b/res/TITLE.HGR/SUPER.HUEY index 344ff8df708fae76baef64c9974c3916a04025bf..f5228f8a90b4a2fb28b0fb17656c36c8dda9afed 100644 GIT binary patch delta 350 zcmZp0Xt3E(&&)VwaszV($AXIuN1G0;o;#6IWpV?X`9uMhiT5QZJ21*m6j0o}gT;E(SMvvbhw*cTzy#f&9)p qc>$L&$hvs$*vWgO55qjTT?Wa_$>y?-Obrc_?Kl)C3dn%{p$Gs-?01m> delta 336 zcmZp$X>iz3&pc6pcd~$p*2H_76YslDULnFikzZ$WJY&S>?JORQ69p_Lo3lAi4q)T} zNlor&%LKCdL3#pYfGR~M-q)CT-*>Ws1lQzyqEeeLu;&`VegUnC0(_IrrJxE~!K(f-DS{1hoxFfc7-YeH zzSzloqz{A4+%5w%bF#TCkjc+K`MiX{L;(e`I>uPmrUR?zHcURqH+`}JyFSpN5dD=v Go(2Ht!E~bl diff --git a/res/TITLE.HGR/SUPER.ICEHOCKEY b/res/TITLE.HGR/SUPER.ICEHOCKEY index e3c41e838039c87ff9c4eeec21b41f5a76b25f28..f97af31bfeff25d4c9f759e6c5b26771718144b1 100644 GIT binary patch delta 653 zcmYL{J%|%Q6vrpYCOi4ud~81Nj!PBdo<%@yM7>yP6B2}Ad4-4E#_fzSE1a2CQIL@A z%)2X;aATU^-u&Nh9FE;Vq4sq4$I zQf%6Oey`Vk(!2vaXoo6$FP@ou;EQL(%^XxiEqc52(CnJmE5JjH9&R^Fjo#B8soH9% zX?Azo25^;u5#9yOAB7La1hi#cspI9MwmK$nP|jrxkMl5$neb7sK`nA$xMgtT zNCFEbOb)^QBHe`wkw*YSH;NsCgQ)fYBnyCx2 zAOq5eUfQN7eKI{KMU13ogdB|c!sHO$J6sM8ee5>{IE?p()W>Sv)HaQiZaXS zwbJ308=dAh@GJ}MRvPxBt1_iSI``P~nzO`9^qRLkY>4gw@I1qgs4TF6k!`^zy$DBz zeQ2c%kSux*|B}(-1bER_M{}}tCQDgj^b0z4Mq~gS1A@FJWHOf2cZ4=Ju&424$UM!xydq8^euIjJGatss+IP75Uv2*jBcNxSc`?|buR z=I8Mbp2XZuDSFdrXZr^28cLBb%~*D(kWreX)sO3h$cx?3N2nLWaE#G~nvWiV8@v)9E-jIE^qM$xB!i51td;FrK&U6k)JpE?tOogS;{3}}G0%5pf zo}C{u5vn|_5rRe!!m&C>%LvAR`uVDp%DG} z%&8=6igp77uzn zCWLdw^gN4-SHy79gsGesQ3Ks%BWJ)o;ea$X6QD0=(EdP0K+Zomx%WXStT~E7Nw|F5@Y{7 z{}q0zEfQK%+E#QxEgx%clyE#H`I7W9OCyp(Cvb6AZ;r)DS?((;#x$Jx8 z+0sJkMC#IL!OFjK2GUkHtDMc(A;04E$f5YcRj*0 z?;QhApW@+|u%Gc{fWK~l3mZHcd(db)-u_?CU8i%c(cEjWve#wo#X{HLZ(El#@01Ip z)2V#r?9uPBZSEbsbGQy~mdQ_59mJ+!KNv`-Oxi7h2w>?={6R0*S$8q7~U1!cf|f>9-ES~N6E-Y|+yqu3m4nAQen zD+P-L{Psixw9WU9nLufQcbG#t;MG1u93-AqTIyY57BcOvvd}EsX;s_fF`C2Q`KQ>; zFl-$_bZ^Cs;^--Y9M?xZ1iNE{us6Z<$OCT^x$CNt7W>M9yl8{d<>UKV-^DCO944F5 jiDm8m6FwNZ{!}HKuO}K%0AxS-#5;Kw;T_!Qi~MT8=gHCz delta 900 zcmY+=Ye-X30KoCPd*|I*ZMK#GBv=Jq!T1gRh>_@UdqLlW*|9)jb(b=4RZ zHV{N3x35|gFUgBx0Rm%&UH`W}FiH@OR}(jlZQ}dGvdc=WY6(Of;>&c~{0OshYqq{S z?>P38St(91=)3wWtFvx^pcDvl@{JyUJaZh25TK$%8=r`ObOh1B?PVVxN5{*t27+x% zf7>pW%RYi=7%%M0aqszD#w;KK&+gnWO+s-kvmRzkuk&y0v@%QU1ihbjeie818wk=u z&~pa4K4#_x@DvDKw|&}Z&55rB(P$S}G~R1l7ROWROPtd5dDc$Y2%;f`H~Hg(d(SaT zCjqfa_6rdoV%F*hx85~v5Z%nuJHg}H7MCvn?MH(25LnMumG^{;JUA5shd*2yUvGa- z5REm%fu_+z=HGZ4{kiVIsu6WY0YNmPiBpxA^+UbPGDu(?%gxn&b1Rt@eB|yW1BO;+ zO?QH)vf5Sm+}=v9O7V~ILaA4<5rS^Bu4_Sf+BGIcuPqLLzfu&yGaz_yq}zO=JGzG; z8p`0%x7cWWf=Ou-PzijeAn@HxQVBvr5CnxuGo4^gc2?GY>pTnlDn6s6u*9SF;&ceO zt|wa}+qnp{LSUh0(e=_2Y=R)*ZTGMI(s73%8mf-dxo^CAZ=}3s)?CGN=(h}r=d>id5l&Z diff --git a/res/TITLE.HGR/THE.DAM.BUSTERS b/res/TITLE.HGR/THE.DAM.BUSTERS index c8987068bf317fa77927ec1d90c96fe3d2b41138..4d9b8a6b50fc4c1b66ad0e049e95842658759cdb 100644 GIT binary patch delta 634 zcmX|8O>a^`6y@>t#(r3AOA9UTOxni8U*N)jVBX4~;M(1kRyYqz8VRvwZb-UlEV@vf zm3xgmV!HO#K-`#s|G+McuM|7pfyA3k=AM~*&$%CXgonpc#L)KJem!hL3P6W%2D+yl zDe5haPEYp<4AAQI>OnnFasIGDz6K#K-QcRLdyRnn%)MqNMcWB4jaYm5_anW|t&mDQ zb%BvNGN$Ql(N@wEzfr{xeZkpDs~3LmwX0C6acUU60?4G`bO>oF&g(%X78swLMb30R zcU%Dw1C`yPi%zX`uKQC`;Rzk+nr`Urx&H_W2m%50QpOOxbO3KK)-#8*Lh%D$vU({+uapyj@Giln%dNb-$wm5Sp*?p@~T&p=y>m`;iukWRU#!F0~ za*{4LvUHrw)7#uPaS&bVCKo`+OZOr&U(FfMKmR=Wvxl0QBifHvnPmVsR{h^Zo_g&|>&Ti(turcUXG6J_YB8 zlLM*4eezPEjqPXz1Ij82(#R|K&e8^xnAPH#4KDpl85*Pv4N!*rXM}LC_L1eF+fQm_ z<*Y_z!Sg~y4>*xt?W0M2;g4Wu^k>iUBr5z)b1@xngk!idHs=f=etU>Ij(6NTb(gdh zxQz4T4VvN{suOoy7*i8#G_p}tCYSKSR0s=N5VMmHyit`Bwj1kEsJCcXaokkzcO^RN zBOeWU^_+=Yl&VbWR6uHKt=C>j(=n}G!fkDYZe^e3Rot3hbSY6xKkk)!UdN|&b;`^V zzDa`fjt?a&ehA$~vxzVZVAXnd?!GT`yDBkLu2pVhsbm1dSO+Gz@9 z(AQ^BHLH94kXzj3W!|LS;7yjaWW?r&7qs7i_uL z>`$1SNyKEbO96m}rmheo4d}J<&!F?4z`FgN7YRME#lF~;ag2S-0JU?(n{7k!#+ diff --git a/res/TITLE.HGR/TOMAHAWK b/res/TITLE.HGR/TOMAHAWK index 9eb619197226dd155975140a6753814e9c561751..b0c4cf6fdaa169692b8ab8e437132b7c2488582e 100644 GIT binary patch delta 747 zcmYk3KTOk65XbYQEj|9&R-v?%Rud9T^J}7mg9%03!9?T4@=FKOAd)aJAW_j*1$#7z z4T;*{yRfs6$OB_yWRZo$trIc621txuSUNEqlX|Zu;+yVsm%ICZ?_n0lDgyBAxhUK~ zXGg}7mVg%{GeMIlw1jI7P@rQLiX%7QwR0V5; zF(mPsqa$H|KEFJ!C5;7>Y z-Kf?+Yv~tI)nBwyS`jidoA2?1R?DqDFaexL%#IZZLBP!Aj8TfROHd%%O{K19FrRx| zers~wt=;3ZK4b3;9{J{TvPXdJ++KL;TxTmi!f!7nt>HW1T7wkreemy4guMcO@V<|m zx+X8MF2&+&>WI)ljVs61h77RyV~&s1388`YU9GmXlEL$v69$C`SIe#yr$}fDMny1W zbQ6XIbeo8uyeJ@h<;iO0t0^!b-n)^^ryO}nz+$u6oSRHd5;E}R9eW{zvQGdDw@f!- zAOB#2!u`{r+oBtU{j5i;1`9lvVRPBIX|58VZeumzQkmGbh29OCXWs+IBq+ZYmb8uWQesAOEwf#2&jb_nC5<;#FfoX3R! F!Cw?xLjV8( delta 1184 zcmY+CO=}ZT6oxydv16@f)WpQJQ7BZy45*+`XsXFVP(&myhJX^{2Xx`0#*bj4)j27( zhJc!!`v{ zn`CB1WNV7}N+FmXjQoSr7p4MghPhC;);U6?;@U$$MlL1i+&x z0C+D7fVPqliLsk-pD{Vf`(zdb!23}Ea0CTFTZxOfb_;qmImriP76iZtQ2_8E6aYa_ z6nmm_l4CLp0^q|a062~UAm~Y8PeM-e5t#)6a1sRokD~zK2^0XFLXoOk{U4upJX!O} z)LaCYtf}eOJ??%g>W@#BGBK+*X~Y)$-A7XSF+@ttccH{v!xvec023-mi3qa-rcEX;-UO}(JIVX{+9Z4 zBj!6QC!^U%M&))fW9q@e!iaWJRft-hrAEC|Z;-vz_(G0%Z)cIjkMRldI}%oh{@g!3 I9o4V?2eFw3wg3PC diff --git a/res/TITLE.HGR/TRACK.AND.FIELD b/res/TITLE.HGR/TRACK.AND.FIELD index 6f0ff07d02e4b537545bfd347bd36b91aa2ed4e6..7d1446092b2df2da2e9a548d76696ea75eb0fa29 100644 GIT binary patch delta 275 zcmXAjJxc>Y6h$-6teIHoTA4y4wj!noSXrc5MDUmR3&tY&)&;Hn$hCs7BxrE$PHcL zCA(N1Q<0g(R?Mf=T*>&Rngf7C@G$>&KC#n6VZXCKTx?n^PFC=|vxcJiD>5@1YpEm| zGPik=*ArGo(j*g#vjUK@E_Pd|fiF;O2Q3$f(j^tbhLTHl>K;=a`uo0~UHluuNVqpQ zw`J&pz`vLpy`|&~Xf&ZIA$XY5lULs5x~+nG4fptwwe44qpS$aL$PdtNpE3Tt!~Ouj CVu)4% delta 362 zcmZ8dJ4*vW5Wd_impjeF#t5+p+F2+Hikd=;LjwK_d#hMj2zy?LAZT`&&c@iufz@K8 zMN-+CB8wIl)>qjGF~qEsD-1Nkj3)psXDfr92O5(%OzTDR zTx-d=8-?2c83q@lHe*b+zZ6YCXbuSwEaAX*;WEF_jUHPvlF?N!?nU9f47xF+QwCV} xj;ORaRN-js?Wo(1YEI%l)vIbJJgnrrJJMfI-SmkSJS}Aj1!w)aYNy{H{68ssp5Fif diff --git a/res/TITLE.HGR/WINTER.GAMES b/res/TITLE.HGR/WINTER.GAMES index 666d2d3c742985fb468ca063c481ed6102a9181c..1fd2967e1455d38eca7dd8e108c92ad52f9af7a7 100644 GIT binary patch delta 657 zcmYL`F=*RB6o!!_#}`{}6gzelCvm2fA_8frcIeO!9t>SdD=3*thZ64|ZYcCQ4ner4 z*4?AvKtT3VjFtwxv{M9i$zm`Wv=;}`Idth@tUlSLx#it=r@Qy*KX?L<9WHcL9W?M- z0B2Oaz#I0Y!r7K^XJ$}I4H)PM#;jN_S}P;9xtnbm$_KCp9- z5C}@$m!@Twx~Rl=Nt0=O;q`seNOR`b ze*bFy94Yb+XWI49?N6JuK>)qekF$2mG^a73KoJOnM%@lZ`$n2~`+ow&0EXU${N~F@L zuadBV&guc4sdurM+o$>vzvRlZjPq5YQ^xsu#)Gimk!zg2+eWZpcn^V~^ubD!RZ<$a zb_fPnn%GV4P@jJ{u9xwZL579f_d+Pl|C^*hZcyaZYlB)EsBe-Nz4c}#D$84yxz<+s H|6~6Jfm#p6 delta 1121 zcmZ9Ly-OoO7{=WgzrPYScY1!rP6>hv7J?Rcg@s__#}=oJTtBa7zY66xr3C?SI~oAofd&9~q5;5NXaI0G z8UWmb1_1Y>0l;mOVzO@sHrb~lxnF5P06c&O00+g5A9Z71nxSX5A`3=nX*Itc(IeiNF{KJ6(%SUb z+-1xSY??g#OI~rqxv>5@;Xm0p{qK%rHtLU+*NNS`;Y6uXs#TIVSM{Ie$4b8L99`Tw zsoIU4d}x1fo~-EK-)9dMt@o*%Ej3a^h09Ynv#Fq5vz?3^wqX^{T}4&dHzN8scb#8w zH{`-CnK}AFnd6w1lbEsO@LkCFG}bh$Q_3BN1?g0tSv}FkvVThKjxVMI!ME@K84E%I A=>Px# diff --git a/res/TITLE.HGR/WORLD.KARATE b/res/TITLE.HGR/WORLD.KARATE index 0e0404a446bb8f985dec948de974d55e4821d9a2..ca37af6a281c08e8f191331b22c0c9e3fcf16ef1 100644 GIT binary patch delta 693 zcmYL`O>0^~6oyCZ$K=LDZM-qYSWBT0<|ZhGP%!lax-StjDglEuP|3AlQf@QeYG$CD zZd!8ZkbRfMKheL?jhp_0{*0cvns#P04`#z#Dkg$N0kZKSZC~VTQ!!ox6&JKC#sw+Hj!uLsOiFnR3gO2sC#Oa}DX9HGzUzi6 z2%H^ppOAe`&H1GM#u+)F47{un&YyqOYl0rtog^Wzv4FrkHFDBGDN6*Yb@*&~*vNlz zw5-g(r=D0u3qU4L7z50RM7h|D1I{bJ_`dJ7JWvP+Gi)YKU1tS6EZXojJNmD3 zf2H`SZGl1{!pxFVZ!PDh2NHvBiNMN3I(NBhlxQ+1V)Ay)#MnSj8SN4r)ih_p%Ke zg;9_~=Y@aHqk7j*m>E|R)b1pC-6YfURO;d?Pxzz7rR}}TfEFOw8wLrKDvjVzIRjrx I@9!M5zoxj;8~^|S delta 1206 zcmYk3%}*0S6u@7r(y}T=rSe$`CPp#~X=6f6ick_xdZG!h5R#fk5)UhC8dKS>l$rlP zoRNb!4<1Y}n!wShe}b1@ym|G&#h4flUEg%e>`X83H@|&fQ*lqM9QbMIpEtr!izpT{ z5#K98U_{au1R;c74)8^uBN0MEgxyso2qKX_%)Nz2jobct%LXmAPRN{bv_{V7BFYlTa4TRgK4iGO!H8I+!txkYDVj$wkL;Dl zmh`>(IqgpS&K5)GR;SH5|JL~#J67HvE$;dC!41DY&i%Tpv*@G4kB12B6lZVn=hTO@ zv#F6SU;r?SY;EbO`^3dZML=AAxv=EYYwfsLDZ<*aX|7xSKpJ74aaLy88ZWh`hm)~y zG^?fh_U_}m%P;aY$YRfU7|;-$_r}pTw=o_d36;PLXrDrkHs;w%5CrZ@W3EM?tK8%m zzgc#`*V(-qJX4G7M1A=p-*1`Pbmz77r}TJ@(#Er@p5brU)*GV(n?tkn4NT7ER?u?` wSlkSpLIXBgK3ij$f}I2g(H{}jMm9o05= DisableAccelerator { !error "code is too large: ends at ", LCRAM2_END } - FONTDST = (LCRAM2_END + 255) and -256 + FONTDST = $E000 } EvenLasterMover FONTSRC = * !pseudopc FONTDST { - !source "src/ui.font.data.lc2.a" - !if * > $E000 { - !error "code is too large: ends at ", * - } + !source "src/ui.font.data.a" } !if RELBASE = $2000 { !ifdef PASS2 { @@ -199,6 +208,7 @@ EvenLasterMover !set PASS2=1 !warn "ProRWTS ends at ", hdddataend - 1 !warn "STACK at ", STACKBASE + !warn "OKVS CACHE at ", OKVS_CACHE !warn "LCRAM2 ends at ", LCRAM2_END !warn "RELBASE = ", $10000 - (LastMover - FirstMover) } diff --git a/src/4sports.init.a b/src/4cade.init.a similarity index 77% rename from src/4sports.init.a rename to src/4cade.init.a index 6ef02a7..e25c308 100644 --- a/src/4sports.init.a +++ b/src/4cade.init.a @@ -18,6 +18,44 @@ jsr ROM_NORMAL jsr ROM_IN0 jsr ROM_PR0 + + ; accommodate uppercase-only machines (64K ][+ is supported) + lda ROM_MACHINEID + cmp #$A0 + beq + ; Spectrum ED + cmp #$06 + beq + + lda #$DF + +HIDE_NEXT_2_BYTES ++ lda #$FF + sta zpCharMask + + ; print text title in same place as graphical title will appear + ldy #14 +- lda II,y + ora #$80 + +FORCE_UPPERCASE_IF_REQUIRED + sta $070C,y + dey + bpl - + ldy #12 +- lda INSTANT,y + ora #$80 + sta $04B5,y + dey + bpl - + ldy #10 +- lda REPLAY,y + ora #$80 + sta $0536,y + dey + bpl - + + ; TODO make this true again + ; proboothd duplicates the above code and jumps here, + ; so if you make any changes before this comment, you + ; MUST adjust the final JMP in src/proboothd/proboothd.a + jsr Has64K ; check for 64K (required) bcc + @@ -57,42 +95,10 @@ ; bit 7 = 1 if joystick ; and all other bits are 0 (we'll set bit 3 after copying it to LC RAM) - ; accommodate uppercase-only machines (64K ][+ is supported) - lda ROM_MACHINEID - cmp #$A0 - beq + ; Spectrum ED - cmp #$06 - beq + - lda #$DF - +HIDE_NEXT_2_BYTES -+ lda #$FF - sta zpCharMask - - ; print text title in same place as graphical title will appear - ldy #14 -- lda II,y - ora #$80 - +FORCE_UPPERCASE_IF_REQUIRED - sta $070C,y - dey - bpl - - ldy #12 -- lda INSTANT,y - ora #$80 - sta $04B5,y - dey - bpl - - ldy #10 -- lda REPLAY,y - ora #$80 - sta $0536,y - dey - bpl - - ; increase text window width so we can print to the edge of the screen without scrolling inc $21 ; print version or build number in lower right corner - ldx #30 + ldx #28 ldy #23 jsr SetCursorPosition +LDADDR LoadingVersion @@ -105,7 +111,7 @@ } ; set up text window so it only covers lower left corner - lda #30 + lda #28 sta $21 lda #19 sta $22 @@ -184,7 +190,7 @@ ldy #4 @ELM lda FONTSRC,x - ; relocate font data to RAM bank 2 + ; relocate font data to $E000 sta FONTDST,x inx bne @ELM @@ -282,14 +288,14 @@ REPLAY !text "R E P L A Y" !ifndef RELEASE { LoadingVersion - !byte 8 - !text "build 00" + !byte 10 + !text " build 00" LoadingBuild !word BUILDNUMBER } else { LoadingVersion - !byte 10 - !text " v1.0" + !byte 12 + !text "v1.0-alpha.1" } Loading64K !byte 3 @@ -346,7 +352,7 @@ PrintAsDecimal !source "src/hw.accel.a" !source "src/hw.vbl.init.a" - !source "src/parse.games.a" + !source "src/parse.common.a" OneTimeSetup lda zpMachineStatus @@ -373,8 +379,9 @@ CopyDevs lda hddopendir+1 ; save current directory as 'root' ldy hddopendir+3 + sta gRootDirectory+1 + sty gRootDirectory+3 jsr SwitchToBank1 - +ST16 gRootDirectory jsr LoadFile ; load preferences file into $8000 !word kRootDirectory @@ -384,42 +391,11 @@ CopyDevs !word gGlobalPrefsStore !word - !byte 16 - +LD16 SRC ; (SRC) points to free space after the OKVS data structure we just created - +ST16 gGamesListStore ; save pointer to free space for next store - - jsr LoadFile ; load games list file into $8200 - !word kRootDirectory - !word @kGameListConfFile -- !word $8200 - jsr ParseGamesList ; parse games list into OKVS data structure in LC RAM bank - !word gGamesListStore - !word - - -!ifndef RELEASE { - +READ_ROM_NO_WRITE - lda #40 - sta $21 - lda #36 - sta $24 - dec $25 - jsr $FC22 - lda SRC+1 - jsr $FDDA - lda SRC - jsr $FDDA - +READ_RAM1_WRITE_RAM1 -} - - +LDADDR gGamesListStore - jsr okvs_len - +LD16 WCOUNT - +ST16 GameCount - +ST16 SAVE jsr pref_get ; see if cheats are enabled by default + ; sets PTR -> cheat pref value as length-prefixed string '1' or '0' !word kCheat !word 0 - +ST16 PTR ; (PTR) -> cheat pref value as length-prefixed string '1' or '0' ldy #1 lda (PTR),y ; A = #$B1 or #$B0 and #1 ; A = #$01 or #$00 @@ -429,8 +405,40 @@ CopyDevs ora MachineStatus sta MachineStatus ; set bit 3 of MachineStatus - ; calculate and update visible game count (3-digit decimal number as ASCII string) - dey ; Y = 0 + rol + rol + rol + rol + and #%00000110 + tax ; X in (0,2,4,6) + ldy kGameCounts, x + sty GameCount ; store total game count based on based on (has-joystick) X (has-128K) + sty SAVE + ldy kGameCounts+1, x + sty GameCount+1 + sty SAVE+1 + lsr + tax ; X in (0,1,2,3) + lda kSearchIndexLo, x + sta @searchIndexSrc+1 ; set up search index record based on (has-joystick) X (has-128K) + lda kSearchIndexHi, x + sta @searchIndexSrc+2 + lda kSearchCacheLo, x + sta @searchCacheSrc+1 ; set up search cache record based on (has-joystick) X (has-128K) + lda kSearchCacheHi, x + sta @searchCacheSrc+2 + ldy #5 +@searchIndexSrc + lda $FDFD, y ; SMC + sta kSearchIndexRecord, y +@searchCacheSrc + lda $FDFD, y + sta kSearchCacheRecord, y + dey + bpl @searchIndexSrc + + ; convert GameCount (word) to VisibleGameCount (3-digit decimal number as ASCII string) + iny ; Y = 0 @outer lda #0 pha @@ -461,11 +469,49 @@ CopyDevs bit CLEARKBD jmp Reenter -@kGameListConfFile - !byte 10 - !text "GAMES.CONF" - @kPowersOfTen !byte 100 !byte 10 !byte 1 + +kSearchIndexLo + !byte kSearchIndexRecord00 + !byte >kSearchIndexRecord01 + !byte >kSearchIndexRecord10 + !byte >kSearchIndexRecord11 +kSearchCacheLo + !byte kSearchCacheRecord00 + !byte >kSearchCacheRecord01 + !byte >kSearchCacheRecord10 + !byte >kSearchCacheRecord11 +kSearchIndexRecord00 + !source "src/index/search00.idx.a" +kSearchIndexRecord01 + !source "src/index/search01.idx.a" +kSearchIndexRecord10 + !source "src/index/search10.idx.a" +kSearchIndexRecord11 + !source "src/index/search11.idx.a" +kSearchCacheRecord00 + !source "src/index/cache00.idx.a" +kSearchCacheRecord01 + !source "src/index/cache01.idx.a" +kSearchCacheRecord10 + !source "src/index/cache10.idx.a" +kSearchCacheRecord11 + !source "src/index/cache11.idx.a" +kGameCounts + !source "src/index/count00.a" + !source "src/index/count01.a" + !source "src/index/count10.a" + !source "src/index/count11.a" diff --git a/src/4sports.init.cffa.a b/src/4cade.init.cffa.a similarity index 100% rename from src/4sports.init.cffa.a rename to src/4cade.init.cffa.a diff --git a/src/4sports.init.gs.a b/src/4cade.init.gs.a similarity index 100% rename from src/4sports.init.gs.a rename to src/4cade.init.gs.a diff --git a/src/constants.a b/src/constants.a index 4a2784d..33ed210 100644 --- a/src/constants.a +++ b/src/constants.a @@ -1,26 +1,75 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2022 by 4am ; ;------------------------------------------------------------------------------ ; YE OLDE GRAND UNIFIED MEMORY MAP ; ; LC RAM BANK 1 -; D000..E92C - persistent data structures (gGlobalPrefsStore, gGamesListStore) -; E92D..FFF1 - main program code -; FFF2..FFF9 - API functions and global constants available for main program +; D000 - reserved +; D001..D06E - gGlobalPrefsStore +; ...unused... +; E000..E3FF - HGR font data +; ...unused... +; E730..FFEB - main program code +; FFEC..FFF9 - API functions and global constants available for main program ; code, prelaunchers, transition effects, &c. -; (Wait/UnwaitForVBL, MockingboardStuff, MachineStatus) +; (LoadFileDirect, Wait/UnwaitForVBL, MockingboardStuff, MachineStatus) ; FFFA..FFFF - NMI, reset, IRQ vectors ; ; LC RAM BANK 2 -; D000..D3FF - ProRWTS data -; D400..D677 - ProRWTS code -; D678..DB9D - HGR font code & ProRWTS glue code -; DB9E..DBAD - backup of stack (during gameplay and self-running demos) +; D000..D5FF - ProRWTS data +; D600..D8BD - ProRWTS code +; D8BE..DC76 - ProRWTS glue code +; DC77..DC7C - backup of stack (during gameplay and self-running demos) +; DC7D..DC82 - okvs cache (attract state saved across self-running demo) ; ...unused... -; DBB4..DBFF - (de)acceleration function -; DC00..DFFF - HGR font data +; DFB4..DFFF - (de)acceleration function +; +; MAIN MEMORY DURING SEARCH/BROWSE MODE +; 6000..9FFF - search index +; A000..BCFF - search cache +; BD00..BEFF - prefs buffer (used to write PREFS.CONF if cheat mode changes) +; BF00..BFFF - ProRWTS glue (supports LoadIndexedFile) +; +; MAIN MEMORY DURING MEGA-ATTRACT MODE +; 0100..0105 - re-entry code for demos (reloaded before demo) +; 0106..01BF - prelaunch code (reloaded before demo) +; 0400..07FF - text screen (cleared before each module) +; 0800..1EFF - slideshow configuration file (persistent during slideshow module) +; 2000..5FFF - hi-res screens (cleared before each module) +; 4000..5FFF - slideshow index file (loaded before slideshow module) +; 6000.. - mega-attract configuration file (reloaded before each module) +; BD00..BEFF - prefs buffer (clobbered if cheat mode changes) +; BF00..BFFF - ProRWTS glue (reset after demo) +; +; MAIN MEMORY DURING MINI-ATTRACT MODE +; 0100..0105 - re-entry code for demos (reloaded before demo) +; 0106..01BF - prelaunch code (reloaded before demo) +; 0400..07FF - text screen (cleared before each module) +; 0800..1FFF - mini-attract index file (loaded once) +; 2000..5FFF - hi-res screens +; 6000.. - mini-attract configuration file (reloaded before each module) +; 6000.. - transition effect code (reloaded before each screenshot module) +; BF00..BFFF - ProRWTS glue (reset after demo) +; +; MAIN MEMORY DURING GAME LAUNCH +; 0100..0105 - re-entry code +; 0106..01BF - prelaunch code +; 0400..7FFF - text screen cleared +; 2000..5FFF - hi-res screens cleared +; A000.. - prelaunch index file +; +; MAIN MEMORY DURING CREDITS (preserves search index and cache) +; 0800.. - credits text +; +; MAIN MEMORY DURING GLOBAL HELP (preserves search index and cache) +; 0800.. - help text +; +; MAIN MEMORY DURING PER-GAME HELP (clobbers search cache) +; 0800.. - help text +; A000.. - game help index file +; ;------------------------------------------------------------------------------ !ifndef _CONSTANTS_ { @@ -39,11 +88,11 @@ CLR80VID = $C00C ; 40 columns (also used to get out of DHGR mode) SET80VID = $C00D ; 80 columns (also used to get into DHGR mode) PRIMARYCHARSET= $C00E ; no mousetext for you SLOT3STATUS = $C017 ; bit 7 only -TBCOLOR = $C022 ; IIgs text foreground and background colors (also VidHD) +TBCOLOR = $C022 ; IIgs text foreground and background colors (also VidHD but write-only) NEWVIDEO = $C029 ; IIgs graphics modes (also VidHD) SPEAKER = $C030 ; chirp chirp -CLOCKCTL = $C034 ; bits 0-3 are IIgs border color (also VidHD) -SHADOW = $C035 ; IIgs auxmem-to-bank-E1 shadowing (also VidHD) +CLOCKCTL = $C034 ; bits 0-3 are IIgs border color (also VidHD but write-only) +SHADOW = $C035 ; IIgs auxmem-to-bank-E1 shadowing (also VidHD but write-only) TEXTMODE = $C051 PAGE1 = $C054 ; page 1 (affects text, HGR, DHGR) PAGE2 = $C055 ; page 2 (affects text, HGR, DHGR) @@ -57,6 +106,7 @@ ROM_TEXT2COPY =$F962 ; turn on alternate display mode on IIgs ROM_REBOOT = $FAA6 ROM_TEXT = $FB2F ROM_MACHINEID =$FBB3 +ROM_MACHINE2C =$FBC0 ROM_HOME = $FC58 ROM_COUT = $FDED ROM_NORMAL = $FE84 ; NORMAL text (instead of INVERSE or FLASH) @@ -100,12 +150,10 @@ firstletter= $FA ; byte MatchCount = $FB ; byte BestMatchScore = $FC ; byte -; $FE ; used by ParseGamesList -; $FF ; used by ParseGamesList - ; main memory +gStackSize = 6 ; seems like only six are needed gPathname = $BFD0 ; used by SetPath/AddToPath -gKeyLen = $1F00 ; used by ParseGamesList +gKeyLen = $1F00 gKey = $1F01 UILine1 = $1FB0 UILine2 = $1FD8 @@ -114,25 +162,32 @@ UI_ToPlay = $1FF7 gValLen = $1F80 gVal = $1F81 -; LC RAM 1 +gSearchIndex = $6000 +gSearchCache = $A000 + +; LC RAM 1 & 2 +iAddToPath = $FFEC +iLoadFileDirect = $FFEF ; note: you really want LC RAM 2 banked in before calling this WaitForVBL = $FFF2 UnwaitForVBL = $FFF5 -MockingboardStuff = $FFF8 ; bit 7 = 1 if speech chip present (Mockingboard "C") - ; bit 6 = 1 if Mockingboard "B" (stereo) found (else Mockingboard "A") - ; bit 4-5 unused +MockingboardStuff = $FFF8 ; bit 7 = 1 if SC-01 speech chip present (Speech I) + ; bit 6 = 1 if SSI-263 speech chip present (Mockingboard "B"-"D") + ; bit 5 = 1 if two AY-3-8910s present (Sound II / Mockingboard "A"-"D") + ; bit 5 = 0 if only AY-3-8910 present (Sound I) + ; bit 4 unused ; bits 0-3: slot number MachineStatus = $FFF9 ; LC RAM 2 -DisableAccelerator = $DBB4 +DisableAccelerator = $DFB4 EnableAccelerator = DisableAccelerator+3 ; AND masks for MockingboardStuff MOCKINGBOARD_SLOT = %00001111 -HAS_SPEECH = %10000000 +HAS_SPEECH = %11000000 -; AND masks for game info bitfield (after game display name in gGamesListStore) +; AND masks for game info bitfield (after game display name in gSearchStore) HAS_DHGR_TITLE = %10000000 ; this one is hard-coded via BMI instead of AND/BNE CHEAT_CATEGORY = %00001111 @@ -144,20 +199,32 @@ HAS_VIDHD = %00010000 SUPPORTS_SHR = %00110000 CHEATS_ENABLED = %00001000 +; AND masks for gMegaAttractModeFilter +ATTRACT_DEMO = %00000001 +ATTRACT_HGR_TITLE = %00000010 +ATTRACT_HGR_ACTION = %00000100 +ATTRACT_DHGR_TITLE = %00001000 +ATTRACT_DHGR_ACTION = %00010000 +ATTRACT_SHR = %00100000 +ATTRACT_GR = %01000000 +ATTRACT_DGR = %10000000 + +PRELAUNCH_STANDARD_SIZE = 61 ; LoadStandardPrelaunch, eventually to be determined at build-time + ; shared symbols for prelaunch and effects to call ProRWTS2 functions -iCurBlockLo = $D401 -iCurBlockHi = $D403 -iProDOS_enter = $D678 -LoadFileDirect = $DB01 -iAuxReq = $DB27 -launchpatch = $D616 -iAddToPath = $FEC3 -itraverse = $D8E0 +iCurBlockLo = $D601 ; constant +iCurBlockHi = $D603 ; constant +launchpatch = $D85C ; glue.launch.a +itraverse = $DB4B ; Roger Rabbit, avoid, use Infiltrator 2 style instead + ; also Columns (via file in disk image) +ldrlo = $55 ; constant ldrhi = $56 ; constant namlo = $57 ; constant namhi = $58 ; constant -ldrlo2 = $59 ; constant -ldrhi2 = $5A ; constant +ldrlo2 = $64 ; constant +ldrhi2 = $65 ; constant + +; Columns and Dangerous Dave also call (de)accelerator functions directly _CONSTANTS_=* } diff --git a/src/fx/fx.cover.fade.a b/src/fx/fx.cover.fade.a old mode 100644 new mode 100755 index a5d51a3..08d40e4 --- a/src/fx/fx.cover.fade.a +++ b/src/fx/fx.cover.fade.a @@ -6,7 +6,7 @@ ; !cpu 6502 -!to "build/FX/COVERFADE",plain +!to "build/COVERFADE",plain *=$6000 !source "src/fx/macros.a" diff --git a/src/fx/fx.dgr.fizzle.a b/src/fx/fx.dgr.fizzle.a new file mode 100644 index 0000000..8d42dcf --- /dev/null +++ b/src/fx/fx.dgr.fizzle.a @@ -0,0 +1,52 @@ +;license:MIT +;(c) 2017-2021 by qkumba/4am/John Brooks +; +!cpu 6502 +!to "build/DGR.FIZZLE",plain +*=$6000 + + !source "src/fx/macros.a" + + +OVERCOPY_TO_0 start, end + ;$FF clobbered + ;X=0 + ;Y=0 + jmp loop + +start +!pseudopc 0 { + ;X=0 + ;Y=0 +loop txa +loop1 eor #$05 ; LFSR form 0x0500 with period 2047 +wait inx + bpl wait + tax +loop2 txa + ora #$04 + sta * != >STAGE0 { !error "Templates are not all on same page" } -; Note: the final k_rts is later copied to zero page $0F and used in MainLoop, -; so don't put any more code before BoxInitialStages. BoxInitialStages diff --git a/src/fx/fx.dhgr.48boxes.down.a b/src/fx/fx.dhgr.48boxes.down.a index df78e60..4b96c86 100644 --- a/src/fx/fx.dhgr.48boxes.down.a +++ b/src/fx/fx.dhgr.48boxes.down.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.DOWN",plain +!to "build/FX.INDEXED/DHGR.48.DOWN",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.longdiagonal.a b/src/fx/fx.dhgr.48boxes.longdiagonal.a index f0fb17a..ccbfa95 100644 --- a/src/fx/fx.dhgr.48boxes.longdiagonal.a +++ b/src/fx/fx.dhgr.48boxes.longdiagonal.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.LDIAGON",plain +!to "build/FX.INDEXED/DHGR.48.LDIAGON",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.pageturn.clear.a b/src/fx/fx.dhgr.48boxes.pageturn.clear.a new file mode 100644 index 0000000..257a2d6 --- /dev/null +++ b/src/fx/fx.dhgr.48boxes.pageturn.clear.a @@ -0,0 +1,51 @@ +;license:MIT +;(c) 2020 by 4am & qkumba +; +!cpu 6502 +!to "build/FX.INDEXED/DHGR.48.PAGEC",plain +*=$6000 + + !source "src/fx/fx.dhgr.48boxes.common.a" + + !byte $E1,$E2,$E1,$E7,$ED,$F3,$F9,$FF + !byte $E7,$E8,$E7,$E8,$EE,$F4,$FA,$00 + !byte $ED,$EE,$ED,$EE,$ED,$F3,$F9,$FF + !byte $F3,$F4,$F3,$F4,$F3,$F4,$FA,$00 + !byte $F9,$FA,$F9,$FA,$F9,$FA,$F9,$FF + !byte $FF,$00,$FF,$00,$FF,$00,$FF,$00 + +StagesHi ; high bytes of address of drawing routine for each stage + !byte clear0F + !byte clear0E + !byte clear0D + !byte clear0C + !byte clear0B + !byte clear0A + !byte clear09 + !byte clear08 + !byte clear07 + !byte clear06 + !byte clear05 + !byte clear04 + !byte clear03 + !byte clear02 + !byte clear01 + !byte clear00 + !byte 0,0,0,0,0,0,0,0,0,0,0,0,0 + !byte copy00 + !byte copy01 + !byte copy02 + !byte copy03 + !byte copy04 + !byte copy05 + !byte copy06 + !byte copy07 + !byte copy08 + !byte copy09 + !byte copy0A + !byte copy0B + !byte copy0C + !byte copy0D + !byte copy0E + !byte copy0F +EndStagesHi diff --git a/src/fx/fx.dhgr.48boxes.sidetoside.a b/src/fx/fx.dhgr.48boxes.sidetoside.a index 3257285..3eec14e 100644 --- a/src/fx/fx.dhgr.48boxes.sidetoside.a +++ b/src/fx/fx.dhgr.48boxes.sidetoside.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SIDES",plain +!to "build/FX.INDEXED/DHGR.48.SIDES",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.snake.a b/src/fx/fx.dhgr.48boxes.snake.a index 243260e..de982eb 100644 --- a/src/fx/fx.dhgr.48boxes.snake.a +++ b/src/fx/fx.dhgr.48boxes.snake.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SNAKE",plain +!to "build/FX.INDEXED/DHGR.48.SNAKE",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.snake.clear.a b/src/fx/fx.dhgr.48boxes.snake.clear.a index 13e6c17..f89925a 100644 --- a/src/fx/fx.dhgr.48boxes.snake.clear.a +++ b/src/fx/fx.dhgr.48boxes.snake.clear.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SNAKEC",plain +!to "build/FX.INDEXED/DHGR.48.SNAKEC",plain *=$6000 !source "src/fx/fx.dhgr.48boxes.common.a" diff --git a/src/fx/fx.dhgr.48boxes.spiral.a b/src/fx/fx.dhgr.48boxes.spiral.a index 038e3c3..80d75e3 100644 --- a/src/fx/fx.dhgr.48boxes.spiral.a +++ b/src/fx/fx.dhgr.48boxes.spiral.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SPIRAL",plain +!to "build/FX.INDEXED/DHGR.48.SPIRAL",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.spiral.clear.a b/src/fx/fx.dhgr.48boxes.spiral.clear.a index bbb55f9..b265fed 100644 --- a/src/fx/fx.dhgr.48boxes.spiral.clear.a +++ b/src/fx/fx.dhgr.48boxes.spiral.clear.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SPIRALC",plain +!to "build/FX.INDEXED/DHGR.48.SPIRALC",plain *=$6000 !source "src/fx/fx.dhgr.48boxes.common.a" diff --git a/src/fx/fx.dhgr.48boxes.sync.a b/src/fx/fx.dhgr.48boxes.sync.a index 479f717..75f4e11 100644 --- a/src/fx/fx.dhgr.48boxes.sync.a +++ b/src/fx/fx.dhgr.48boxes.sync.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SYNC",plain +!to "build/FX.INDEXED/DHGR.48.SYNC",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.sync.clear.a b/src/fx/fx.dhgr.48boxes.sync.clear.a index be09d80..4ecb098 100644 --- a/src/fx/fx.dhgr.48boxes.sync.clear.a +++ b/src/fx/fx.dhgr.48boxes.sync.clear.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SYNCC",plain +!to "build/FX.INDEXED/DHGR.48.SYNCC",plain *=$6000 !source "src/fx/fx.dhgr.48boxes.common.a" diff --git a/src/fx/fx.dhgr.bar.dissolve.a b/src/fx/fx.dhgr.bar.dissolve.a index 5697632..93a0763 100644 --- a/src/fx/fx.dhgr.bar.dissolve.a +++ b/src/fx/fx.dhgr.bar.dissolve.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am ; !cpu 6502 -!to "build/FX/DHGR.BAR.DISSLV",plain +!to "build/FX.INDEXED/DHGR.BAR.DISSLV",plain *=$6000 hgrlo = $0200 ; [$C0 bytes, main memory only] @@ -10,11 +10,8 @@ hgr1hi = $0300 ; [$C0 bytes, main memory only] !source "src/fx/macros.a" - ldx #(end-start) ; copy code to zero page -- lda start-1, x - sta $FF, x - dex - bne - + +COPY_TO_0 start, end + ;X=0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi jmp loop diff --git a/src/fx/fx.dhgr.bubbles.a b/src/fx/fx.dhgr.bubbles.a index 5f2f9aa..1930e86 100644 --- a/src/fx/fx.dhgr.bubbles.a +++ b/src/fx/fx.dhgr.bubbles.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BUBBLES",plain +!to "build/FX.INDEXED/DHGR.BUBBLES",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.bubbles.in.a b/src/fx/fx.dhgr.bubbles.in.a index e9a432c..6556416 100644 --- a/src/fx/fx.dhgr.bubbles.in.a +++ b/src/fx/fx.dhgr.bubbles.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BUBBLES.IN",plain +!to "build/FX.INDEXED/DHGR.BUBBLES.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.butterfly.a b/src/fx/fx.dhgr.butterfly.a index 1098314..7668ff9 100644 --- a/src/fx/fx.dhgr.butterfly.a +++ b/src/fx/fx.dhgr.butterfly.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BUTTERFLY",plain +!to "build/FX.INDEXED/DHGR.BUTTERFLY",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.butterfly.in.a b/src/fx/fx.dhgr.butterfly.in.a index 3c81dbf..f9e2424 100644 --- a/src/fx/fx.dhgr.butterfly.in.a +++ b/src/fx/fx.dhgr.butterfly.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BFLY.IN",plain +!to "build/FX.INDEXED/DHGR.BFLY.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.butterfly.ripple.a b/src/fx/fx.dhgr.butterfly.ripple.a index 5bfc2f9..16c9f23 100644 --- a/src/fx/fx.dhgr.butterfly.ripple.a +++ b/src/fx/fx.dhgr.butterfly.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BFLY.RIP",plain +!to "build/FX.INDEXED/DHGR.BFLY.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.corner4.a b/src/fx/fx.dhgr.corner4.a index 6c505b3..433d105 100644 --- a/src/fx/fx.dhgr.corner4.a +++ b/src/fx/fx.dhgr.corner4.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.CORNER4",plain +!to "build/FX.INDEXED/DHGR.CORNER4",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.corner4.in.a b/src/fx/fx.dhgr.corner4.in.a index 534bf29..f59054a 100644 --- a/src/fx/fx.dhgr.corner4.in.a +++ b/src/fx/fx.dhgr.corner4.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.CORNER4.IN",plain +!to "build/FX.INDEXED/DHGR.CORNER4.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.corner4.ripple.a b/src/fx/fx.dhgr.corner4.ripple.a index 89097ea..931d910 100644 --- a/src/fx/fx.dhgr.corner4.ripple.a +++ b/src/fx/fx.dhgr.corner4.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.CORNER4RIP",plain +!to "build/FX.INDEXED/DHGR.CORNER4RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.diagonal.a b/src/fx/fx.dhgr.diagonal.a index 65dddca..c5805c1 100644 --- a/src/fx/fx.dhgr.diagonal.a +++ b/src/fx/fx.dhgr.diagonal.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/DHGR.DIAGONAL",plain +!to "build/FX.INDEXED/DHGR.DIAGONAL",plain *=$6000 hgrlo = $0200 ; [$C0 bytes, main memory only] @@ -11,12 +11,8 @@ copymasks= $02C0 ; [$08 bytes, different values in main and !source "src/fx/macros.a" - ldx #(end-start) ; copy code to zero page -- lda start-1, x - sta $FF, x - dex - bne - - + +COPY_TO_0 start, end + ;X=0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi ldy #8 ; copy copymask arrays into place in main and auxmem diff --git a/src/fx/fx.dhgr.fizzle.a b/src/fx/fx.dhgr.fizzle.a index d2712ec..d067471 100644 --- a/src/fx/fx.dhgr.fizzle.a +++ b/src/fx/fx.dhgr.fizzle.a @@ -2,10 +2,12 @@ ;(c) 2017-2020 by qkumba/4am/John Brooks ; !cpu 6502 -!to "build/FX/DHGR.FIZZLE",plain +!to "build/FX.INDEXED/DHGR.FIZZLE",plain *=$6000 -addrs=$C0 ; [$40 bytes] +addrs=$BF ; [$40 bytes] + + !source "src/fx/macros.a" ldx #$1F ; build address lookup table - txa @@ -15,18 +17,18 @@ addrs=$C0 ; [$40 bytes] sta addrs+$20, x dex bpl - - ldx #(end-start) ; copy LFSR code to zero page -- lda start-1, x - sta $FF, x - dex - bne - + + +OVERCOPY_TO_0 start, end + ;$FF clobbered + ;X=0 + ;Y=0 jmp copyaux start !pseudopc 0 { +;Y=0 on entry to copyaux copyaux sta $C003 ; copy $4000/aux to $8000/main ldx #$20 - ldy #$00 a lda $4000, y b sta $8000, y iny @@ -37,8 +39,7 @@ b sta $8000, y bne a sta $C002 sta $C001 ; 80STORE mode -; X,Y=0 on entry to LFSR -; in: X,Y=0 +;X,Y=0 on entry to LFSR loop txa loop1 eor #$35 ; LFSR form 0x3500 with period 16383 tax @@ -62,9 +63,9 @@ dst sta $FD00, y bmi exit txa bne loop1 -exit lda $4000 ; last lousy byte (because LFSR never hits 0) - sta $2000 - sta $C000 ; 80STORE mode off + lda (src+1), y ; last lousy byte (because LFSR never hits 0) + sta (dst+1), y +exit sta $C000 ; 80STORE mode off rts aux sta $C055 ; switch $2000 access to aux memory (read/write!) sta 127 then we're done +ROW_X_TO_BASE_ADDRESSES +ROW_X_TO_MIRROR_ADDRESSES diff --git a/src/fx/fx.dhgr.precomputed.2bit.a b/src/fx/fx.dhgr.precomputed.2bit.a index ca45f02..c233e5b 100644 --- a/src/fx/fx.dhgr.precomputed.2bit.a +++ b/src/fx/fx.dhgr.precomputed.2bit.a @@ -57,11 +57,7 @@ +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi +BUILD_MIRROR_COLS mirror_cols +COPY_SELF_TO_AUXMEM - ldx #(end-start) ; copy InputLoop code to zero page -- lda start-1, x - sta $FF, x - dex - bne - + +COPY_TO_0 start, end jmp InputLoop start @@ -70,7 +66,7 @@ Exit2Bit rts InputLoop ldy #0 input=*+1 - ldx .coords, y ; first value: HGR row + 1 + ldx .coords ; first value: HGR row + 1 beq Exit2Bit ; if 0 then we're done +ROW_X_TO_2BIT_BASE_ADDRESSES diff --git a/src/fx/fx.dhgr.r.by.pixel.a b/src/fx/fx.dhgr.r.by.pixel.a index e10d585..c1c3452 100644 --- a/src/fx/fx.dhgr.r.by.pixel.a +++ b/src/fx/fx.dhgr.r.by.pixel.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/DHGR.R.BY.PIXEL",plain +!to "build/FX.INDEXED/DHGR.R.BY.PIXEL",plain *=$6000 hgrlo = $0201 ; [$C0 bytes, main memory only, offset by 1 because lookups will be based on $0200,x] @@ -11,12 +11,8 @@ copymasks= $02C1 ; [$07 bytes, different values in main and !source "src/fx/macros.a" - ldx #(end-start) ; copy code to zero page -- lda start-1, x - sta $FF, x - dex - bne - - + +COPY_TO_0 start, end + ;X=0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi ldy #7 ; copy copymask arrays into place in main and auxmem diff --git a/src/fx/fx.dhgr.radial.a b/src/fx/fx.dhgr.radial.a index fcd8224..0f27b2a 100644 --- a/src/fx/fx.dhgr.radial.a +++ b/src/fx/fx.dhgr.radial.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL",plain +!to "build/FX.INDEXED/DHGR.RADIAL",plain *=$6000 mirror_src1 = $E8 ; word diff --git a/src/fx/fx.dhgr.radial2.a b/src/fx/fx.dhgr.radial2.a index 6b33c6c..c60413a 100644 --- a/src/fx/fx.dhgr.radial2.a +++ b/src/fx/fx.dhgr.radial2.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL2",plain +!to "build/FX.INDEXED/DHGR.RADIAL2",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.radial3.a b/src/fx/fx.dhgr.radial3.a index 5567a8c..a44462c 100644 --- a/src/fx/fx.dhgr.radial3.a +++ b/src/fx/fx.dhgr.radial3.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL3",plain +!to "build/FX.INDEXED/DHGR.RADIAL3",plain *=$6000 mirror_src1 = $E8 ; word diff --git a/src/fx/fx.dhgr.radial4.a b/src/fx/fx.dhgr.radial4.a index 4257249..a9dd46f 100644 --- a/src/fx/fx.dhgr.radial4.a +++ b/src/fx/fx.dhgr.radial4.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL4",plain +!to "build/FX.INDEXED/DHGR.RADIAL4",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.radial5.a b/src/fx/fx.dhgr.radial5.a index b72d48d..7e7bcf7 100644 --- a/src/fx/fx.dhgr.radial5.a +++ b/src/fx/fx.dhgr.radial5.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL5",plain +!to "build/FX.INDEXED/DHGR.RADIAL5",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.redlines.a b/src/fx/fx.dhgr.redlines.a index 78ec4b5..4f1810a 100644 --- a/src/fx/fx.dhgr.redlines.a +++ b/src/fx/fx.dhgr.redlines.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am ; !cpu 6502 -!to "build/FX/DHGR.REDLINES",plain +!to "build/FX.INDEXED/DHGR.REDLINES",plain *=$6000 ; for red line: @@ -14,11 +14,8 @@ hgr1hi = $0300 ; [$C0 bytes, main memory only] !source "src/fx/macros.a" - ldx #(end-start) ; copy code to zero page -- lda start-1, x - sta $FF, x - dex - bne - + +COPY_TO_0 start, end + ;X=0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi jmp loop diff --git a/src/fx/fx.dhgr.ripple.a b/src/fx/fx.dhgr.ripple.a index 5a961b1..28311e9 100644 --- a/src/fx/fx.dhgr.ripple.a +++ b/src/fx/fx.dhgr.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RIPPLE",plain +!to "build/FX.INDEXED/DHGR.RIPPLE",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.slow.star.a b/src/fx/fx.dhgr.slow.star.a index 030acf4..6f14155 100644 --- a/src/fx/fx.dhgr.slow.star.a +++ b/src/fx/fx.dhgr.slow.star.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SLOW.STAR",plain +!to "build/FX.INDEXED/DHGR.SLOW.STAR",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.slow.star.in.a b/src/fx/fx.dhgr.slow.star.in.a index f2ef206..fc2c30b 100644 --- a/src/fx/fx.dhgr.slow.star.in.a +++ b/src/fx/fx.dhgr.slow.star.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SLOW.STARI",plain +!to "build/FX.INDEXED/DHGR.SLOW.STARI",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.slow.star.ripple.a b/src/fx/fx.dhgr.slow.star.ripple.a index 44b24fa..e3c2b19 100644 --- a/src/fx/fx.dhgr.slow.star.ripple.a +++ b/src/fx/fx.dhgr.slow.star.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SLOWST.RIP",plain +!to "build/FX.INDEXED/DHGR.SLOWST.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.snowflake.a b/src/fx/fx.dhgr.snowflake.a index ac8e01b..c60c7a4 100644 --- a/src/fx/fx.dhgr.snowflake.a +++ b/src/fx/fx.dhgr.snowflake.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SNOWFLAKE",plain +!to "build/FX.INDEXED/DHGR.SNOWFLAKE",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.snowflake.in.a b/src/fx/fx.dhgr.snowflake.in.a index 893edb8..868b690 100644 --- a/src/fx/fx.dhgr.snowflake.in.a +++ b/src/fx/fx.dhgr.snowflake.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SNOWFL.IN",plain +!to "build/FX.INDEXED/DHGR.SNOWFL.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.snowflake.ripple.a b/src/fx/fx.dhgr.snowflake.ripple.a index 3b8b2de..90f3bbb 100644 --- a/src/fx/fx.dhgr.snowflake.ripple.a +++ b/src/fx/fx.dhgr.snowflake.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SNOWFL.RIP",plain +!to "build/FX.INDEXED/DHGR.SNOWFL.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.soft.diagonal.a b/src/fx/fx.dhgr.soft.diagonal.a index b6d81c5..5799927 100644 --- a/src/fx/fx.dhgr.soft.diagonal.a +++ b/src/fx/fx.dhgr.soft.diagonal.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am ; !cpu 6502 -!to "build/FX/DHGR.SOFT.DIAG",plain +!to "build/FX.INDEXED/DHGR.SOFT.DIAG",plain *=$6000 src = $F0 diff --git a/src/fx/fx.dhgr.soft.iris.a b/src/fx/fx.dhgr.soft.iris.a index de20e4f..8b2eca0 100644 --- a/src/fx/fx.dhgr.soft.iris.a +++ b/src/fx/fx.dhgr.soft.iris.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SOFT.IRIS",plain +!to "build/FX.INDEXED/DHGR.SOFT.IRIS",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.soft.iris.in.a b/src/fx/fx.dhgr.soft.iris.in.a index 49bc1f7..4df4e31 100644 --- a/src/fx/fx.dhgr.soft.iris.in.a +++ b/src/fx/fx.dhgr.soft.iris.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SOFTIRISIN",plain +!to "build/FX.INDEXED/DHGR.SOFTIRISIN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.star.a b/src/fx/fx.dhgr.star.a index a791058..e9523d9 100644 --- a/src/fx/fx.dhgr.star.a +++ b/src/fx/fx.dhgr.star.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.STAR",plain +!to "build/FX.INDEXED/DHGR.STAR",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.star.in.a b/src/fx/fx.dhgr.star.in.a index 510abd1..d8c2574 100644 --- a/src/fx/fx.dhgr.star.in.a +++ b/src/fx/fx.dhgr.star.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.STAR.IN",plain +!to "build/FX.INDEXED/DHGR.STAR.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.star.ripple.a b/src/fx/fx.dhgr.star.ripple.a index c45cd0e..2e48b40 100644 --- a/src/fx/fx.dhgr.star.ripple.a +++ b/src/fx/fx.dhgr.star.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.STAR.RIP",plain +!to "build/FX.INDEXED/DHGR.STAR.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.swirl.a b/src/fx/fx.dhgr.swirl.a index d2f68bc..c7a270a 100644 --- a/src/fx/fx.dhgr.swirl.a +++ b/src/fx/fx.dhgr.swirl.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SWIRL",plain +!to "build/FX.INDEXED/DHGR.SWIRL",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.wavy.iris.a b/src/fx/fx.dhgr.wavy.iris.a index 9356a39..1740b0d 100644 --- a/src/fx/fx.dhgr.wavy.iris.a +++ b/src/fx/fx.dhgr.wavy.iris.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.WAVY.IRIS",plain +!to "build/FX.INDEXED/DHGR.WAVY.IRIS",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.iris.bloom.a b/src/fx/fx.dhgr.wavy.iris.bloom.a index 1c312e1..b732dc9 100644 --- a/src/fx/fx.dhgr.wavy.iris.bloom.a +++ b/src/fx/fx.dhgr.wavy.iris.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BLOOM",plain +!to "build/FX.INDEXED/DHGR.BLOOM",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.iris.bloom.in.a b/src/fx/fx.dhgr.wavy.iris.bloom.in.a index 6da6cf2..f29cbaf 100644 --- a/src/fx/fx.dhgr.wavy.iris.bloom.in.a +++ b/src/fx/fx.dhgr.wavy.iris.bloom.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BLOOM.IN",plain +!to "build/FX.INDEXED/DHGR.BLOOM.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.iris.in.a b/src/fx/fx.dhgr.wavy.iris.in.a index c20e1f9..1cbefb8 100644 --- a/src/fx/fx.dhgr.wavy.iris.in.a +++ b/src/fx/fx.dhgr.wavy.iris.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.WAVY.IN",plain +!to "build/FX.INDEXED/DHGR.WAVY.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.ripple.a b/src/fx/fx.dhgr.wavy.ripple.a index a0ba687..9769d8f 100644 --- a/src/fx/fx.dhgr.wavy.ripple.a +++ b/src/fx/fx.dhgr.wavy.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.WAVY.RIP",plain +!to "build/FX.INDEXED/DHGR.WAVY.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.ripple.bloom.a b/src/fx/fx.dhgr.wavy.ripple.bloom.a index 729e08a..c6476e8 100644 --- a/src/fx/fx.dhgr.wavy.ripple.bloom.a +++ b/src/fx/fx.dhgr.wavy.ripple.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BLOOM.RIP",plain +!to "build/FX.INDEXED/DHGR.BLOOM.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.gr.fizzle.a b/src/fx/fx.gr.fizzle.a index 53e30a0..6a51c34 100644 --- a/src/fx/fx.gr.fizzle.a +++ b/src/fx/fx.gr.fizzle.a @@ -1,86 +1,57 @@ ;license:MIT -;(c) 2019 by qkumba +;(c) 2017-2021 by qkumba/4am/John Brooks !cpu 6502 -!to "build/FX/GR.FIZZLE",plain -*=$6400 +!to "build/GR.FIZZLE",plain +*=$6000 - ;init RNG + !source "src/fx/macros.a" - ldx #1 - stx @rnd1+1 - dex - stx @rnd2+1 + +OVERCOPY_TO_0 start, end + ;$FF clobbered + ;X=0 + ;Y=0 + jmp loop - ;iterate - -@loop - ldy @rnd1+1 - ldx @rnd2+1 - lsr @rnd2+1 - ror @rnd1+1 +start +!pseudopc 0 { + ;X=0 + ;Y=0 +loop txa +loop1 eor #$05 ; LFSR form 0x0500 with period 2047 +wait inx + bpl wait + tax +loop2 txa + and #$03 + ora #$04 + sta 127 then we're done +ROW_X_TO_BASE_ADDRESSES +ROW_X_TO_MIRROR_ADDRESSES diff --git a/src/fx/fx.hgr.precomputed.2bit.a b/src/fx/fx.hgr.precomputed.2bit.a index 89fa891..e097002 100644 --- a/src/fx/fx.hgr.precomputed.2bit.a +++ b/src/fx/fx.hgr.precomputed.2bit.a @@ -265,11 +265,7 @@ zerotbl !byte $f0, $f2, $ca, $d2, $d8, $e0, $e2, $e6, $ea, $ee +BUILD_HGR_LOOKUP_TABLES hgrlo, hgr1hi +BUILD_MIRROR_COLS mirror_cols +BUILD_SPARSE_BITMASKS_2BIT copymasks, mirror_copymasks - ldx #(end-start-1) ; copy InputLoop code to zero page -- lda start, x - sta $0, x - dex - bpl - + +COPY_TO_0 start, end jmp InputLoop start !pseudopc 0 { @@ -277,7 +273,7 @@ Exit2Bit rts InputLoop ldy #0 input=*+1 - ldx .coords, y ; first value: HGR row + 1 + ldx .coords ; first value: HGR row + 1 beq Exit2Bit ; if 0 then we're done +ROW_X_TO_2BIT_BASE_ADDRESSES diff --git a/src/fx/fx.hgr.precomputed.3bit.a b/src/fx/fx.hgr.precomputed.3bit.a index 9082695..bb42a9c 100644 --- a/src/fx/fx.hgr.precomputed.3bit.a +++ b/src/fx/fx.hgr.precomputed.3bit.a @@ -228,11 +228,7 @@ ripplezp +BUILD_3BIT_HGR_LOOKUP_TABLES +BUILD_EXTRA_COLS +BUILD_SPARSE_BITMASKS_3BIT - ldx #(end-start-1) ; copy InputLoop code to zero page -- lda start, x - sta $0, x - dex - bpl - + +COPY_TO_0 start, end jmp InputLoop start !pseudopc 0 { @@ -240,7 +236,7 @@ Exit3Bit rts InputLoop ldy #0 input=*+1 - lda .coords, y + lda .coords bmi Exit3Bit ; if high bit is 1 then we're done cmp #$40 php diff --git a/src/fx/fx.hgr.r.by.2.a b/src/fx/fx.hgr.r.by.2.a index a53e4d8..ee0c265 100644 --- a/src/fx/fx.hgr.r.by.2.a +++ b/src/fx/fx.hgr.r.by.2.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/R.BY.2",plain +!to "build/FX.INDEXED/R.BY.2",plain *=$6000 maskindex = $fd diff --git a/src/fx/fx.hgr.r.by.palette.a b/src/fx/fx.hgr.r.by.palette.a index 6ded648..6fadb55 100644 --- a/src/fx/fx.hgr.r.by.palette.a +++ b/src/fx/fx.hgr.r.by.palette.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/R.BY.PALETTE",plain +!to "build/FX.INDEXED/R.BY.PALETTE",plain *=$6000 maskindex = $fd diff --git a/src/fx/fx.hgr.r.by.pixel.a b/src/fx/fx.hgr.r.by.pixel.a index cbf7204..d0e4fae 100644 --- a/src/fx/fx.hgr.r.by.pixel.a +++ b/src/fx/fx.hgr.r.by.pixel.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/R.BY.PIXEL",plain +!to "build/FX.INDEXED/R.BY.PIXEL",plain *=$6000 maskindex = $fd diff --git a/src/fx/fx.hgr.radbubbles.a b/src/fx/fx.hgr.radbubbles.a index f4fa515..ce41c03 100644 --- a/src/fx/fx.hgr.radbubbles.a +++ b/src/fx/fx.hgr.radbubbles.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/RADBUBBLES",plain +!to "build/FX.INDEXED/RADBUBBLES",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.radial.a b/src/fx/fx.hgr.radial.a index aaaa8b3..4a3a8ff 100644 --- a/src/fx/fx.hgr.radial.a +++ b/src/fx/fx.hgr.radial.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL",plain +!to "build/FX.INDEXED/RADIAL",plain *=$6000 mirror_src1 = $E8 ; word diff --git a/src/fx/fx.hgr.radial2.a b/src/fx/fx.hgr.radial2.a index 4dda4c1..fcab75b 100644 --- a/src/fx/fx.hgr.radial2.a +++ b/src/fx/fx.hgr.radial2.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL2",plain +!to "build/FX.INDEXED/RADIAL2",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.radial3.a b/src/fx/fx.hgr.radial3.a index 1def09f..98bab27 100644 --- a/src/fx/fx.hgr.radial3.a +++ b/src/fx/fx.hgr.radial3.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL3",plain +!to "build/FX.INDEXED/RADIAL3",plain *=$6000 mirror_src1 = $E8 ; word diff --git a/src/fx/fx.hgr.radial4.a b/src/fx/fx.hgr.radial4.a index b614635..20c8f69 100644 --- a/src/fx/fx.hgr.radial4.a +++ b/src/fx/fx.hgr.radial4.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL4",plain +!to "build/FX.INDEXED/RADIAL4",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.radial5.a b/src/fx/fx.hgr.radial5.a index 4909ec9..d8264e6 100644 --- a/src/fx/fx.hgr.radial5.a +++ b/src/fx/fx.hgr.radial5.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL5",plain +!to "build/FX.INDEXED/RADIAL5",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.redlines.a b/src/fx/fx.hgr.redlines.a index 3e842bc..1767a02 100644 --- a/src/fx/fx.hgr.redlines.a +++ b/src/fx/fx.hgr.redlines.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am ; !cpu 6502 -!to "build/FX/REDLINES",plain +!to "build/FX.INDEXED/REDLINES",plain *=$6000 row1 = $fe diff --git a/src/fx/fx.hgr.ripple.a b/src/fx/fx.hgr.ripple.a index cba1417..5968631 100644 --- a/src/fx/fx.hgr.ripple.a +++ b/src/fx/fx.hgr.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RIPPLE",plain +!to "build/FX.INDEXED/RIPPLE",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.slow.star.a b/src/fx/fx.hgr.slow.star.a index a8eb19b..7c8394d 100644 --- a/src/fx/fx.hgr.slow.star.a +++ b/src/fx/fx.hgr.slow.star.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SLOW.STAR",plain +!to "build/FX.INDEXED/SLOW.STAR",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.slow.star.in.a b/src/fx/fx.hgr.slow.star.in.a index 57aa474..add2bd4 100644 --- a/src/fx/fx.hgr.slow.star.in.a +++ b/src/fx/fx.hgr.slow.star.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SLOW.STAR.IN",plain +!to "build/FX.INDEXED/SLOW.STAR.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.slow.star.ripple.a b/src/fx/fx.hgr.slow.star.ripple.a index 4813cbe..aa34013 100644 --- a/src/fx/fx.hgr.slow.star.ripple.a +++ b/src/fx/fx.hgr.slow.star.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SLOW.STAR.RIP",plain +!to "build/FX.INDEXED/SLOW.STAR.RIP",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.snowflake.a b/src/fx/fx.hgr.snowflake.a index d0c5dfc..7d06a9c 100644 --- a/src/fx/fx.hgr.snowflake.a +++ b/src/fx/fx.hgr.snowflake.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SNOWFLAKE",plain +!to "build/FX.INDEXED/SNOWFLAKE",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.snowflake.in.a b/src/fx/fx.hgr.snowflake.in.a index 15a51a7..425eb26 100644 --- a/src/fx/fx.hgr.snowflake.in.a +++ b/src/fx/fx.hgr.snowflake.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SNOWFLAKE.IN",plain +!to "build/FX.INDEXED/SNOWFLAKE.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.snowflake.ripple.a b/src/fx/fx.hgr.snowflake.ripple.a index 97b3d87..3cc75e0 100644 --- a/src/fx/fx.hgr.snowflake.ripple.a +++ b/src/fx/fx.hgr.snowflake.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SNOWFLAKE.RIP",plain +!to "build/FX.INDEXED/SNOWFLAKE.RIP",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.soft.diagonal.a b/src/fx/fx.hgr.soft.diagonal.a index 3471bee..b0c87ef 100644 --- a/src/fx/fx.hgr.soft.diagonal.a +++ b/src/fx/fx.hgr.soft.diagonal.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.DIAGONAL",plain +!to "build/FX.INDEXED/SOFT.DIAGONAL",plain *=$6000 y = $fc diff --git a/src/fx/fx.hgr.soft.iris.a b/src/fx/fx.hgr.soft.iris.a index 01dedf9..bd78ef8 100644 --- a/src/fx/fx.hgr.soft.iris.a +++ b/src/fx/fx.hgr.soft.iris.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SOFT.IRIS",plain +!to "build/FX.INDEXED/SOFT.IRIS",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.soft.iris.in.a b/src/fx/fx.hgr.soft.iris.in.a index c6424ee..9c747dc 100644 --- a/src/fx/fx.hgr.soft.iris.in.a +++ b/src/fx/fx.hgr.soft.iris.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SOFT.IRIS.IN",plain +!to "build/FX.INDEXED/SOFT.IRIS.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.soft.l.a b/src/fx/fx.hgr.soft.l.a index 8928a5a..7d3c06f 100644 --- a/src/fx/fx.hgr.soft.l.a +++ b/src/fx/fx.hgr.soft.l.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.L",plain +!to "build/FX.INDEXED/SOFT.L",plain *=$6000 y = $fc diff --git a/src/fx/fx.hgr.soft.r.a b/src/fx/fx.hgr.soft.r.a index 0807982..998b57e 100644 --- a/src/fx/fx.hgr.soft.r.a +++ b/src/fx/fx.hgr.soft.r.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.R",plain +!to "build/FX.INDEXED/SOFT.R",plain *=$6000 y = $fc diff --git a/src/fx/fx.hgr.soft.ud.a b/src/fx/fx.hgr.soft.ud.a index 73ec170..b0a0530 100644 --- a/src/fx/fx.hgr.soft.ud.a +++ b/src/fx/fx.hgr.soft.ud.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.UD",plain +!to "build/FX.INDEXED/SOFT.UD",plain *=$6000 maskindex = $fc diff --git a/src/fx/fx.hgr.soft.ud.in.a b/src/fx/fx.hgr.soft.ud.in.a index d90cdfc..b478295 100644 --- a/src/fx/fx.hgr.soft.ud.in.a +++ b/src/fx/fx.hgr.soft.ud.in.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.UD.IN",plain +!to "build/FX.INDEXED/SOFT.UD.IN",plain *=$6000 maskindex = $fc diff --git a/src/fx/fx.hgr.soft.ud.out.a b/src/fx/fx.hgr.soft.ud.out.a index 75eb4f3..089d963 100644 --- a/src/fx/fx.hgr.soft.ud.out.a +++ b/src/fx/fx.hgr.soft.ud.out.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.UD.OUT",plain +!to "build/FX.INDEXED/SOFT.UD.OUT",plain *=$6000 maskindex = $fc diff --git a/src/fx/fx.hgr.spiral.a b/src/fx/fx.hgr.spiral.a index 87e7b1d..dec91fd 100644 --- a/src/fx/fx.hgr.spiral.a +++ b/src/fx/fx.hgr.spiral.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/SPIRAL",plain +!to "build/FX.INDEXED/SPIRAL",plain *=$6000 !source "src/constants.a" diff --git a/src/fx/fx.hgr.split.ud.intro.a b/src/fx/fx.hgr.split.ud.intro.a index bf66463..611fd44 100644 --- a/src/fx/fx.hgr.split.ud.intro.a +++ b/src/fx/fx.hgr.split.ud.intro.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/SPLIT.UD.INTRO",plain +!to "build/FX.INDEXED/SPLIT.UD.INTRO",plain *=$6000 !source "src/fx/macros.a" diff --git a/src/fx/fx.hgr.stagger.lr.a b/src/fx/fx.hgr.stagger.lr.a index 1a1e303..cc44f03 100644 --- a/src/fx/fx.hgr.stagger.lr.a +++ b/src/fx/fx.hgr.stagger.lr.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/STAGGER.LR",plain +!to "build/FX.INDEXED/STAGGER.LR",plain *=$6000 row = $fd diff --git a/src/fx/fx.hgr.stagger.lr.white.a b/src/fx/fx.hgr.stagger.lr.white.a index e4a1b78..42686bb 100644 --- a/src/fx/fx.hgr.stagger.lr.white.a +++ b/src/fx/fx.hgr.stagger.lr.white.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/STAGGERWHITE.LR",plain +!to "build/FX.INDEXED/STAGGERWHITE.LR",plain *=$6000 row = $fd diff --git a/src/fx/fx.hgr.stagger.ud.a b/src/fx/fx.hgr.stagger.ud.a index 17e3e07..c10cc83 100644 --- a/src/fx/fx.hgr.stagger.ud.a +++ b/src/fx/fx.hgr.stagger.ud.a @@ -1,5 +1,5 @@ !cpu 6502 -!to "build/FX/STAGGER.UD",plain +!to "build/FX.INDEXED/STAGGER.UD",plain *=$6000 row1 = $fe diff --git a/src/fx/fx.hgr.stagger.ud.white.a b/src/fx/fx.hgr.stagger.ud.white.a index 642fc08..16dc523 100644 --- a/src/fx/fx.hgr.stagger.ud.white.a +++ b/src/fx/fx.hgr.stagger.ud.white.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/STAGGERWHITE.UD",plain +!to "build/FX.INDEXED/STAGGERWHITE.UD",plain *=$6000 row1 = $fe diff --git a/src/fx/fx.hgr.star.a b/src/fx/fx.hgr.star.a index 7969607..4a17ee3 100644 --- a/src/fx/fx.hgr.star.a +++ b/src/fx/fx.hgr.star.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/STAR",plain +!to "build/FX.INDEXED/STAR",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.star.bloom.a b/src/fx/fx.hgr.star.bloom.a index 7c6cbdd..0eefc7c 100644 --- a/src/fx/fx.hgr.star.bloom.a +++ b/src/fx/fx.hgr.star.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/STAR.BLOOM",plain +!to "build/FX.INDEXED/STAR.BLOOM",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.star.in.a b/src/fx/fx.hgr.star.in.a index e0eeab1..d0bb60e 100644 --- a/src/fx/fx.hgr.star.in.a +++ b/src/fx/fx.hgr.star.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/STAR.IN",plain +!to "build/FX.INDEXED/STAR.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.star.ripple.a b/src/fx/fx.hgr.star.ripple.a index 2ac2b82..d4410a7 100644 --- a/src/fx/fx.hgr.star.ripple.a +++ b/src/fx/fx.hgr.star.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/STAR.RIPPLE",plain +!to "build/FX.INDEXED/STAR.RIPPLE",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.swirl.a b/src/fx/fx.hgr.swirl.a index 0cf9d92..49410fe 100644 --- a/src/fx/fx.hgr.swirl.a +++ b/src/fx/fx.hgr.swirl.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SWIRL",plain +!to "build/FX.INDEXED/SWIRL",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.tri.fizzle.a b/src/fx/fx.hgr.tri.fizzle.a index f831211..adf4628 100644 --- a/src/fx/fx.hgr.tri.fizzle.a +++ b/src/fx/fx.hgr.tri.fizzle.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/TRI.FIZZLE",plain +!to "build/FX.INDEXED/TRI.FIZZLE",plain *=$6000 phase = $FC ; byte, $80 or $00 diff --git a/src/fx/fx.hgr.vertical.blinds.a b/src/fx/fx.hgr.vertical.blinds.a index cb5c9de..b2063d2 100755 --- a/src/fx/fx.hgr.vertical.blinds.a +++ b/src/fx/fx.hgr.vertical.blinds.a @@ -2,7 +2,7 @@ ;(c) 2019 by qkumba ; !cpu 6502 -!to "build/FX/VERTICAL.BLINDS",plain +!to "build/FX.INDEXED/VERTICAL.BLINDS",plain *=$6000 ldx #0 diff --git a/src/fx/fx.hgr.wavy.iris.a b/src/fx/fx.hgr.wavy.iris.a index 3abbbe1..8bcaed9 100644 --- a/src/fx/fx.hgr.wavy.iris.a +++ b/src/fx/fx.hgr.wavy.iris.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/WAVY.IRIS",plain +!to "build/FX.INDEXED/WAVY.IRIS",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.iris.bloom.a b/src/fx/fx.hgr.wavy.iris.bloom.a index 76d7a7a..1a1fb1a 100644 --- a/src/fx/fx.hgr.wavy.iris.bloom.a +++ b/src/fx/fx.hgr.wavy.iris.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/W.IRIS.BLOOM",plain +!to "build/FX.INDEXED/W.IRIS.BLOOM",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.iris.bloom.in.a b/src/fx/fx.hgr.wavy.iris.bloom.in.a index 143bd95..5d8d976 100644 --- a/src/fx/fx.hgr.wavy.iris.bloom.in.a +++ b/src/fx/fx.hgr.wavy.iris.bloom.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/W.IRIS.BLOOM.IN",plain +!to "build/FX.INDEXED/W.IRIS.BLOOM.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.iris.in.a b/src/fx/fx.hgr.wavy.iris.in.a index e0c9faa..80752ef 100644 --- a/src/fx/fx.hgr.wavy.iris.in.a +++ b/src/fx/fx.hgr.wavy.iris.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/WAVY.IRIS.IN",plain +!to "build/FX.INDEXED/WAVY.IRIS.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.ripple.a b/src/fx/fx.hgr.wavy.ripple.a index 3a10272..67640d3 100644 --- a/src/fx/fx.hgr.wavy.ripple.a +++ b/src/fx/fx.hgr.wavy.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/WAVY.RIPPLE",plain +!to "build/FX.INDEXED/WAVY.RIPPLE",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.ripple.bloom.a b/src/fx/fx.hgr.wavy.ripple.bloom.a index 31c5cbf..6e58880 100644 --- a/src/fx/fx.hgr.wavy.ripple.bloom.a +++ b/src/fx/fx.hgr.wavy.ripple.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/W.RIPPLE.BLOOM",plain +!to "build/FX.INDEXED/W.RIPPLE.BLOOM",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.shr.2pass.lr.a b/src/fx/fx.shr.2pass.lr.a new file mode 100644 index 0000000..8528d13 --- /dev/null +++ b/src/fx/fx.shr.2pass.lr.a @@ -0,0 +1,51 @@ +;license:MIT +;(c) 2021 by 4am + +!cpu 6502 +!to "build/FX.INDEXED/SHR.TWOPASS.LR",plain +*=$A000 + +shrlo = $301 ; $C8 bytes, indexed as shrlo-1,x +shrhi = $38 ; $C8 bytes, indexed as shrhi-1,x + + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + + +COPY_TO_0 start, end + +BUILD_SHR_LOOKUP_TABLES shrlo, shrhi + ;X=0 + +COPY_SCB_AND_PALETTES + ;WRITEAUXMEM active + + jmp loop1 + +start +!pseudopc 0 { +loop1 ldy #0 +loop2 ldx #1 +loop3 lda shrlo, x + sta $38 { + !error "code is too large: ends at ", end-start +} diff --git a/src/fx/fx.shr.80boxes.a b/src/fx/fx.shr.80boxes.a new file mode 100644 index 0000000..311505b --- /dev/null +++ b/src/fx/fx.shr.80boxes.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am & qkumba +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80BOXES",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2,$F1,$F0 + !byte $FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2,$F1 + !byte $FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2 + !byte $FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3 + !byte $FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4 + !byte $FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5 + !byte $FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6 + !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7 + +StageInitialIndexes + !byte 1 + !byte 2 + !byte 3 + !byte 4 + !byte 5 + !byte 6 + !byte 7 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.arrow.a b/src/fx/fx.shr.80boxes.arrow.a new file mode 100644 index 0000000..242b155 --- /dev/null +++ b/src/fx/fx.shr.80boxes.arrow.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.ARROW",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC,$EA,$E8 + !byte $FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC,$EA + !byte $FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC + !byte $00,$FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE + !byte $FF,$FD,$FB,$F9,$F7,$F5,$F3,$F1,$EF,$ED + !byte $FD,$FB,$F9,$F7,$F5,$F3,$F1,$EF,$ED,$EB + !byte $FB,$F9,$F7,$F5,$F3,$F1,$EF,$ED,$EB,$E9 + !byte $F9,$F7,$F5,$F3,$F1,$EF,$ED,$EB,$E9,$E7 + +StageInitialIndexes + !byte 1 + !byte 2 + !byte 3 + !byte 4 + !byte 5 + !byte 6 + !byte 7 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.common.a b/src/fx/fx.shr.80boxes.common.a new file mode 100644 index 0000000..f307638 --- /dev/null +++ b/src/fx/fx.shr.80boxes.common.a @@ -0,0 +1,229 @@ +;license:MIT +;(c) 2021 by 4am & qkumba +; +; The SHR screen in 320x200 mode is separated into 80 boxes. +; Boxes are laid out in a grid, left-to-right, top-down: +; +; 0 1 2 3 4 5 6 7 8 9 +; 10 11 12 13 14 15 16 17 18 19 +; 20 21 22 23 24 25 26 27 28 29 +; 30 31 32 33 34 35 36 37 38 39 +; 40 41 42 43 44 45 46 47 48 49 +; 50 51 52 53 54 55 56 57 58 59 +; 60 61 62 63 64 65 66 67 68 69 +; 70 71 72 73 74 75 76 77 78 79 +; +; Each box is 32x25 pixels, so each row of each box is 16 consecutive +; bytes in memory (2 pixels per byte) once you calculate the SHR base +; address for that row. +; +; |BoxInitialStages| defines the initial grid of stages for each box. +; Each stage is used as an index into the |StageInitialIndexes| array +; to find the drawing routine for that stage (if any). +; Each box's stage is incremented after each iteration through the main loop. +; When the main loop iterates through all 80 boxes without drawing anything, +; the program exits. +; +; There are 7 copy routines that copy certain pixels from the source +; image in mainmem to the destination image in auxmem. Technically +; these all have the same entry point, with X = 1..7 on entry. +; We always copy pixels in horizontal pairs, meaning we can just copy +; bytes without having to worry about masking high and low nibbles. +; +; row| pixels +; ---+.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- +; 00 |77777777777777777777777777777777 +; 01 |77777777777777777777777777777777 +; 02 |77666666666666666666666666666677 +; 03 |77666666666666666666666666666677 +; 04 |77665555555555555555555555556677 +; 05 |77665555555555555555555555556677 +; 06 |77665544444444444444444444556677 +; 07 |77665544444444444444444444556677 +; 08 |77665544333333333333333344556677 +; 09 |77665544333333333333333344556677 +; 10 |77665544332222222222223344556677 +; 11 |77665544332222222222223344556677 +; 12 |77665544332211111111223344556677 +; 13 |77665544332222222222223344556677 +; 14 |77665544332222222222223344556677 +; 15 |77665544333333333333333344556677 +; 16 |77665544333333333333333344556677 +; 17 |77665544444444444444444444556677 +; 18 |77665544444444444444444444556677 +; 19 |77665555555555555555555555556677 +; 20 |77665555555555555555555555556677 +; 21 |77666666666666666666666666666677 +; 22 |77666666666666666666666666666677 +; 23 |77777777777777777777777777777777 +; 24 |77777777777777777777777777777777 +; + +!macro SET_ROW_X { +; out: Z=0 because shrhi is never 0 + lda shrlo, x + sta $FF) { + !error "Code is too big to fit on zero page! ", *-start +} + +BoxInitialStages diff --git a/src/fx/fx.shr.80boxes.down.a b/src/fx/fx.shr.80boxes.down.a new file mode 100644 index 0000000..1b44355 --- /dev/null +++ b/src/fx/fx.shr.80boxes.down.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.DOWN",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF + !byte $FE,$FD,$FE,$FD,$FE,$FD,$FE,$FD,$FE,$FD + !byte $FC,$FB,$FC,$FB,$FC,$FB,$FC,$FB,$FC,$FB + !byte $FA,$F9,$FA,$F9,$FA,$F9,$FA,$F9,$FA,$F9 + !byte $F8,$F7,$F8,$F7,$F8,$F7,$F8,$F7,$F8,$F7 + !byte $F6,$F5,$F6,$F5,$F6,$F5,$F6,$F5,$F6,$F5 + !byte $F4,$F3,$F4,$F3,$F4,$F3,$F4,$F3,$F4,$F3 + !byte $F2,$F1,$F2,$F1,$F2,$F1,$F2,$F1,$F2,$F1 + +StageInitialIndexes + !byte 7,0,0 + !byte 6,0,0 + !byte 5,0,0 + !byte 4,0,0 + !byte 3,0,0 + !byte 2,0,0 + !byte 1 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.sidetoside.a b/src/fx/fx.shr.80boxes.sidetoside.a new file mode 100644 index 0000000..96b5877 --- /dev/null +++ b/src/fx/fx.shr.80boxes.sidetoside.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am & qkumba +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.SIDE2",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0,$DC + !byte $DC,$E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC,$00 + !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0,$DC + !byte $DC,$E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC,$00 + !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0,$DC + !byte $DC,$E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC,$00 + !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0,$DC + !byte $DC,$E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC,$00 + +StageInitialIndexes + !byte 1,1 + !byte 2,1 + !byte 3,1 + !byte 4,1 + !byte 5,1 + !byte 6,1 + !byte 7,1 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.snake.a b/src/fx/fx.shr.80boxes.snake.a new file mode 100644 index 0000000..80b1233 --- /dev/null +++ b/src/fx/fx.shr.80boxes.snake.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.SNAKE",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7 + !byte $ED,$EE,$EF,$F0,$F1,$F2,$F3,$F4,$F5,$F6 + !byte $EC,$EB,$EA,$E9,$E8,$E7,$E6,$E5,$E4,$E3 + !byte $D9,$DA,$DB,$DC,$DD,$DE,$DF,$E0,$E1,$E2 + !byte $D8,$D7,$D6,$D5,$D4,$D3,$D2,$D1,$D0,$CF + !byte $C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE + !byte $C4,$C3,$C2,$C1,$C0,$BF,$BE,$BD,$BC,$BB + !byte $B1,$B2,$B3,$B4,$B5,$B6,$B7,$B8,$B9,$BA + +StageInitialIndexes + !byte 7,7,7 + !byte 6,6,6 + !byte 5,5,5 + !byte 4,4,4 + !byte 3,3,3 + !byte 2,2,2 + !byte 1,1,1 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.spiral.a b/src/fx/fx.shr.80boxes.spiral.a new file mode 100644 index 0000000..b16f97d --- /dev/null +++ b/src/fx/fx.shr.80boxes.spiral.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.SPIRAL",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $E9,$E8,$E7,$E6,$E5,$E4,$E3,$E2,$E1,$00 + !byte $EA,$CF,$CE,$CD,$CC,$CB,$CA,$C9,$E0,$FF + !byte $EB,$D0,$BD,$BC,$BB,$BA,$B9,$C8,$DF,$FE + !byte $EC,$D1,$BE,$B3,$B2,$B1,$B8,$C7,$DE,$FD + !byte $ED,$D2,$BF,$B4,$B5,$B6,$B7,$C6,$DD,$FC + !byte $EE,$D3,$C0,$C1,$C2,$C3,$C4,$C5,$DC,$FB + !byte $EF,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$DB,$FA + !byte $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7,$F8,$F9 + +StageInitialIndexes + !byte 7,7,0 + !byte 6,6,0 + !byte 5,5,0 + !byte 4,4,0 + !byte 3,3,0 + !byte 2,2,0 + !byte 1,1 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.common.a b/src/fx/fx.shr.common.a new file mode 100644 index 0000000..3aa0799 --- /dev/null +++ b/src/fx/fx.shr.common.a @@ -0,0 +1,231 @@ +;license:MIT +;(c) 2021 by 4am + +!macro BUILD_SHR_LOOKUP_TABLES .lo, .hi { +; in: none +; out: X=0 +; Z=1 + ldx #$C8 + lda #$60 + ldy #$9C +- sta .lo-1, x +!if .hi < $100 { + sty .hi-1, x +} else { + pha + tya + sta .hi-1, x + pla +} + sec + sbc #$A0 + bcs + + dey ++ dex + bne - +} + +!macro BUILD_SHR_REVERSE_LOOKUP_TABLES .lo, .hi { +; in: none +; out: X=0 +; Z=1 + ldx #$C8 + lda #$00 + ldy #$20 +- sta .lo-1, x +!if .hi < $100 { + sty .hi-1, x +} else { + pha + tya + sta .hi-1, x + pla +} + clc + adc #$A0 + bcc + + iny ++ dex + bne - +} + +!macro COPY_SCB_AND_PALETTES { +; in: X=0 /!\ +; out: X=0 +; Z=1 +; WRITEAUXMEM active + sta $C005 +- lda $9D00, x + sta $9D00, x + lda $9E00, x + sta $9E00, x + lda $9F00, x + sta $9F00, x + inx + bne - +} + +!macro BUILD_SHR_MIRROR_ROWS_AND_COLS .mirror_rows, .mirror_cols { +; out: X=0 +; Z=1 + ldx #$C7 + ldy #$00 +- tya + sta .mirror_cols-$28, x + sta .mirror_rows-1, x + iny + dex + bne - +} + +!macro SHR_COPY_TO_STAGE_2 { +; in: X=0 /!\ +; out: X=0 +; Z=1 +; WRITEMAINMEM active + +WRITE_MAIN +- lda $A000, x + sta $9D00, x + lda $A100, x + sta $9E00, x + inx + bne - +} + +!macro SHR_RESTORE_FROM_STAGE_2 { +; out: X=0 +; Z=1 + ldx #$00 +- lda $9D00, x ; copy main code back to $A000 + sta $A000, x ; so it can be called again if necessary + lda $9E00, x + sta $A100, x + inx + bne - +} + +!macro LOAD_SHR_COORDINATES_AT .coords, .filename, .scratch { +; out: WRITEMAINMEM active +; LC RAM2 active and read/write + ldx .filename ; LOAD_FILE_AT macro destroys pathname +- lda .filename, x ; so we need to make a copy + sta .scratch, x + dex + bpl - + + +READ_RAM2_WRITE_RAM2 + +LOAD_FILE_AT .scratch, .coords +} + +!macro SHR_STAGE_1 .shrlo, .shrhi, .mirror_rows, .mirror_cols { + +BUILD_SHR_MIRROR_ROWS_AND_COLS .mirror_rows, .mirror_cols + ;X=0 + +BUILD_SHR_LOOKUP_TABLES .shrlo, .shrhi + ;X=0 + +COPY_SCB_AND_PALETTES + ;X=0 + ;WRITEAUXMEM active + +SHR_COPY_TO_STAGE_2 +} + +!macro SHR_STAGE_2 .startzp, .endzp { + +COPY_TO_0 .startzp, .endzp + + +WRITE_AUX + jsr $0 + +WRITE_MAIN + + +SHR_RESTORE_FROM_STAGE_2 + +READ_RAM1_WRITE_RAM1 +} + +!macro SHR_STAGE_3 .coords, .shrlo, .shrhi, .mirror_rows, .mirror_cols { +input ldx .coords ; first value: SHR row (only 0..99 will be in input array) + bmi exit ; if > 127 then we're done + ldy #1 + lda (.coords + sta $f1 + lda #<(.coords + .length - 2) + sta $f2 + lda #>(.coords + .length - 2) + sta $f3 + clc + !byte $24 +- sec +-- lda ($f0), y + pha + lda ($f2), y + sta ($f0), y + pla + sta ($f2), y + iny + bcc - + ldy #0 + !byte $24 +- clc + inc $f0 + bne + + inc $f1 ++ lda $f1 + eor #>(.coords + .length/2) + bne + + lda $f0 + eor #<(.coords + .length/2) + beq ++ ++ lda $f2 + bne + + dec $f3 ++ dec $f2 + bcs - + bcc -- ; always +++ +} diff --git a/src/fx/fx.shr.diagonal.a b/src/fx/fx.shr.diagonal.a new file mode 100644 index 0000000..52b7998 --- /dev/null +++ b/src/fx/fx.shr.diagonal.a @@ -0,0 +1,63 @@ +;license:MIT +;(c) 2021 by 4am + +!cpu 6502 +!to "build/FX.INDEXED/SHR.DIAGONAL",plain +*=$A000 + +shrlo = $301 ; $C8 bytes, indexed as shrlo-1,x +shrhi = $201 ; $C8 bytes, indexed as shrhi-1,x + + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + + +COPY_TO_0 start, end + +BUILD_SHR_LOOKUP_TABLES shrlo, shrhi + ;X=0 + +COPY_SCB_AND_PALETTES + ;WRITEAUXMEM active + + jmp colloop + +start +!pseudopc 0 { +colloop + ldx #$C8 +startcollo=*+1 + ldy #$9F ; SMC +startcolhi=*+1 + lda #$00 + sta palettes + sta src+1 + ldx #$0F ; palette counter ($0F -> $00, not used as index) +rb_palette_loop + ldy #$00 ; byte offset within palette (00 -> 1F, used as index) +rb_color_loop + lda #$00 + sta fracv + sta fracv_hi + sta color + lda src + sta dst + lda src+1 + sec + sbc #>(palettes-$4000) + sta dst+1 + lda (src), y ; get final Red or Blue value for this color in this palette + asl ; Red or Blue value is bits 0-3, shift them into bits 4-7 + asl + asl + asl + sta incv +rb_step_loop + lda fracv + clc + adc incv + sta fracv + bcc + + lda fracv_hi + eor #$01 + sta fracv_hi + bne + + inc color ++ lda color + sta (dst), y + inc dst+1 + inc dst+1 + bpl rb_step_loop + iny + cpy #$20 + bcc rb_color_loop + lda src + clc + adc #$20 + sta src + bcc + + inc src+1 ++ dex + bpl rb_palette_loop + + lda #>palettes + sta src+1 + ldx #$0F ; palette counter ($0F -> $00, not used as index) +g_palette_loop + ldy #$00 ; byte offset within palette (00 -> 1E by 2, used as index) +g_color_loop + lda #$00 + sta fracv + sta fracv_hi + sta color + lda src + sta dst + lda src+1 + sec + sbc #>(palettes-$4000) + sta dst+1 + lda (src), y ; get final Green value for this color in this palette + and #$F0 ; Green value is bits 4-7, mask out other bits + sta incv +g_step_loop + lda fracv + clc + adc incv + sta fracv + bcc + + lda fracv_hi + eor #$01 + sta fracv_hi + bne + + lda color + clc + adc #$10 + sta color ++ lda color + ora (dst), y ; keep existing Blue value in bits 0-3 + sta (dst), y + inc dst+1 + inc dst+1 + bpl g_step_loop + iny + iny ; high nibble of second color byte is always 0 so skip it + cpy #$20 + bcc g_color_loop + lda src + clc + adc #$20 + sta src + bcc + + inc src+1 ++ dex + bpl g_palette_loop + + ldx #$44 + stx copy1+2 + inx + stx copy2+2 + lda #$40 + sta incv + ldx #$1D + ldy #$00 +copyloop jsr WaitForVBL + sta $C005 +copy1 lda $4400, y ; SMC + sta $9E00, y +copy2 lda $4500, y ; SMC + sta $9F00, y + iny + bne copy1 + sta $C004 + inc copy1+2 + inc copy1+2 + inc copy2+2 + inc copy2+2 + lda incv + jsr WaitForKeyWithTimeout + bmi exit + dec incv + dec incv + dex + bpl copyloop +exit jmp UnwaitForVBL + + !source "src/wait.a" diff --git a/src/fx/fx.shr.fizzle.a b/src/fx/fx.shr.fizzle.a index d707a64..dc569d1 100644 --- a/src/fx/fx.shr.fizzle.a +++ b/src/fx/fx.shr.fizzle.a @@ -2,11 +2,13 @@ ;(c) 2019-2020 by qkumba/4am/John Brooks !cpu 6502 -!to "build/FX/SHR.FIZZLE",plain +!to "build/FX.INDEXED/SHR.FIZZLE",plain *=$A000 -addrs=$80 ; [128 bytes] -src=addrs-$20 ; [word] + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + +addrs=$7F ; [128 bytes] lda #$A0 ; create address lookup table tax @@ -15,22 +17,28 @@ src=addrs-$20 ; [word] sty addrs-$21, x dex bne - - sta $C005 -- lda $9D00, y ; pre-copy SHR SCB and palette - sta $9D00, y - lda $9E00, y - sta $9E00, y - lda $9F00, y - sta $9F00, y - iny - bne - + + +OVERCOPY_TO_0 start, end + ;$FF clobbered + ;X=0 + ;Y=0 + + +COPY_SCB_AND_PALETTES + ;WRITEAUXMEM active + + jmp loop + +start +!pseudopc 0 { + ;X=0 + ;Y=0 loop txa loop1 eor #$60 ; LFSR form 0x6000 with period 32767 tax loop2 lda addrs, x - sta src+1 - lda (src), y - sta (src), y + sta shrhi { + !error "code is too large: ends at ", end-start +} diff --git a/src/fx/fx.shr.lr2.a b/src/fx/fx.shr.lr2.a new file mode 100644 index 0000000..a9a95eb --- /dev/null +++ b/src/fx/fx.shr.lr2.a @@ -0,0 +1,50 @@ +;license:MIT +;(c) 2021 by 4am + +!cpu 6502 +!to "build/FX.INDEXED/SHR.LR2",plain +*=$A000 + +shrlo = $301 ; $C8 bytes, indexed as shrlo-1,x +shrhi = $38 ; $C8 bytes, indexed as shrhi-1,x + + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + + +COPY_TO_0 start, end + +BUILD_SHR_LOOKUP_TABLES shrlo, shrhi + ;X=0 + +COPY_SCB_AND_PALETTES + ;WRITEAUXMEM active + + jmp loop1 + +start +!pseudopc 0 { +loop1 ldy #1 +loop2 ldx #$C8 +loop3 lda shrlo-1, x + sta $38 { + !error "code is too large: ends at ", end-start +} diff --git a/src/fx/fx.shr.radial.a b/src/fx/fx.shr.radial.a new file mode 100644 index 0000000..f438ee1 --- /dev/null +++ b/src/fx/fx.shr.radial.a @@ -0,0 +1,127 @@ +;license:MIT +;(c) 2021 by 4am +; +!cpu 6502 +!to "build/FX.INDEXED/SHR.RADIAL",plain +*=$A000 + +mirror_rows = $106 ; $C8 bytes +shrlo = $200 ; $C8 bytes +shrhi = $300 ; $C8 bytes +coords = $9F00 ; $1F41 bytes +last_coords = coords+$1F3E +CoordinatesFileCopy = $BE42; $11 bytes +mirror_cols = $BE60 ; $A0 bytes but clobbers $27 previous bytes during construction + + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + + +SHR_STAGE_1 shrlo, shrhi, mirror_rows, mirror_cols + jmp stage2 + +!pseudopc *-$300 { +stage2 + +LOAD_SHR_COORDINATES_AT coords, CoordinatesFile, CoordinatesFileCopy + ;WRITEMAINMEM active + + lda #$80 + sta coords-2 + + +SHR_STAGE_2 startzp, endzp + rts + +startzp +!pseudopc 0 { + ; bottom-left quadrant (opposite row, original column, reverse input order) +LoopBL ldx last_coords ; SMC + bmi LoopTL + lda mirror_rows, x + tax + ldy #1 + lda (LoopBL+1), y + tay + jsr copy + lda $38 { + !error "code is too large: ends at ", end-start +} diff --git a/src/fx/macros.a b/src/fx/macros.a index ee25618..c60890b 100644 --- a/src/fx/macros.a +++ b/src/fx/macros.a @@ -6,12 +6,14 @@ ; posted on comp.sys.apple2 on 2018-07-11 ; https://groups.google.com/d/msg/comp.sys.apple2/v2HOfHOmeNQ/zD76fJg_BAAJ !macro BUILD_HGR_LOOKUP_TABLES .hgrlo, .hgr1hi { +; preserves Y ldx #0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 .hgrlo, .hgr1hi } ; use this macro instead if you know X is already 0 on entry, to save 2 bytes !macro BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 .hgrlo, .hgr1hi { +; preserves Y - txa and #$F8 bpl + @@ -159,5 +161,27 @@ + } +!macro COPY_TO_0 .start, .end { +; out: X=0 +; Z=1 + ldx #(.end-.start) +- lda .start-1, x + sta $FF, x + dex + bne - +} + +!macro OVERCOPY_TO_0 .start, .end { +; over-copy region to $00 +; clobbers $FF +; out: X=0 +; Y=last byte before start (e.g. 0 if the last instruction is JMP $0000) + ldx #(.end-.start+1) +- ldy .start-2, x + sty $FE, x + dex + bne - +} + _FX_MACROS_=* } diff --git a/src/glue.decompress.a b/src/glue.decompress.a index 4f781d3..c9fa018 100644 --- a/src/glue.decompress.a +++ b/src/glue.decompress.a @@ -53,12 +53,11 @@ DecompressHGR pha lda auxreq bne + - jmp LoadFile ; load decompression code to $200 -+ jmp LoadAuxFile ; load decompression code to $200/aux + jmp LoadIndexedFile ; load decompression code to $200 ++ jmp LoadAuxIndexedFile ; load decompression code to $200/aux @loaddecrunch - !word kRootDirectory - !word kDecrunchFile !word $200 + !word kDecrunchRecord ldx auxreq sta READMAINMEM,x ; X = 0 or 1, so this will be READMAINMEM or READAUXMEM sta WRITEMAINMEM,x ; X = 0 or 1, so this will be WRITEMAINMEM or WRITEAUXMEM diff --git a/src/glue.launch.a b/src/glue.launch.a index 825a40b..5df13a2 100644 --- a/src/glue.launch.a +++ b/src/glue.launch.a @@ -4,19 +4,20 @@ ; Functions to launch games and self-running demos ; ; Public functions +; - AnyGameSelected ; - GetGameToLaunch ; - FindGame -; - FindGameInActionSlideshow -; - GetGameDisplayName ; - PlayGame ; - Launch ; ; Public variables: -; - gGameToLaunch - 0-based index into gGamesListStore (word) +; - gGameToLaunch - 0-based index into gSearchStore (word) ; gGameToLaunch !word $FFFF +gLastMegaAttractGame + !word $FFFF ;------------------------------------------------------------------------------ ; AnyGameSelected @@ -30,15 +31,15 @@ gGameToLaunch ;------------------------------------------------------------------------------ AnyGameSelected +LD16 gGameToLaunch - +CMP16 $FFFF - bne ForceGoodResult + +CMP16_NE $FFFF, ForceGoodResult rts ; CMP sets carry when equal ;------------------------------------------------------------------------------ ; GetGameToLaunch ; get filename of game that is currently selected in the UI (if any) ; -; in: gGameToLaunch = index into gGamesListStore (word) or #$FFFF if no game selected +; in: gGameToLaunch = index into gSearchStore (word) or #$FFFF if no game selected +; gSearchStore populated ; out: C clear if a game is selected, and ; A/Y points to game filename ; C set if no game is selected @@ -47,7 +48,7 @@ GetGameToLaunch jsr AnyGameSelected bcs _gameToLaunchExit +ST16 WINDEX - +LDADDR gGamesListStore + +LDADDR gSearchStore jsr okvs_nth ForceGoodResult clc @@ -56,130 +57,53 @@ _gameToLaunchExit ;------------------------------------------------------------------------------ ; FindGame -; check if an arbitrary game exists, for some definition of 'exists' -; -; in: A/Y points to game filename -; out: C clear if game exists in gGamesListStore, and -; $WINDEX = game index, or #$FFFF if the game doesn't really -; exist but we want to return a successful result anyway -; C set if game does not exist (this can happen because slideshows -; list games that require a joystick, but the games list parser -; filters them out if the machine doesn't have a joystick) -; all registers clobbered -;------------------------------------------------------------------------------ -FindGame - +ST16 @key - jsr okvs_find - !word gGamesListStore -@key !word $FDFD ; SMC - bcc GlueLaunchRTS -; Hack to allow self-running demos that don't correspond to a game -; filename. If the name ends in a '.', accept it unconditionally. - ldx #$FF - stx WINDEX - stx WINDEX+1 - +LD16 @key - +ST16 PARAM - ldy #0 - lda (PARAM),y - tay - lda (PARAM),y - cmp #"." - beq ForceGoodResult - sec -GlueLaunchRTS - rts - -;------------------------------------------------------------------------------ -; FindGameInActionSlideshow ; check if an arbitrary game exists, for some definition of 'exists', while ; in the middle of a slideshow ; -; /!\ This function assumes that gSlideshowStore exists and is populated, -; which is generally only true during the callback function of a slideshow -; -; in: A/Y points to game filename -; out: C clear if game exists, and -; $WINDEX = game index, and -; A/Y points to game display name + game info bitfield -; C set if game can't be found by any means +; in: A/Y points to a key in gSlideshowStore +; out: C clear if game exists and is playable on current machine, and +; (SAVE) -> game display name, and +; (gLastMegaAttractGame) -> game filename +; C set otherwise +; clobbers $FF, PTR +; all registers clobbered ;------------------------------------------------------------------------------ -FindGameInActionSlideshow - +ST16 @sskey - jsr FindGame - bcc GetGameDisplayName -; if the game was not found, try getting the value of the current record from -; gSlideshowStore (some games have multiple action screenshots, in which case -; the key is only the screenshot filename, and the value is the actual game -; filename) - jsr okvs_get - !word gSlideshowStore -@sskey !word $FDFD ; SMC - jsr FindGame - bcs GlueLaunchRTS - ; /!\ execution falls through here to GetGameDisplayName - -;------------------------------------------------------------------------------ -; GetGameDisplayName -; lookup or construct the display name for a specific game -; -; in: A/Y contains address of a key in gGamesListStore -; out: A/Y contains address of game display name + game info bitfield -; (this might be just the corresponding value in gGamesListStore, -; or it might be a temporary buffer in main memory that we constructed -; out of thin air) -; gValLen possibly clobbered (up to gValLen+MaxInputLength) -; X preserved -; C clear -;------------------------------------------------------------------------------ -GetGameDisplayName - +ST16 SAVE - jsr okvs_get_current ; get value for this key - ; (PTR) -> truncated game display name + info bitfield - ldy #0 - lda (PTR), y ; A = length of truncated game display name + info bitfield - cmp #1 ; 1 means there's no title, just info bitfield (1 byte) +FindGame + +ST16 gLastMegaAttractGame + jsr okvs_next_field ; (PTR) -> OKVS value (filename or empty string) + ; Y=0 + lda (PTR), y beq + +LD16 PTR + +ST16 gLastMegaAttractGame ++ jsr okvs_next_field_PTR_is_already_set ; (PTR) -> game display name + +LD16 PTR ; A/Y -> game display name + +ST16 SAVE ; (SAVE) -> game display name + jsr okvs_next_field ; (PTR) -> game requirements bitfield + ; Y=0 + + ; check if game requires joystick + lda (PTR), y + sta $FF + bpl @check128K + lda MachineStatus + and #HAS_JOYSTICK + beq @failedCheck ; machine doesn't have joystick but game requires it + +@check128K + ; check if game requires 128K + bit $FF + bvc @passedAllChecks + lda MachineStatus + and #HAS_128K + beq @failedCheck ; machine doesn't have 128K but game requires it + +@passedAllChecks clc rts -+ ; game display name is truncated, we must expand it - iny ; Y = 1 - lda (PTR), y ; A = game info bitfield - pha ; save on stack - dey - lda (SAVE), y ; A = length of key - tay - iny - sty @len - sty gValLen - lda #$24 ; BIT opcode - sta @or ; first character remains capitalized - ldy #1 -- lda (SAVE), y - cmp #$49 ; 'I' - bne + - cmp gValLen-1,y - beq ++ ; preserve 'II' casing -+ cmp #$2E - bne @or - lda #$20 ; convert '.' to ' ' -@or ora #$20 ; SMC (opcode) -++ sta gValLen, y - cmp #$20 - bne + - lda #$24 ; first character after ' ' remains capitalized - +HIDE_NEXT_2_BYTES -+ lda #$09 ; OR opcode - sta @or -@next iny -@len=*+1 - cpy #$FD ; SMC - bne - - pla - sta gValLen, y - +LDADDR gValLen - clc + +@failedCheck + sec rts ;------------------------------------------------------------------------------ @@ -194,16 +118,26 @@ GetGameDisplayName PlayGame jsr GetGameToLaunch ; A/Y = address of game filename +PlayGameInAY +ST16 SAVE +ST16 @pfile jsr ClearScreens ; avoid seeing code load into the HGR page ; (clobbers $106, must do now before loading prelaunch code) - jsr LoadFile ; load this game's prelaunch file at $106 - !word kPrelaunchDirectory -@pfile !word $FDFD + jsr LoadIndexedFile ; load prelaunch index file +- !word gSearchCache + !word kPrelaunchIndexRecord + + jsr okvs_find + !word - +@pfile !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile !word $0106 +@indexRecordPtr + !word $FDFD ; SMC ; we start by placing the subdirectory name at gPathname+kGameDirectoryLen ; to leave room for the GameDirectory name as the parent @@ -264,14 +198,16 @@ Launch jmp LaunchInternal Joystick - jsr LoadFile - !word kPrelaunchDirectory - !word kStandardPrelaunch - !word $0106 + jsr LoadStandardPrelaunch - jsr LoadFile - !word kRootDirectory - !word kJoystickFile - !word 0 + jsr LoadIndexedFile + !word $800 + !word kJoystickRecord jmp Launch + +LoadStandardPrelaunch + jsr LoadIndexedFile ; load standard prelaunch code at $0106 + !word $0106 + !word kStandardPrelaunchRecord + rts diff --git a/src/glue.launch.lc2.a b/src/glue.launch.lc2.a index f62863b..700ff73 100644 --- a/src/glue.launch.lc2.a +++ b/src/glue.launch.lc2.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-9 by 4am & qkumba +;(c) 2018-2021 by 4am & qkumba ; ; Functions to launch games and self-running demos ; @@ -8,17 +8,18 @@ ; which handle bank switching for you. LaunchInternal - ldy #$F1 -- lda $100,y - sta STACKBASE - $EF,y ; back up stack - iny - bne - tsx ; back up stack pointer stx STACKPTR + 1 - sty RestoreStackNextTime + 1 + inx +- pla + sta STACKBASE - $100 + gStackSize,x + ; back up stack + inx + bne - + stx RestoreStackNextTime + 1 ; tell |Reenter| to restore the stack and stack pointer - tya + txa ldy #$18 - sta $bf57,y dey diff --git a/src/glue.prorwts2.a b/src/glue.prorwts2.a index db33600..97efa23 100644 --- a/src/glue.prorwts2.a +++ b/src/glue.prorwts2.a @@ -1,22 +1,21 @@ ;license:MIT -;(c) 2018-2020 by 4am & qkumba +;(c) 2018-2021 by 4am & qkumba ; ; ProRWTS2 glue functions ; ; Public functions ; - LoadFile -; - LoadDHRFile -; -; Public variables -; - gRootDirectory +; - LoadAuxFile +; - LoadIndexedFile +; - LoadAuxIndexedFile ; ; A general note about paths: ; -; LoadFile, LoadDHRFile, and SaveSmallFile support subdirectories. -; Directories are delimited by '/' like ProDOS. At program startup, we get the -; current directory and save it; that is the PROGRAM ROOT DIRECTORY. All -; pathnames are relative to the PROGRAM ROOT DIRECTORY. There is no concept of -; setting or changing the 'current' directory. +; Load[*]File routines support subdirectories. Directories are delimited by '/' +; like ProDOS. At program startup, we get the current directory and save it; +; that is the PROGRAM ROOT DIRECTORY. All pathnames are relative to the PROGRAM +; ROOT DIRECTORY. There is no concept of setting or changing the 'current' +; directory. ; ; The PROGRAM ROOT DIRECTORY is not guaranteed to be the root directory of the ; underlying ProDOS disk (although it can be). But it doesn't matter, because @@ -33,8 +32,8 @@ ; PROGRAM ROOT DIRECTORY. ;------------------------------------------------------------------------------ -; LoadFile -; Load a file into memory all at once, using ProRWTS2 +; LoadFile/LoadAuxFile +; Load a file into main or auxiliary memory, all at once, using ProRWTS2 ; ; supports paths, see note ; @@ -47,67 +46,131 @@ ; gPathname clobbered ;------------------------------------------------------------------------------ LoadFile - +PARAMS_ON_STACK 6 + ldx #7 + bne .loadcommon +LoadAuxFile + ldx #6 +.loadcommon + pla + sta PARAM + txa + pha + and #6 + clc + adc PARAM + tay + pla + tax + pla + sta PARAM+1 + adc #0 + pha + tya + pha + txa + pha +LDPARAM 1 jsr SetPath +LDPARAM 3 jsr AddToPath + plp + php + bmi + +LDPARAMPTR 5, ldrlo ; set load address - jsr SwitchToBank2 ++ jsr SwitchToBank2 + plp + bcc + jsr LoadFileInternal jmp SwitchToBank1 - -;------------------------------------------------------------------------------ -; LoadAuxFile -; Load a file into aux memory all at once, using ProRWTS2 -; -; supports paths, see note -; -; in: stack contains 6 bytes of parameters: -; +1 [word] address of length-prefixed pathname -; +3 [word] address of length-prefixed filename -; +5 [word] address to load file, or 0 to use file's default address -; out: all flags clobbered -; all registers clobbered -; gPathname clobbered -;------------------------------------------------------------------------------ -LoadAuxFile - +PARAMS_ON_STACK 6 - +LDPARAM 1 - jsr SetPath - +LDPARAM 3 - jsr AddToPath - +LDPARAMPTR 5, ldrlo ; set load address - jsr SwitchToBank2 - lda #1 ; request aux memory ++ ldx #1 ; request aux memory jsr LoadFileAuxInternal jmp SwitchToBank1 ;------------------------------------------------------------------------------ -; LoadDHRFile -; load .A2FC file (uncompressed double hi-res graphics) into memory -; all at once, using ProRWTS2 -; first $2000 bytes of file are loaded into auxiliary memory $4000..$5FFF -; second $2000 bytes of file are loaded into main memory $4000..$4FFF +; LoadIndexedFile/LoadAuxIndexedFile +; Load a file from inside an indexed file, all at once, into main or auxiliary +; memory ; -; supports paths, see note +; To save disk space, some collections of small, related files (e.g. per-game +; help files) are merged into a single data file with an associated index file. +; The index stores the original filename along with an offset (into the merged +; data file) and a length. +; +; Callers are responsible for loading the index file and finding the relevant +; record within the index. Most callers use okvs_find() for this, although some +; have hard-coded records generated at build time. ; ; in: stack contains 4 bytes of parameters: -; +1 [word] address of length-prefixed pathname -; +3 [word] address of length-prefixed filename +; +1 [word] address of load destination +; +3 [word] pointer to index record ; out: all flags clobbered ; all registers clobbered -; stack set to next instruction after parameters ;------------------------------------------------------------------------------ -LoadDHRFile +LoadAuxIndexedFile + lda #$EE ; INC + +HIDE_NEXT_2_BYTES +LoadIndexedFile + lda #$8D ; STA + sta @iauxreq +PARAMS_ON_STACK 4 - +LDPARAM 1 - jsr SetPath - +LDPARAM 3 - jsr AddToPath + +LDPARAMPTR 1, @address + +LDPARAMPTR 3, zpword + inc $BF0E ; disable ROM mapping on return jsr SwitchToBank2 - jsr LoadDHRFileInternal + jsr resetRoot + ldx #2 + ldy #0 + lda (zpword), y + tay +- iny + lda (zpword), y + sta @offset, x + dex + bpl - + dex +- iny + lda (zpword), y + sta @size - $fe, x + inx + bmi - + jsr $bf00 ; yes, ProDOS abstraction + !byte $c8 + !word @c8_parms + jsr $bf00 + !byte $ce + !word @ce_parms +@iauxreq + sta SavedZP + auxreq - first_zp + ; SMC + + jsr $bf00 + !byte $ca + !word @ca_parms + sta auxreq + jsr $bf00 + !byte $cc + !word @cc_parms + jsr swap_zpg ; restore sizelo2/hi2 + dec $BF0E ; re-enable ROM mapping on return + +LD16 @address + sta ldrlo2 ; support Launch of what we just loaded + sty ldrhi2 jmp SwitchToBank1 -gRootDirectory - !word $FDFD +@c8_parms + !byte 3 +@filename + !word kTotalDataFile + !byte 0 +@ce_parms + !byte $d0 + !byte 1 +@offset !byte 0, 0, 0 ; SMC + !byte $ff +@ca_parms + !byte $ff +@cc_parms + !byte 1 +@address !word $DFDF ; SMC +@size !word $DFDF ; SMC + !word $ffff diff --git a/src/glue.prorwts2.lc2.a b/src/glue.prorwts2.lc2.a index c68bfcc..0ca28ec 100644 --- a/src/glue.prorwts2.lc2.a +++ b/src/glue.prorwts2.lc2.a @@ -8,25 +8,19 @@ ; and parse.prefs which handle bank switching for you. LoadFileInternal - lda #0 ; 0 = read into main memory + ldx #0 ; 0 = read into main memory LoadFileAuxInternal - sta @auxreq+1 ; call with A=1 to load directly into aux memory +LDADDR gPathname -!if RELBASE != $2000 { - !ifdef PASS2 { - } else { ;PASS2 - !if * != LoadFileDirect { - !error "LoadFileDirect=",*, ", fix constants.a" - } - } -} +LoadFileDirect +ST16 namlo ; set filename + txa + pha jsr traverse ; go to subdirectory, set up filename for read lda #cmdread ; read (instead of write) sta reqcmd lsr sta auxreq - lda ldrlo+1 + lda ldrhi bne + ; if caller provided a load address, use it sta sizelo ; otherwise query the load address from file metadata sta sizehi ; 0 = query load address @@ -34,43 +28,13 @@ LoadFileAuxInternal +LD16 ldrlo2 +ST16 ldrlo + lda #$FF ; read entire file (ProRWTS2 will figure out exact size) +LoadFileInternal_SizePatch sta sizehi -!if RELBASE != $2000 { - !ifdef PASS2 { - } else { ;PASS2 - !if *+1 != iAuxReq { - !error "iAuxReq=",*+1, ", fix constants.a" - } - } -} -@auxreq - lda #0 + pla sta auxreq JumpOpen jmp hddopendir ; exit via ProRWTS2 -LoadDHRFileInternal - +LDADDR gPathname - +ST16 namlo ; set filename - jsr traverse ; go to subdirectory, set up filename for read - lda #$20 - sta sizehi - asl - sta ldrhi ; into $4000 - lda #cmdread ; read (instead of write) - sta reqcmd - ;;lda #1 ; 1 = read into aux memory - sta auxreq - lsr ; read first $2000 bytes - sta sizelo - sta ldrlo - jsr hddopendir ; call ProRWTS2 - lda #$20 ; read next $2000 bytes - sta sizehi - dec auxreq ; 0 = read into main memory - clc ; not a subdirectory - jmp hddrdwrpart ; call ProRWTS2 - SaveSmallFileInternal +LDADDR gPathname +ST16 namlo ; set filename for ProRWTS2 @@ -80,10 +44,10 @@ SaveSmallFileInternal lda #0 ; 0 = read into main memory sta sizelo ;sta sizehi ; 0 = query load address - ;jsr hddopendir ; call ProRWTS2 + ;jsr hddopendir ; call ProRWTS2 ;lda ldrlo2 sta ldrlo - lda #$80 ;lda ldrhi2 + lda #>kGlobalPrefsBuffer ;lda ldrhi2 sta ldrhi lda #cmdwrite ; write (instead of read) sta reqcmd diff --git a/src/hw.accel.a b/src/hw.accel.a index 9f92c2e..5c8e706 100755 --- a/src/hw.accel.a +++ b/src/hw.accel.a @@ -44,7 +44,7 @@ ; ; WARNING: The memory location to set the accelerator ; speed may overlap existing locations such as: -; annuciators or Apple //c specific hardware +; annunciators or Apple //c specific hardware ; paddle trigger ; ; Known to work: IIGS, //c+ @@ -232,6 +232,7 @@ build_addon ; setspeed must be self-modified before use (setspeed_x and ; setspeed_y). ; +; all return with Z=0 ;----------------------------------------------------------- ; Function #1: Apple IIc+ @@ -250,17 +251,17 @@ iicplus !pseudopc DisableAccelerator { ; cgga calls save X and Y regs but sets $0 to 0 ; (this will get a laugh from C programmers) + php lda $0 pha - php sei ; timing sensitive jsr @jiggerypokery lda gMachineInDHGRMode bne + ; DHGR mode doesn't need fix sta $C05B ; fix HGR-mode colouring -+ plp ; restore interrupt state - pla ++ pla sta $0 + plp ; restore interrupt state rts @jiggerypokery diff --git a/src/hw.accel.lc2.a b/src/hw.accel.lc2.a index 5287d12..de10056 100644 --- a/src/hw.accel.lc2.a +++ b/src/hw.accel.lc2.a @@ -5,13 +5,13 @@ ; Apple II models, cards, and environments ; ; /!\ These live in LC RAM 2 and rely on other code which is also in LC RAM 2. /!\ -; (EnableAccelerator and DisableAccelerator are copied into LC2 in 4sports.init.) +; (EnableAccelerator and DisableAccelerator are copied into LC2 in 4cade.init.) ; You can call these functions directly if and only if you are already in LC2. EnableAcceleratorAndSwitchToBank1 jsr EnableAccelerator - jmp SwitchToBank1 + bne + ; always taken DisableAcceleratorAndSwitchToBank1 jsr DisableAccelerator - jmp SwitchToBank1 ++ jmp SwitchToBank1 diff --git a/src/hw.joystick.a b/src/hw.joystick.a index 1260eee..813c23f 100644 --- a/src/hw.joystick.a +++ b/src/hw.joystick.a @@ -16,7 +16,6 @@ ; Fastchip firmware 0.4b-compatibility fix by Frank M. (0.5b seems unaffected) ;------------------------------------------------------------------------------ HasJoystick - lda $FBB3 cmp #$06 bne ++ diff --git a/src/hw.mockingboard.a b/src/hw.mockingboard.a index 05c36b7..72e3fd1 100644 --- a/src/hw.mockingboard.a +++ b/src/hw.mockingboard.a @@ -18,15 +18,26 @@ ; (zp$81 will contain the slot in form $Cx) ; /!\ ALL ACCELERATORS MUST BE OFF OR SET TO 1 MHZ ; out: if card was found, X = #$?n where n is the slot number of the card, otherwise #$00 -; and bit 6 = 0 if Mockingboard Sound I found -; or bit 6 = 1 if Mockingboard Sound II or "A" found -; and bit 7 = 1 if Mockingboard Sound/Speech I or "C" found +; and bit 5 = 0 if Mockingboard Sound I found +; or bit 5 = 1 if Mockingboard Sound II or "A"-"D" found +; and bit 6 = 1 if SSI-263 speech chip found +; or bit 7 = 1 if SC-01 speech chip found ; flags clobbered ; zp $80-$82 clobbered ; A/Y clobbered ;------------------------------------------------------------------------------ GetMockingboardStuff +ST16 @callback+1 + lda ROM_MACHINEID + cmp #$06 + bne @not_iic + ldx ROM_MACHINE2C + bne @not_iic + dex ; enable Mockingboard 4C support + stx $C403 + stx $C404 + +@not_iic lda #$00 sta $80 sta $82 ; type @@ -127,11 +138,13 @@ GetMockingboardStuff @wait_irq lda $80 - bne @got_irq + bne + iny bne @wait_irq inx bne @wait_irq + clc ++ ror $82 ; detect speech - SC-01 ;based on S/S I demo dsk @@ -159,24 +172,22 @@ GetMockingboardStuff bne - inx bne - - clc ; not found - bcc @got_irq + beq @got_irq @mb_smc21 + sta $c40d ; ifr, clear flag lda #$00 ; turn off cb2 pulse mode to disable false writes to sc01 @mb_smc22 sta $c40c ; pcr - sec ; found, we have an S/S I + sec ; found, we have an SC-01 ror $82 - ldy #$ff - bcc @ssI + bne @ssI @got_irq sei + clc ; not found ror $82 -@onlyI ldy #$ff @mb_smc6 sty $c403 ; 6522#1 ddra @@ -190,16 +201,16 @@ GetMockingboardStuff sta ($80),y ; 6522#1 orb lda #4 sta ($80),y ; 6522#1 orb - dey + @ssI + ldy #$ff @mb_smc8 sty $c483 ; 6522#2 ddra lda #7 @mb_smc9 sta $c482 ; 6522#2 ddrb - iny - tya + lda #0 ldy #$80 sta ($80),y ; 6522#2 orb lda #4 diff --git a/src/hw.vbl.a b/src/hw.vbl.a index d0fa9b6..59aae8d 100644 --- a/src/hw.vbl.a +++ b/src/hw.vbl.a @@ -4,7 +4,7 @@ ; Functions to enable and disable VBL polling on various ; Apple II models -iWaitForVBL +iWaitForVBL sei ; IIc is special sta $C07F ; enable access to VBL register sta $C05B ; enable VBL polling diff --git a/src/index/artwork.idx.a b/src/index/artwork.idx.a new file mode 100644 index 0000000..0744b33 --- /dev/null +++ b/src/index/artwork.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/ARTWORK.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1444524 + !le16 496 diff --git a/src/index/attract.idx.a b/src/index/attract.idx.a new file mode 100644 index 0000000..9676cab --- /dev/null +++ b/src/index/attract.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/ATTRACT.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1434095 + !le16 917 diff --git a/src/index/cache00.idx.a b/src/index/cache00.idx.a new file mode 100644 index 0000000..12478d4 --- /dev/null +++ b/src/index/cache00.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/CACHE00.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1427723 + !le16 214 diff --git a/src/index/cache01.idx.a b/src/index/cache01.idx.a new file mode 100644 index 0000000..07c09e0 --- /dev/null +++ b/src/index/cache01.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/CACHE01.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1428988 + !le16 458 diff --git a/src/index/cache10.idx.a b/src/index/cache10.idx.a new file mode 100644 index 0000000..8f1e420 --- /dev/null +++ b/src/index/cache10.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/CACHE10.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1430525 + !le16 399 diff --git a/src/index/cache11.idx.a b/src/index/cache11.idx.a new file mode 100644 index 0000000..926d9e1 --- /dev/null +++ b/src/index/cache11.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/CACHE11.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1432610 + !le16 688 diff --git a/src/index/count00.a b/src/index/count00.a new file mode 100644 index 0000000..d5fd9b3 --- /dev/null +++ b/src/index/count00.a @@ -0,0 +1,6 @@ +; +; Game count +; +; This file is automatically generated +; +!word 15 diff --git a/src/index/count01.a b/src/index/count01.a new file mode 100644 index 0000000..a734be3 --- /dev/null +++ b/src/index/count01.a @@ -0,0 +1,6 @@ +; +; Game count +; +; This file is automatically generated +; +!word 26 diff --git a/src/index/count10.a b/src/index/count10.a new file mode 100644 index 0000000..27451ad --- /dev/null +++ b/src/index/count10.a @@ -0,0 +1,6 @@ +; +; Game count +; +; This file is automatically generated +; +!word 29 diff --git a/src/index/count11.a b/src/index/count11.a new file mode 100644 index 0000000..27c64ac --- /dev/null +++ b/src/index/count11.a @@ -0,0 +1,6 @@ +; +; Game count +; +; This file is automatically generated +; +!word 43 diff --git a/src/index/coverfade.idx.a b/src/index/coverfade.idx.a new file mode 100644 index 0000000..419530e --- /dev/null +++ b/src/index/coverfade.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/COVERFADE +; +; This file is automatically generated +; + !byte 0 + !be24 1445020 + !le16 410 diff --git a/src/index/credits.idx.a b/src/index/credits.idx.a new file mode 100644 index 0000000..3c7f730 --- /dev/null +++ b/src/index/credits.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/CREDITS +; +; This file is automatically generated +; + !byte 0 + !be24 1445774 + !le16 256 diff --git a/src/index/decrunch.idx.a b/src/index/decrunch.idx.a new file mode 100644 index 0000000..fe2c5fb --- /dev/null +++ b/src/index/decrunch.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/DECRUNCH +; +; This file is automatically generated +; + !byte 0 + !be24 1446030 + !le16 303 diff --git a/src/index/dfx.idx.a b/src/index/dfx.idx.a new file mode 100644 index 0000000..a4f791c --- /dev/null +++ b/src/index/dfx.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DFX.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1437158 + !le16 1242 diff --git a/src/index/dgr.fizzle.idx.a b/src/index/dgr.fizzle.idx.a new file mode 100644 index 0000000..9b7dd4e --- /dev/null +++ b/src/index/dgr.fizzle.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DGR.FIZZLE +; +; This file is automatically generated +; + !byte 0 + !be24 1445506 + !le16 67 diff --git a/src/index/dgr.idx.a b/src/index/dgr.idx.a new file mode 100644 index 0000000..6751c2d --- /dev/null +++ b/src/index/dgr.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DGR.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1444512 + !le16 12 diff --git a/src/index/dhgr.idx.a b/src/index/dhgr.idx.a new file mode 100644 index 0000000..5ca3f31 --- /dev/null +++ b/src/index/dhgr.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DHGR.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1443721 + !le16 739 diff --git a/src/index/dtitle.idx.a b/src/index/dtitle.idx.a new file mode 100644 index 0000000..41be221 --- /dev/null +++ b/src/index/dtitle.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DTITLE.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442057 + !le16 216 diff --git a/src/index/fx.idx.a b/src/index/fx.idx.a new file mode 100644 index 0000000..4f9da1c --- /dev/null +++ b/src/index/fx.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/FX.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1435012 + !le16 2146 diff --git a/src/index/gamehelp.idx.a b/src/index/gamehelp.idx.a new file mode 100644 index 0000000..395baf0 --- /dev/null +++ b/src/index/gamehelp.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/GAMEHELP.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1438758 + !le16 797 diff --git a/src/index/gr.fizzle.idx.a b/src/index/gr.fizzle.idx.a new file mode 100644 index 0000000..801003a --- /dev/null +++ b/src/index/gr.fizzle.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/GR.FIZZLE +; +; This file is automatically generated +; + !byte 0 + !be24 1445430 + !le16 76 diff --git a/src/index/gr.idx.a b/src/index/gr.idx.a new file mode 100644 index 0000000..72d9619 --- /dev/null +++ b/src/index/gr.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/GR.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1444460 + !le16 52 diff --git a/src/index/helptext.idx.a b/src/index/helptext.idx.a new file mode 100644 index 0000000..1d32f4c --- /dev/null +++ b/src/index/helptext.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HELPTEXT +; +; This file is automatically generated +; + !byte 0 + !be24 1445573 + !le16 201 diff --git a/src/index/hgr0.idx.a b/src/index/hgr0.idx.a new file mode 100644 index 0000000..9913c25 --- /dev/null +++ b/src/index/hgr0.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR0.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442273 + !le16 335 diff --git a/src/index/hgr1.idx.a b/src/index/hgr1.idx.a new file mode 100644 index 0000000..710ad9a --- /dev/null +++ b/src/index/hgr1.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR1.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442608 + !le16 69 diff --git a/src/index/hgr2.idx.a b/src/index/hgr2.idx.a new file mode 100644 index 0000000..380f1c8 --- /dev/null +++ b/src/index/hgr2.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR2.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442677 + !le16 81 diff --git a/src/index/hgr3.idx.a b/src/index/hgr3.idx.a new file mode 100644 index 0000000..427d82e --- /dev/null +++ b/src/index/hgr3.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR3.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442758 + !le16 62 diff --git a/src/index/hgr4.idx.a b/src/index/hgr4.idx.a new file mode 100644 index 0000000..1461178 --- /dev/null +++ b/src/index/hgr4.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR4.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442820 + !le16 623 diff --git a/src/index/hgr5.idx.a b/src/index/hgr5.idx.a new file mode 100644 index 0000000..86ea705 --- /dev/null +++ b/src/index/hgr5.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR5.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1443443 + !le16 274 diff --git a/src/index/hgr6.idx.a b/src/index/hgr6.idx.a new file mode 100644 index 0000000..2fbb5d6 --- /dev/null +++ b/src/index/hgr6.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR6.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1443717 + !le16 4 diff --git a/src/index/joystick.idx.a b/src/index/joystick.idx.a new file mode 100644 index 0000000..d1ade85 --- /dev/null +++ b/src/index/joystick.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/JOYSTICK +; +; This file is automatically generated +; + !byte 0 + !be24 1446333 + !le16 2370 diff --git a/src/index/miniattract0.idx.a b/src/index/miniattract0.idx.a new file mode 100644 index 0000000..a8c86cc --- /dev/null +++ b/src/index/miniattract0.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/MINIATTRACT0.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1440617 + !le16 381 diff --git a/src/index/miniattract1.idx.a b/src/index/miniattract1.idx.a new file mode 100644 index 0000000..570af86 --- /dev/null +++ b/src/index/miniattract1.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/MINIATTRACT1.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1440998 + !le16 420 diff --git a/src/index/prelaunch.idx.a b/src/index/prelaunch.idx.a new file mode 100644 index 0000000..38891f2 --- /dev/null +++ b/src/index/prelaunch.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/PRELAUNCH.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1433298 + !le16 797 diff --git a/src/index/res.cover.idx.a b/src/index/res.cover.idx.a new file mode 100644 index 0000000..8ffe940 --- /dev/null +++ b/src/index/res.cover.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/COVER +; +; This file is automatically generated +; + !byte 0 + !be24 422443 + !le16 8184 diff --git a/src/index/res.help.idx.a b/src/index/res.help.idx.a new file mode 100644 index 0000000..26d34f5 --- /dev/null +++ b/src/index/res.help.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/HELP +; +; This file is automatically generated +; + !byte 0 + !be24 438819 + !le16 8184 diff --git a/src/index/res.title.idx.a b/src/index/res.title.idx.a new file mode 100644 index 0000000..80f59b5 --- /dev/null +++ b/src/index/res.title.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/TITLE +; +; This file is automatically generated +; + !byte 0 + !be24 430627 + !le16 8192 diff --git a/src/index/search00.idx.a b/src/index/search00.idx.a new file mode 100644 index 0000000..d214323 --- /dev/null +++ b/src/index/search00.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SEARCH00.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1427156 + !le16 567 diff --git a/src/index/search01.idx.a b/src/index/search01.idx.a new file mode 100644 index 0000000..ce4f6b4 --- /dev/null +++ b/src/index/search01.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SEARCH01.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1427937 + !le16 1051 diff --git a/src/index/search10.idx.a b/src/index/search10.idx.a new file mode 100644 index 0000000..2f94281 --- /dev/null +++ b/src/index/search10.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SEARCH10.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1429446 + !le16 1079 diff --git a/src/index/search11.idx.a b/src/index/search11.idx.a new file mode 100644 index 0000000..b42cbe8 --- /dev/null +++ b/src/index/search11.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SEARCH11.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1430924 + !le16 1686 diff --git a/src/index/sfx.idx.a b/src/index/sfx.idx.a new file mode 100644 index 0000000..a403c4d --- /dev/null +++ b/src/index/sfx.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SFX.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1438400 + !le16 358 diff --git a/src/index/slideshow.idx.a b/src/index/slideshow.idx.a new file mode 100644 index 0000000..3d16922 --- /dev/null +++ b/src/index/slideshow.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SLIDESHOW.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1439555 + !le16 1062 diff --git a/src/index/standard.prelaunch.a b/src/index/standard.prelaunch.a new file mode 100644 index 0000000..65ba825 --- /dev/null +++ b/src/index/standard.prelaunch.a @@ -0,0 +1,8 @@ +; +; Index record for standard prelaunch code +; +; The file is maintained by hand +; + !byte 0 + !be24 0 + !le16 PRELAUNCH_STANDARD_SIZE diff --git a/src/index/title.idx.a b/src/index/title.idx.a new file mode 100644 index 0000000..0c8e584 --- /dev/null +++ b/src/index/title.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/TITLE.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1441418 + !le16 639 diff --git a/src/macros.a b/src/macros.a index 6c5a8dd..ee9670d 100755 --- a/src/macros.a +++ b/src/macros.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; common assembler macros (6502 compatible) ; @@ -10,7 +10,8 @@ ; for functions that take parameters on the stack ; set (PARAM) to point to the parameters and ; move the stack pointer to the first byte after the parameters -; clobbers A,X,Y +; clobbers A,Y +; preserves X !macro PARAMS_ON_STACK .bytes { pla sta PARAM @@ -117,37 +118,51 @@ } ; compare a 16-bit value in A (low) and Y (high) to an absolute address +; branch to target if no match ; zeroes A! -!macro CMP16ADDR .addr { +!macro CMP16ADDR_NE .addr, .target { eor .addr - bne + + bne .target cpy .addr+1 -+ + bne .target } ; compare a 16-bit value in X (low) and Y (high) to an absolute address -!macro CPX16ADDR .addr { +; branch to target if no match +!macro CPX16ADDR_NE .addr, .target { cpx .addr - bne + + bne .target cpy .addr+1 + bne .target +} + +; compare a 16-bit value in A (low) and Y (high) to an immediate value +; branch to target if match +!macro CMP16_E .val, .target { + cmp #<.val + bne + + cpy #>.val + beq .target + } ; compare a 16-bit value in A (low) and Y (high) to an immediate value -!macro CMP16 .val { +; branch to target if no match +!macro CMP16_NE .val, .target { cmp #<.val - bne + + bne .target cpy #>.val -+ + bne .target } ; compare a 16-bit value in X (low) and Y (high) against zero +; branch to target if not zero ; requires LDX16 immediately prior, since Y comparison is implicit! ; destroys A! -!macro CPX16_0 { - bne + +!macro CPX16_0_NE .target { + bne .target txa -+ + bne .target } !macro LBPL .target { @@ -194,7 +209,7 @@ ; various language card configurations !macro READ_RAM1_NO_WRITE { - bit $C088 + sta $C088 } !macro READ_RAM1_WRITE_RAM1 { @@ -203,7 +218,7 @@ } !macro READ_RAM2_NO_WRITE { - bit $C080 + sta $C080 } !macro READ_RAM2_WRITE_RAM2 { @@ -222,7 +237,23 @@ } !macro READ_ROM_NO_WRITE { - bit $C082 + sta $C082 +} + +!macro READ_AUX { + sta READMAINMEM +} + +!macro READ_MAIN { + sta READAUXMEM +} + +!macro WRITE_AUX { + sta WRITEAUXMEM +} + +!macro WRITE_MAIN { + sta WRITEMAINMEM } ; requires setting zpCharMask in zero page to #$FF or #$DF before use @@ -283,18 +314,16 @@ +READ_ROM_NO_WRITE } -!macro GET_MOCKINGBOARD_SPEECH { ;carry set if present +!macro GET_MOCKINGBOARD_SPEECH { ;sign set if SC-01, overflow set if SSI-263 +READ_RAM2_NO_WRITE - lda MockingboardStuff - asl + bit MockingboardStuff +READ_ROM_NO_WRITE } -!macro GET_MOCKINGBOARD_SPEECH_AND_MACHINE_STATUS { ;carry set if present +!macro GET_MOCKINGBOARD_SPEECH_AND_MACHINE_STATUS { ;sign set if SC-01, overflow set if SSI-263 +READ_RAM2_NO_WRITE - lda MockingboardStuff - asl lda MachineStatus + bit MockingboardStuff +READ_ROM_NO_WRITE } @@ -302,6 +331,7 @@ +READ_RAM2_NO_WRITE lda MockingboardStuff cmp #1 + and #7 ora #$C0 +READ_ROM_NO_WRITE } @@ -310,11 +340,13 @@ +READ_RAM2_NO_WRITE lda MockingboardStuff cmp #1 + and #7 ora #$C0 tax lda MachineStatus +READ_ROM_NO_WRITE } + !macro USES_TEXT_PAGE_2 { lda ROM_MACHINEID cmp #$06 @@ -330,28 +362,80 @@ !macro RESET_VECTOR .addr { lda #<.addr sta $3F2 + !ifndef .addr { + !set emitted=1 + lda #>.addr + sta $3F3 + eor #$A5 + sta $3F4 + } else { + !ifdef emitted { + lda #>.addr + sta $3F3 + eor #$A5 + sta $3F4 + } else { + !if (>.addr != 1) or (.addr = $100) { + lda #>.addr + sta $3F3 + eor #$A5 + sta $3F4 + } + } + } +} + +!macro RESET_VECTOR_HALF .addr { lda #>.addr sta $3F3 eor #$A5 sta $3F4 } +!macro RESET_AND_IRQ_VECTOR .addr { + lda #<.addr + sta $3F2 + sta $3FE + lda #>.addr + sta $3F3 + sta $3FF + eor #$A5 + sta $3F4 +} ; for games that clobber $100-$105, the prelaunch code constructs a new reset vector ; somewhere else and sets its !macro NEW_RESET_VECTOR .addr { + ldx #5 +- lda $100,x + sta .addr,x + dex + bpl - + +RESET_VECTOR .addr +} + +!macro NEW_RESET_VECTOR_64K .addr { lda #$2C sta .addr - lda #$88 + lda #$89 sta .addr+1 lda #$C0 sta .addr+2 - lda #$6C ; JMP ($FFFC) points to 'Reenter' + lda #$4C ; JMP $FAA6 to reboot sta .addr+3 - lda #$FC + lda #$A6 sta .addr+4 - lda #$FF + lda #$FA sta .addr+5 - +RESET_VECTOR .addr + lda #<.addr + sta $3F2 + sta $FFFC + !if >.addr != 1 { + lda #>.addr + sta $3F3 + sta $FFFD + eor #$A5 + sta $3F4 + } } ; for 64k games on ][+ which either hang or restart @@ -370,23 +454,78 @@ ; load an external file by pathname ; LC RAM 2 MUST BE BANKED IN -; LOW BYTE OF .addr MUST BE $00 +; set .addr to $0000 to load to any aligned addres in main +; LOW BYTE OF .addr MUST BE $00 IN THAT CASE !macro LOAD_FILE_AT .filepath, .addr { - lda #0 - sta iAuxReq ; read to main memory + !if .addr > 0 { lda #>.addr sta ldrhi + } + !if <.addr > 0 { + lda #<.addr + sta ldrlo + } lda iCurBlockLo pha lda iCurBlockHi pha + ldx #0 ; read to main memory + !if <.addr = 0 { + stx ldrlo + } +LDADDR .filepath - jsr LoadFileDirect + jsr iLoadFileDirect pla sta iCurBlockHi pla sta iCurBlockLo } +; load an external file by pathname +; set path to new directory +; LC RAM 2 MUST BE BANKED IN +!macro LOAD_FILE_KEEP_DIR .filepath, .dirlen { + ldx #0 ; read to main memory + stx ldrhi + stx ldrlo + +LDADDR .filepath + jsr iLoadFileDirect + + ldx #.dirlen + stx $BFD0 +- lda .filepath,x + sta $BFD0,x + dex + bne - + +} + +!macro LOAD_FILE_KEEP_DIR .filepath, .addr, .dirlen { + lda #>.addr + sta ldrhi + lda #<.addr + sta ldrlo + ldx #0 ; read to main memory + +LDADDR .filepath + jsr iLoadFileDirect + + ldx #.dirlen + stx $BFD0 +- lda .filepath,x + sta $BFD0,x + dex + bne - +} + +; Macros for demo launchers that need to check whether they should run +; on the current machine. Exit demo if the requirements are not met. +!macro GAME_REQUIRES_JOYSTICK { + +GET_MACHINE_STATUS + and #HAS_JOYSTICK + bne + + jmp $100 ++ +} + _MACROS_=* } diff --git a/src/okvs.a b/src/okvs.a index f9ef0dc..fa446aa 100644 --- a/src/okvs.a +++ b/src/okvs.a @@ -1,12 +1,10 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Ordered key/value store (6502 compatible)(256+ records compatible) ; ; Public functions -; - okvs_init(address) reset (required) ; - okvs_len(address) get number of keys -; - okvs_append(address, key, value, max_len) add new key/value pair ; - okvs_update(address, key, value) update key/value pair ; - okvs_get(address, key) get value by key lookup ; - okvs_find(address, key) get key by key lookup @@ -18,88 +16,65 @@ ; Call init() once. Call it again to reset the store to 0 records. ; ; Records are maintained in a singly linked list, so most functions are O(n). -; len() and append() are O(1) though. +; len() is always O(1). okvs_nth() can be O(1) if some other code produces +; a key lookup table and stores its address in the 'free space pointer +; after last record' field in the header. ; ; Record count is stored as a word, so a store can hold 65535 records. ; ; Keys and values are length-prefixed strings (Pascal style), so max length -; of any single key or value is 255 bytes. +; of any single key or value is 255 bytes. Record length is stored as a byte +; that includes itself, so the maximum data length of a record is 254 bytes. ; ; Keys are case-sensitive. Lookups are an exact byte-for-byte comparison. ; -; append() has a max_len argument to reserve more space for the value, in case -; you want to update it later. max_len is the total space to reserve, not the -; additional space. One exception: max_len can be 0, and it will be treated as -; length(value) at append time. update() always modifies the value in place. -; There is no range checking because this is assembly. - ; All functions take the starting address of the store's data buffer in -; memory, so there can be multiple independent stores at one time. The next- -; record pointers are actual memory addresses, so stores are not easily -; relocatable. append() will happily extend the store's data buffer without -; limit. There is no overflow protection because this is assembly. +; memory, so there can be multiple independent stores at one time. Only the +; size of a record is stored, so stores are easily relocatable. There is no +; overflow protection because this is assembly. +; +; There is an append() function but it has been separated out of this version +; because it is only used once during program startup, so it does not need +; to persist in LC RAM. ; ; There is no sort() function. ; ; There is no delete() function. ; -; Keys can be duplicated, but get() and find() will always return the one that -; was append()ed first. +; Keys can be duplicated, but get() and find() will always return the first +; match. +; +; Records can technically have more fields than key and value, but callers +; are on their own for navigating inside the record. If you have a pointer +; to one length-prefixed field (including key or value), okvs_next_field() +; will find the start of the next field. ; ; Structures: ; ; Store ; +0 number of records (word) -; +2 free space pointer after last record (word) +; +2 free space pointer after last record (word) or $0000 ; +4 Record ; ...Record... ; ...Record... ; ; Record -; +0 next-record pointer (word) -; +2 key length -; +3 key +; +0 record length (including this field) +; +1 key length +; +2 key ; +K+2 value length (actual length, not max length) ; +K+3 value ; ... filler bytes up to value max length (set at append() time) -;------------------------------------------------------------------------------ -; okvs_init -; -; in: A/Y = handle to storage space -; out: $00/$01 clobbered -; $02/$03 clobbered -; all registers clobbered -;------------------------------------------------------------------------------ -okvs_init - jsr GetStoreAddressFromAY - ; PTR -> store - ; Y = 0 - tya - sta (PTR),y ; set number of keys in store to 0 (word) - iny - sta (PTR),y - - iny ; set next-free-space pointer to store + 4 - ldx PTR+1 - lda PTR - clc - adc #$04 - bcc + - inx -+ sta (PTR),y - iny - txa - sta (PTR),y - rts - ;------------------------------------------------------------------------------ ; okvs_len +; okvs_len_imm ; ; in: A/Y = handle to storage space ; out: $WCOUNT contains number of keys in this store ; X preserved ; A, Y clobbered +; Z set if no keys ; $00/$01 clobbered ; $02/$03 clobbered ;------------------------------------------------------------------------------ @@ -107,119 +82,13 @@ okvs_len jsr GetStoreAddressFromAY ; PTR -> store ; Y = 0 +okvs_len_imm lda (PTR), y ; get number of keys in store (word) sta WCOUNT iny lda (PTR), y sta WCOUNT+1 - rts - -;------------------------------------------------------------------------------ -; okvs_append -; -; in: stack contains 7 bytes of parameters: -; +1 [word] handle to storage space -; +3 [word] address of key -; +5 [word] address of value -; +7 [byte] maximum length of value (or 0 to fit) -; out: (new record count is not returned because no one cares) -; all registers clobbered -; $00/$01 clobbered -; $02/$03 clobbered -; $04/$05 has the address of the next available byte after the new record -; $08/$09 clobbered -;------------------------------------------------------------------------------ -okvs_append - +PARAMS_ON_STACK 7 - jsr GetStoreAddress - ; PTR -> store - ; Y = 0 - lda (PTR),y ; A = number of keys in store - sta WINDEX - iny - lda (PTR), y - sta WINDEX+1 - inc WINDEX - bne + - inc WINDEX+1 -+ - dey - lda WINDEX - sta (PTR),y ; increment number of keys - lda WINDEX+1 - iny - sta (PTR),y - iny - lda (PTR),y ; get address of next free space - tax - iny - lda (PTR),y - sta PTR+1 - sta SAVE+1 - stx PTR - stx SAVE - ; PTR -> new record - ; SAVE -> new record - jsr incptr2 - ; PTR -> space for new key - +LDPARAMPTR 3, SRC ; SRC -> new key to copy - ldy #0 - lda (SRC),y - tay - tax -- lda (SRC),y ; copy new key - sta (PTR),y - dey - cpy #$FF - bne - - - ;;sec - txa - adc PTR ; update PTR to byte after copied key - sta PTR - bcc + - inc PTR+1 -+ ; PTR -> space for new value - +LDPARAMPTR 5, SRC ; SRC -> new value to copy - iny ;;ldy #7 - lda (PARAM),y ; get max length of value - tax - bne + - tay - lda (SRC),y ; no max, use actual length instead - tax - inx -+ tay -- lda (SRC),y - sta (PTR),y - dey - cpy #$FF - bne - - - txa - clc - adc PTR - sta SRC - bcc + - inc PTR+1 -+ lda PTR+1 - sta SRC+1 ; SRC -> byte after this record - +LD16 SAVE - +ST16 PTR ; PTR -> this record again - ldy #0 - lda SRC ; update next-record pointer - sta (PTR),y - iny - lda SRC+1 - sta (PTR),y - jsr GetStoreAddress - ; PTR -> store - ldy #2 - lda SRC-2,y - sta (PTR),y ; update next-free-space pointer in head - iny - lda SRC-2,y - sta (PTR),y + ora WCOUNT rts ;------------------------------------------------------------------------------ @@ -247,16 +116,8 @@ okvs_get jsr GetStoreAddress ; PTR -> store ; Y = 0 - lda (PTR),y ; A = number of keys in store - sta WCOUNT - iny - lda (PTR),y - sta WCOUNT+1 - bne + - dey - lda (PTR),y + jsr okvs_len_imm beq @fail ; no keys, fail immediately -+ jsr incptr4 ; PTR -> first record +LDPARAMPTR 3, SRC ; SRC -> key we want to find @@ -269,11 +130,12 @@ okvs_get sty KEYLEN @matchRecordLoop +LD16 PTR - clc - adc #2 - bcc + - iny ; DEST -> key of this record -+ +ST16 DEST + tax + inx + bne + + iny ++ stx DEST ; DEST -> key of this record + sty DEST+1 ldy #0 @matchKeyLoop lda (SRC),y @@ -287,11 +149,11 @@ KEYLEN = *+1 clc @maybeGetValue brk ; SMC - jsr okvs_get_current + jsr okvs_next_field +LD16 PTR clc rts -@next jsr derefptr ; PTR -> next record +@next jsr stepptr ; PTR -> next record inc WINDEX bne + inc WINDEX+1 @@ -305,17 +167,6 @@ KEYLEN = *+1 @fail sec rts -okvs_get_current - +ST16 PTR - ldy #0 - lda (PTR),y - clc - adc PTR - sta PTR - bcc + - inc PTR+1 -+ jmp incptr - ;------------------------------------------------------------------------------ ; okvs_next ; get (N+1)th key, with wraparound @@ -334,8 +185,7 @@ okvs_next + jsr okvs_len +LD16 WINDEX - +CMP16ADDR WCOUNT - bne + + +CMP16ADDR_NE WCOUNT, + sta WINDEX sta WINDEX+1 + @@ -349,20 +199,46 @@ okvs_next ; $WINDEX = record index ; out: A/Y = lo/hi address of nth key ; $WINDEX preserved -; X = 0 -; Z = 0 ; all other flags clobbered ; $PTR clobbered ;------------------------------------------------------------------------------ okvs_nth - jsr GetStoreAddressFromAY - ; PTR -> store - jsr incptr4 - ; PTR -> first record + jsr GetStoreAddressFromAY ; PTR -> store +LD16 WINDEX +ST16 SAVE - jmp @next -- jsr derefptr + jsr incptr2 ; PTR -> store+2 + ldy #1 + lda (PTR), y + beq @slowpath ; if no key lookup table, iterate through store + pha ; otherwise look up key address and return it + dey + lda (PTR), y + sta PTR + pla + sta PTR+1 ; PTR -> key lookup table + asl SAVE + rol SAVE+1 ; SAVE = WINDEX*2 (16-bit) + lda SAVE + clc + adc PTR + bcc + + clc + inc PTR+1 ++ sta PTR + lda SAVE+1 + adc PTR+1 + sta PTR+1 ; PTR -> nth record key lookup table + lda (PTR), y + pha + iny + lda (PTR), y + tay + pla ; A/Y -> nth key in store + rts +@slowpath + jsr incptr2 ; PTR -> first record + bne @next ; always branches +- jsr stepptr @next lda SAVE dec SAVE @@ -372,9 +248,8 @@ okvs_nth dec SAVE+1 tay bne - - jsr incptr2 + jsr incptr +LD16 PTR - ldx #0 rts ;------------------------------------------------------------------------------ @@ -449,31 +324,22 @@ okvs_iter_values jsr GetStoreAddress ; PTR -> store ; Y = 0 - lda (PTR),y ; get number of keys in store (word) - sta WCOUNT - iny - lda (PTR),y - sta WCOUNT+1 - bne + - dey - lda (PTR),y + jsr okvs_len_imm beq @exit ; no keys, exit immediately -+ - +LDPARAM 3 - +ST16 @callback + +LDPARAMPTR 3, @callback jsr incptr4 ; PTR -> first record lda #0 sta WINDEX sta WINDEX+1 @loop - lda #2 ; for iter, skip length = 2 + lda #1 ; for iter, skip length = 1 @branch bne + ; SMC (iter_values puts a BIT here, so no branch) - ; for iter_values, skip length = length(key) + 2 + 1 - tay ;;ldy #2 + ; for iter_values, skip length = length(key) + 1 + 1 + tay ;;ldy #1 lda (PTR),y ; A = length of key clc - adc #3 ; skip over pointer to next record (2 bytes) + key length (1 byte) + adc #2 ; skip over record length (1 byte) + key length (1 byte) + sta @skiplen lda WCOUNT+1 ; save WCOUNT on stack pha @@ -508,7 +374,7 @@ okvs_iter_values sta WCOUNT pla sta WCOUNT+1 - jsr derefptr ; PTR -> next record + jsr stepptr ; PTR -> next record inc WINDEX bne + inc WINDEX+1 @@ -524,6 +390,16 @@ okvs_iter_values ;------------------------------------------------------------------------------ ; internal functions +okvs_next_field +; out: Y = 0 + +ST16 PTR +okvs_next_field_PTR_is_already_set + jsr stepptr + jmp incptr ; do NOT change this to BNE + ; because if the low byte of PTR is 0 + ; and the value of (PTR) is also 0 + ; then stepptr will return with Z=1 and + ; we will fall through here unexpectedly incptr4 jsr incptr2 incptr2 jsr incptr incptr @@ -560,3 +436,15 @@ derefptr pla sta PTR+1 rts + +stepptr +; out: Y = 0 +; preserves X + ldy #0 + lda (PTR),y + clc + adc PTR + sta PTR + bcc + + inc PTR+1 ++ rts diff --git a/src/parse.common.a b/src/parse.common.a index 353bdcb..d20d8e3 100644 --- a/src/parse.common.a +++ b/src/parse.common.a @@ -31,7 +31,7 @@ ParseKeyValueList +PARAMS_ON_STACK 5 - +LDPARAM 1 + +LDPARAM 1 ; not LDPARAMPTR, SetKeyPtr requires A/Y! +ST16 @store2 jsr SetKeyPtr ldy #5 @@ -135,3 +135,136 @@ IncAndGetChar beq IncAndGetChar .parseKeyValueDone rts + +;------------------------------------------------------------------------------ +; okvs_append +; +; in: stack contains 7 bytes of parameters: +; +1 [word] handle to storage space +; +3 [word] address of key +; +5 [word] address of value +; +7 [byte] maximum length of value (or 0 to fit) +; out: (new record count is not returned because no one cares) +; all registers clobbered +; $00/$01 clobbered +; $02/$03 clobbered +; $04/$05 has the address of the next available byte after the new record +; $08/$09 clobbered +;------------------------------------------------------------------------------ +okvs_append + +PARAMS_ON_STACK 7 + jsr GetStoreAddress + ; PTR -> store + ; Y = 0 + lda (PTR),y ; A = number of keys in store + sta WINDEX + iny + lda (PTR), y + sta WINDEX+1 + inc WINDEX + bne + + inc WINDEX+1 ++ + dey + lda WINDEX + sta (PTR),y ; increment number of keys + lda WINDEX+1 + iny + sta (PTR),y + iny + lda (PTR),y ; get address of next free space + tax + iny + lda (PTR),y + sta PTR+1 + sta SAVE+1 + stx PTR + stx SAVE + ; PTR -> new record + ; SAVE -> new record + jsr incptr + ; PTR -> space for new key + +LDPARAMPTR 3, SRC ; SRC -> new key to copy + ldy #0 + lda (SRC),y + tay + tax +- lda (SRC),y ; copy new key + sta (PTR),y + dey + cpy #$FF + bne - + + ;;sec + txa + adc PTR ; update PTR to byte after copied key + sta PTR + bcc + + inc PTR+1 ++ ; PTR -> space for new value + +LDPARAMPTR 5, SRC ; SRC -> new value to copy + iny ;;ldy #7 + lda (PARAM),y ; get max length of value + tax + bne + + tay + lda (SRC),y ; no max, use actual length instead + tax ++ inx + tay +- lda (SRC),y + sta (PTR),y + dey + cpy #$FF + bne - + + txa + clc + adc PTR + tax + lda PTR+1 + adc #0 + pha ++ jsr GetStoreAddress + ; PTR -> store + pla + ldy #3 + sta (PTR),y ; update next-free-space pointer in head + dey + txa + sta (PTR),y + sec + sbc SAVE + ldy #0 + sta (SAVE),y ; set record length + rts + +;------------------------------------------------------------------------------ +; okvs_init +; +; in: A/Y = handle to storage space +; out: $00/$01 clobbered +; $02/$03 clobbered +; all registers clobbered +;------------------------------------------------------------------------------ +okvs_init + jsr GetStoreAddressFromAY + ; PTR -> store + ; Y = 0 + tya + sta (PTR),y ; set number of keys in store to 0 (word) + iny + sta (PTR),y + + iny ; set next-free-space pointer to store + 4 + ldx PTR+1 + lda PTR + clc + adc #$04 + bcc + + inx ++ sta (PTR),y + iny + txa + sta (PTR),y + rts diff --git a/src/parse.games.a b/src/parse.games.a deleted file mode 100644 index 16becb1..0000000 --- a/src/parse.games.a +++ /dev/null @@ -1,113 +0,0 @@ -;license:MIT -;(c) 2018-2020 by 4am -; -; GAMES.CONF parser -; -; Public functions: -; - ParseGamesList -; - -;------------------------------------------------------------------------------ -; ParseGamesList -; parse buffer with ABC,KEY=VALUE lines of text into an okvs -; keys and values limited to 127 characters, which should be enough for anyone -; '[' character at beginning of line ends the parsing -; (see games.conf file for more format information) -; -; in: stack contains 4 bytes of parameters: -; +1 [word] handle to storage space for okvs -; +3 [word] handle to buffer containing contents of GAMES.CONF -; out: all registers and flags clobbered -; $1F00..$1FFF clobbered -; $00/$01 clobbered -; $02/$03 clobbered -; $04/$05 has the address of the next available byte after the okvs -; $FE/$FF clobbered -;------------------------------------------------------------------------------ -ParseGamesList - +PARAMS_ON_STACK 4 - - +LDPARAM 1 - +ST16 @store2 - jsr SetKeyPtr - - ldy #$00 ; index into ($FE) pointing to current character - beq @newkey ; always branches -@skipLine ; skip to CR - jsr IncAndGetChar - cmp #$0A ; CR - bne @skipLine -@newkey ldx #$00 ; X = index into current key - stx gValLen ; initialize value length (in case this line has no value) -@emptyline - jsr IncAndGetChar ; get first filter character ('1' if game requires joystick) - cmp #$0A ; ignore blank line - beq @emptyline - cmp #$5B ; '[' ends the parsing - beq @exit - cmp #$30 ; '0' -> no filtering on joystick - beq @filterOnMemory - cmp #$31 ; not '0' or '1' or '[' or CR -> ignore entire line (e.g. comment) - bne @skipLine - bit zpMachineStatus - bpl @skipLine ; game requires joystick but we don't have one, so ignore entire line -@filterOnMemory - jsr IncAndGetChar ; get second filter character ('1' if game requires 128K) - cmp #$30 ; '0' -> no filtering on memory - beq @parseDHGRTitle - cmp #$31 ; not '0' or '1' -> ignore entire line - bne @skipLine - bit zpMachineStatus - bvc @skipLine ; game requires 128K but we only have 64K, so ignore entire line -@parseDHGRTitle - jsr IncAndGetChar ; get third character ('1' if game has DHGR title) - and #$01 - pha -@parseCheatsAvailable - jsr IncAndGetChar ; get fourth character (cheat category, int) - and #CHEAT_CATEGORY - pha -@swallowComma - jsr IncAndGetChar -@gatherKey - jsr IncAndGetChar - cmp #$0A ; CR -> finalize key, no value - beq @endKey - cmp #$3D ; '=' ends the key - beq @endKey - sta gKey,x - inx - bpl @gatherKey -@endKey stx gKeyLen - ldx #$00 ; now X = index into the current value - cmp #$0A - beq @endValue -@gatherValue - jsr IncAndGetChar - cmp #$0A ; CR ends the value - beq @endValue - sta gVal,x - inx - bpl @gatherValue -@endValue - pla ; pop cheat category - sta gVal,x ; store after game display name - pla ; pop has-DHGR-title flag - lsr - ror - ora gVal,x - sta gVal,x ; store in bit 7 of same byte as cheat category - inx - stx gValLen - tya - pha ; okvs functions clobber everything but we need Y - jsr okvs_append -@store2 !word $FDFD ; SMC - !word gKeyLen - !word gValLen - !byte 0 - pla ; pop saved Y - tay - jmp @newkey - -@exit rts diff --git a/src/parse.prefs.a b/src/parse.prefs.a index f8a23df..e9e0a43 100644 --- a/src/parse.prefs.a +++ b/src/parse.prefs.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Parser for global preferences file ; @@ -15,7 +15,7 @@ ; - kCheat ; -kGlobalPrefsBuffer = $8000 +kGlobalPrefsBuffer = $BD00 ; [512 bytes] must be page-aligned ; valid pref keys kNextAttract @@ -27,6 +27,9 @@ kNextFX kNextDFX !byte 7 !raw "NEXTDFX" +kNextSFX + !byte 7 + !raw "NEXTSFX" kCheat !byte 5 !raw "CHEAT" @@ -35,7 +38,7 @@ kCheat !raw "=" .kLF !byte 1,$0A .kFluff1 !byte .kFluff2-*-1 - !raw "# Total Replay II preferences file",$0A + !raw "# Total Replay preferences file",$0A !raw "# Do not edit by hand.",$0A !raw "# Or do. I'm a comment, not a cop.",$0A !byte $0A @@ -46,7 +49,10 @@ kCheat .kFluff3 !byte .kFluff4-*-1 !byte $0A !raw "# value=effect listed in DFX.CONF",$0A -.kFluff4 !byte .kEOF-*-1 +.kFluff4 !byte .kFluff5-*-1 + !byte $0A + !raw "# value=effect listed in SFX.CONF",$0A +.kFluff5 !byte .kEOF-*-1 !byte $0A !raw "# value=0 or 1",$0A .kEOF !byte ._-*-1 @@ -101,11 +107,9 @@ PREFRTS rts ; in: stack contains 4 bytes of parameters: ; +1 [word] address of length-prefixed pref key ; +3 [word] address of OKVS, or 0 -; gGlobalPrefsStore must be initialized (this is done in 4sports.init) +; gGlobalPrefsStore must be initialized (this is done in 4cade.init) ; out: A/Y = address of pref value ; $WINDEX = index of pref value in passed store -; (if OKVS parameter is 0, no validation occurs and X=0 and Z=1 on exit, -; some callers rely on this behavior, so don't change it!) ; PARAM clobbered ; PTR clobbered ; SRC clobbered @@ -113,17 +117,15 @@ PREFRTS rts ;------------------------------------------------------------------------------ pref_get +PARAMS_ON_STACK 4 - +LDPARAMPTR 1, + - +LDPARAMPTR 3, .store1 + jsr .set_store01 - jsr okvs_get ; look up pref key in prefs store + jsr okvs_get ; look up pref key in prefs store, sets PTR to value !word gGlobalPrefsStore -+ !word $FDFD ; SMC +.store0 !word $FDFD ; SMC bcs .useDefaultValue ; if pref key is not found, use default value ldx .store1+1 beq PREFRTS ; if no OKVS to validate against, we're done +ST16 + - +ST16 PTR ldy #0 lda (PTR),y beq .useDefaultValue ; if pref value is empty, use default value @@ -138,6 +140,24 @@ pref_get +LD16 .store1 jmp okvs_nth +.set_store01 + ldx #0 + lda #.store1 - .store0 + +.set_store23 + pha + ldy #1 + jsr + + iny + pla + tax ++ lda (PARAM), y + sta .store0, x + iny + lda (PARAM), y + sta .store0 + 1, x + rts + ;------------------------------------------------------------------------------ ; pref_set ; set pref value by pref key, serialize prefs, and write them to disk @@ -153,13 +173,14 @@ pref_get ;------------------------------------------------------------------------------ pref_set +PARAMS_ON_STACK 4 - +LDPARAMPTR 1, + - +LDPARAMPTR 3, ++ + ldx #.store2 - .store0 + lda #.store3 - .store0 + jsr .set_store23 jsr okvs_update ; save that in prefs store !word gGlobalPrefsStore -+ !word $FDFD ; SMC -++ !word $FDFD ; SMC +.store2 !word $FDFD ; SMC +.store3 !word $FDFD ; SMC +LDADDR kGlobalPrefsBuffer ; clear prefs buffer +ST16 $FE @@ -192,6 +213,11 @@ pref_set +LDADDR .kFluff4 jsr .addString + +LDADDR kNextSFX + jsr .addStringFromStore + + +LDADDR .kFluff5 + jsr .addString +LDADDR kCheat jsr .addStringFromStore @@ -200,13 +226,13 @@ pref_set +LDADDR kGlobalPrefsFilename ; write prefs buffer to file on disk jsr SetPath - +LD16 kGlobalPrefsBuffer ; /!\ execution falls through here to glue.prorwts/SaveSmallFile ;------------------------------------------------------------------------------ ; SaveSmallFile ; Save a file into memory all at once, using ProRWTS2. ; /!\ Only first block (512 bytes) is written. Keep those files small. /!\ ; /!\ All 512 bytes are written to disk. Clear buffer before calling. /!\ +; /!\ Address is hardcoded to kGlobalPrefsBuffer /!\ ; ; supports paths, see note ; @@ -216,7 +242,6 @@ pref_set ; all registers clobbered ;------------------------------------------------------------------------------ SaveSmallFile - +ST16 ldrlo ; set data buffer address for ProRWTS2 jsr SwitchToBank2 jsr SaveSmallFileInternal jmp SwitchToBank1 diff --git a/src/prelaunch/_FileInformation.txt b/src/prelaunch/_FileInformation.txt new file mode 100644 index 0000000..1d9e598 --- /dev/null +++ b/src/prelaunch/_FileInformation.txt @@ -0,0 +1 @@ +# This file is maintained by hand diff --git a/src/prelaunch/battle.chess.a b/src/prelaunch/battle.chess.a index 73a4d66..8d59091 100644 --- a/src/prelaunch/battle.chess.a +++ b/src/prelaunch/battle.chess.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/BATTLE.CHESS",plain +!to "build/PRELAUNCH.INDEXED/BATTLE.CHESS",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/bop.n.wrestle.a b/src/prelaunch/bop.n.wrestle.a index 2dab922..1fe2e05 100644 --- a/src/prelaunch/bop.n.wrestle.a +++ b/src/prelaunch/bop.n.wrestle.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/BOP.N.WRESTLE",plain +!to "build/PRELAUNCH.INDEXED/BOP.N.WRESTLE",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/computer.foosball.a b/src/prelaunch/computer.foosball.a index 0abe7c3..62e410d 100644 --- a/src/prelaunch/computer.foosball.a +++ b/src/prelaunch/computer.foosball.a @@ -2,7 +2,7 @@ ;(c) 2022 by qkumba !cpu 6502 -!to "build/PRELAUNCH/CMPTR.FOOSBALL",plain +!to "build/PRELAUNCH.INDEXED/CMPTR.FOOSBALL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/dive.bomber.a b/src/prelaunch/dive.bomber.a index a8901a1..75efb6d 100644 --- a/src/prelaunch/dive.bomber.a +++ b/src/prelaunch/dive.bomber.a @@ -2,7 +2,7 @@ ;(c) 2021 by qkumba !cpu 6502 -!to "build/PRELAUNCH/DIVE.BOMBER",plain +!to "build/PRELAUNCH.INDEXED/DIVE.BOMBER",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/fight.night.a b/src/prelaunch/fight.night.a index 58efe1b..18c5518 100644 --- a/src/prelaunch/fight.night.a +++ b/src/prelaunch/fight.night.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/FIGHT.NIGHT",plain +!to "build/PRELAUNCH.INDEXED/FIGHT.NIGHT",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/formula.1.racer.a b/src/prelaunch/formula.1.racer.a index 1118745..90a838d 100755 --- a/src/prelaunch/formula.1.racer.a +++ b/src/prelaunch/formula.1.racer.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/FORMULA.1.RACER",plain +!to "build/PRELAUNCH.INDEXED/FORMULA.1.RACER",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/fs2.a b/src/prelaunch/fs2.a index 1a63606..640ff0d 100755 --- a/src/prelaunch/fs2.a +++ b/src/prelaunch/fs2.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/FS2",plain +!to "build/PRELAUNCH.INDEXED/FS2",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/hardball.a b/src/prelaunch/hardball.a index daf1f1f..a5cdf96 100644 --- a/src/prelaunch/hardball.a +++ b/src/prelaunch/hardball.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/HARDBALL",plain +!to "build/PRELAUNCH.INDEXED/HARDBALL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/intl.gran.prix.a b/src/prelaunch/intl.gran.prix.a index 396b7ba..b69d910 100755 --- a/src/prelaunch/intl.gran.prix.a +++ b/src/prelaunch/intl.gran.prix.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/INTL.GRAN.PRIX",plain +!to "build/PRELAUNCH.INDEXED/INTL.GRAN.PRIX",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/one.on.one.a b/src/prelaunch/one.on.one.a index 5baaf0f..12c3203 100644 --- a/src/prelaunch/one.on.one.a +++ b/src/prelaunch/one.on.one.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/ONE.ON.ONE",plain +!to "build/PRELAUNCH.INDEXED/ONE.ON.ONE",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/pool.a b/src/prelaunch/pool.a index 8e261cb..9247223 100644 --- a/src/prelaunch/pool.a +++ b/src/prelaunch/pool.a @@ -2,7 +2,7 @@ ;(c) 2022 by qkumba !cpu 6502 -!to "build/PRELAUNCH/POOL",plain +!to "build/PRELAUNCH.INDEXED/POOL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/shuffleboard.a b/src/prelaunch/shuffleboard.a index ea65fba..543f2ec 100755 --- a/src/prelaunch/shuffleboard.a +++ b/src/prelaunch/shuffleboard.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/SHUFFLEBOARD",plain +!to "build/PRELAUNCH.INDEXED/SHUFFLEBOARD",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/ski.crazed.a b/src/prelaunch/ski.crazed.a index b5e96f4..1a66cf1 100644 --- a/src/prelaunch/ski.crazed.a +++ b/src/prelaunch/ski.crazed.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/SKI.CRAZED",plain +!to "build/PRELAUNCH.INDEXED/SKI.CRAZED",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/spdway.classic.a b/src/prelaunch/spdway.classic.a index e460772..c3e1394 100755 --- a/src/prelaunch/spdway.classic.a +++ b/src/prelaunch/spdway.classic.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/SPDWAY.CLASSIC",plain +!to "build/PRELAUNCH.INDEXED/SPDWAY.CLASSIC",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/ss.baseball.a b/src/prelaunch/ss.baseball.a index 88d0e9b..5da0d8e 100755 --- a/src/prelaunch/ss.baseball.a +++ b/src/prelaunch/ss.baseball.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M., qkumba !cpu 6502 -!to "build/PRELAUNCH/SS.BASEBALL",plain +!to "build/PRELAUNCH.INDEXED/SS.BASEBALL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/ss.basketball.a b/src/prelaunch/ss.basketball.a index a500135..c8e94bb 100755 --- a/src/prelaunch/ss.basketball.a +++ b/src/prelaunch/ss.basketball.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M., qkumba !cpu 6502 -!to "build/PRELAUNCH/SS.BASKETBALL",plain +!to "build/PRELAUNCH.INDEXED/SS.BASKETBALL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/standard.a b/src/prelaunch/standard.a index 2e118ed..505881f 100644 --- a/src/prelaunch/standard.a +++ b/src/prelaunch/standard.a @@ -2,7 +2,7 @@ ;(c) 2021 by qkumba !cpu 6502 -!to "build/PRELAUNCH/STANDARD",plain +!to "build/PRELAUNCH.INDEXED/STANDARD",plain *=$106 !source "src/constants.a" diff --git a/src/prelaunch/summer.games.a b/src/prelaunch/summer.games.a index aaba2cb..aa8b301 100755 --- a/src/prelaunch/summer.games.a +++ b/src/prelaunch/summer.games.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/SUMMER.GAMES",plain +!to "build/PRELAUNCH.INDEXED/SUMMER.GAMES",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/summer.games.ii.a b/src/prelaunch/summer.games.ii.a index aa64fce..9aad1c4 100755 --- a/src/prelaunch/summer.games.ii.a +++ b/src/prelaunch/summer.games.ii.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/SUMMER.GAMES.II",plain +!to "build/PRELAUNCH.INDEXED/SUMMER.GAMES.II",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/super.huey.a b/src/prelaunch/super.huey.a index f6cbd63..b9221b3 100644 --- a/src/prelaunch/super.huey.a +++ b/src/prelaunch/super.huey.a @@ -2,7 +2,7 @@ ;(c) 2021 by qkumba !cpu 6502 -!to "build/PRELAUNCH/SUPER.HUEY",plain +!to "build/PRELAUNCH.INDEXED/SUPER.HUEY",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/tag.team.a b/src/prelaunch/tag.team.a index a1f08c6..38c5f13 100755 --- a/src/prelaunch/tag.team.a +++ b/src/prelaunch/tag.team.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/TAG.TEAM",plain +!to "build/PRELAUNCH.INDEXED/TAG.TEAM",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/test.drive.a b/src/prelaunch/test.drive.a index fea82cd..b0094d7 100644 --- a/src/prelaunch/test.drive.a +++ b/src/prelaunch/test.drive.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/TEST.DRIVE",plain +!to "build/PRELAUNCH.INDEXED/TEST.DRIVE",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/the.dam.busters.a b/src/prelaunch/the.dam.busters.a index cd1d8c0..3e3b86f 100644 --- a/src/prelaunch/the.dam.busters.a +++ b/src/prelaunch/the.dam.busters.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/THE.DAM.BUSTERS",plain +!to "build/PRELAUNCH.INDEXED/THE.DAM.BUSTERS",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/tomahawk.a b/src/prelaunch/tomahawk.a index 2128ed9..6d914a2 100755 --- a/src/prelaunch/tomahawk.a +++ b/src/prelaunch/tomahawk.a @@ -2,7 +2,7 @@ ;(c) 2019 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/TOMAHAWK",plain +!to "build/PRELAUNCH.INDEXED/TOMAHAWK",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/winter.games.a b/src/prelaunch/winter.games.a index 63b3ae0..11969eb 100755 --- a/src/prelaunch/winter.games.a +++ b/src/prelaunch/winter.games.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/WINTER.GAMES",plain +!to "build/PRELAUNCH.INDEXED/WINTER.GAMES",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/world.games.a b/src/prelaunch/world.games.a index 5a11bed..3df3905 100644 --- a/src/prelaunch/world.games.a +++ b/src/prelaunch/world.games.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/WORLD.GAMES",plain +!to "build/PRELAUNCH.INDEXED/WORLD.GAMES",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/world.karate.a b/src/prelaunch/world.karate.a index 8f9fbf2..1f533e1 100644 --- a/src/prelaunch/world.karate.a +++ b/src/prelaunch/world.karate.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/WORLD.KARATE",plain +!to "build/PRELAUNCH.INDEXED/WORLD.KARATE",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/proboothd/proboothd.a b/src/proboothd/proboothd.a index 7ccd4b3..9a19a6c 100644 --- a/src/proboothd/proboothd.a +++ b/src/proboothd/proboothd.a @@ -5,147 +5,203 @@ !to "build/proboothd",plain *=$800 - ;zpage usage, arbitrary selection except for the "ProDOS constant" ones - command = $42 ;ProDOS constant - unit = $43 ;ProDOS constant - adrlo = $44 ;ProDOS constant - adrhi = $45 ;ProDOS constant - bloklo = $46 ;ProDOS constant - blokhi = $47 ;ProDOS constant + ;zpage usage, arbitrary selection except for the "ProDOS constant" ones + command = $42 ;ProDOS constant + unit = $43 ;ProDOS constant + adrlo = $44 ;ProDOS constant + adrhi = $45 ;ProDOS constant + bloklo = $46 ;ProDOS constant + blokhi = $47 ;ProDOS constant - A2L = $3e - A2H = $3f - sizehi = $53 + A2L = $3e + A2H = $3f + sizehi = $53 - ;constants - scrn2p2 = $f87b - dirbuf = $1e00 ;for size-optimisation + ;constants + scrn2p2 = $f87b + dirbuf = $1e00 ;for size-optimisation - !byte 1 - stx unit - ldy #0 ;Yellowstone support -- txa - jsr scrn2p2 - and #7 - ora #$c0 - sta $be30, y - sta slot+2 - sta entry+2 -slot lda $cfff - sta entry+1 + !byte 1 + txa + pha - lda fakeMLI_e-$100, y - sta $be00+fakeMLI_e-fakeMLI, y - iny - bne - - sty adrlo - stx $bf30 - sty $200 + ; put machine in a known state, clear screen + + cld + bit $c082 + sta $c00e + sta $c00c + sta $c000 + sta $c002 + sta $c004 + jsr $fb2f + jsr $fc58 + jsr $fe84 + jsr $fe89 + jsr $fe93 + + ; print title + lda $fbb3 + cmp #$A0 + beq + ; Spectrum ED + cmp #$06 + beq + + lda #$DF + sta @mask+1 ++ ldy #15 +- lda II-1,y + cmp #$E1 + bcc + +@mask and #$FF ; SMC ++ sta $070C-1,y + dey + bne - + ldy #13 +- lda INSTANT-1,y + sta $04B5-1,y + lda REPLAY-1,y + sta $0535-1,y + dey + bne - + + pla + sta unit + tax + ; X = boot slot x16 + ; Y = 0 + + ; set up ProDOS shim + +- txa + jsr scrn2p2 + and #7 + ora #$c0 + sta $be30, y + sta slot+2 + sta entry+2 +slot lda $cfff + sta entry+1 + lda fakeMLI_e-$100, y + sta $be00+fakeMLI_e-fakeMLI, y + iny + bne - + sty adrlo + stx $bf30 + sty $200 opendir ;read volume directory key block - ldx #2 + ldx #2 - ;include volume directory header in count + ;include volume directory header in count -firstent lda #>dirbuf - sta adrhi - sta A2H - jsr seekread - lda #4 - sta A2L -nextent ldy #0 +firstent lda #>dirbuf + sta adrhi + sta A2H + jsr seekread + lda #4 + sta A2L +nextent ldy #0 - ;match name lengths before attempting to match names + ;match name lengths before attempting to match names - lda (A2L), y - and #$0f - tax - inx -- cmp filename, y - beq foundname + lda (A2L), y + and #$0f + tax + inx +- cmp filename, y + beq foundname - ;move to next directory in this block + ;move to next directory in this block - clc - lda A2L - adc #$27 - sta A2L - bcc + + clc + lda A2L + adc #$27 + sta A2L + bcc + - ;there can be only one page crossed, so we can increment instead of adc + ;there can be only one page crossed, so we can increment instead of adc - inc A2H -+ cmp #$ff ;4+($27*$0d) - bne nextent + inc A2H ++ cmp #$ff ;4+($27*$0d) + bne nextent - ;read next directory block when we reach the end of this block + ;read next directory block when we reach the end of this block - ldx dirbuf+2 - ldy dirbuf+3 - bcs firstent + ldx dirbuf+2 + ldy dirbuf+3 + bcs firstent -foundname iny - lda (A2L), y - dex - bne - - stx $ff +foundname + iny + lda (A2L), y + dex + bne - + stx $ff - ;cache KEY_POINTER + ;cache KEY_POINTER - ldy #$11 - lda (A2L), y - tax - iny - lda (A2L), y - tay - -readfile jsr seekread - inc adrhi - inc adrhi + ldy #$11 + lda (A2L), y + tax + iny + lda (A2L), y + tay - ;fetch data block and read it +readfile jsr seekread + inc adrhi + inc adrhi -blockind ldy $ff - inc $ff - ldx dirbuf, y - lda dirbuf+256, y - tay - bne readfile - txa - bne readfile + ;fetch data block and read it -readdone jmp $2000 +blockind ldy $ff + inc $ff + ldx dirbuf, y + lda dirbuf+256, y + tay + bne readfile + txa + bne readfile -seekread stx bloklo - sty blokhi - lda #1 - sta command - lda adrhi - pha -entry jsr $d1d1 - pla - sta adrhi - rts +readdone jmp $2060 -fakeMLI bne retcall -readblk dey - dey - sty adrhi - tay - jsr $bf00+seekread-fakeMLI -retcall pla - tax - inx - inx - inx - txa - pha - rts +seekread stx bloklo + sty blokhi + lda #1 + sta command + lda adrhi + pha +entry jsr $d1d1 + pla + sta adrhi + rts + +fakeMLI bne retcall +readblk dey + dey + sty adrhi + tay + jsr $bf00+seekread-fakeMLI +retcall pla + tax + inx + inx + inx + txa + pha +- rts fakeMLI_e -filename !byte filename_e - filename_b -filename_b !text "LAUNCHER.SYSTEM" ;your start-up file, file is max 40kb +filename + !byte filename_e - filename_b +filename_b + !text "LAUNCHER.SYSTEM" ;your start-up file, file is max 40kb filename_e +II + !byte $D4,$EF,$F4,$E1,$EC,$A0,$D2,$E5,$F0,$EC,$E1,$F9,$A0,$C9,$C9 +INSTANT + !byte $C9,$A0,$CE,$A0,$D3,$A0,$D4,$A0,$C1,$A0,$CE,$A0,$D4 +REPLAY + !byte $A0,$D2,$A0,$C5,$A0,$D0,$A0,$CC,$A0,$C1,$A0,$D9,$A0 *=$9f8 !byte $D3,$C1,$CE,$A0,$C9,$CE,$C3,$AE diff --git a/src/prodos.impl.lc2.a b/src/prodos.impl.lc2.a index 5237fcd..870eb88 100644 --- a/src/prodos.impl.lc2.a +++ b/src/prodos.impl.lc2.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2019-2020 by 4am & qkumba +;(c) 2019-2022 by 4am & qkumba ; ; Pseudo-ProDOS environment ; @@ -18,16 +18,10 @@ ipacket = first_zp ;word buffer = first_zp+2 ;word -!if RELBASE != $2000 { - !ifdef PASS2 { - } else { ;PASS2 - !if * != iProDOS_enter { - !error "iProDOS_enter=",*, ", fix constants.a" - } - } -} ProDOS_enter !set CloseHandles = @imp_close +!set swap_zpg = @swap_zp +!set SavedZP = @saved_zp stx ProDOS_savedX+1 sty ProDOS_savedY+1 jsr @swap_zp @@ -224,42 +218,44 @@ ProDOS_enter resetval=$f0 @imp_seek jsr @set_rdwrbuff - ldx #0 - stx blkidx - stx blkofflo - stx blkoffhi - stx reqcmd jsr @reset - ldx sizelo - bne @seek64 - cmp ldrhi - bcc @seek64 - bne @seek32 - ldx ldrlo - beq @seek32 - -@seek64 - sta sizehi - sta sizelo - jsr @seekreset + lda sizelo + lsr + tay lda ldrhi - sbc #resetval - sta ldrhi + ror + sta blkidx + ldx istree + beq @sametree + tax + beq @skiptree + iny + cpy treeidx -@seek32 - lda ldrhi - sta sizehi +@skiptree + sty treeidx + beq @sametree + ldx hddtreebuf - 1, y + lda hddtreebuf + 255, y + jsr hddreaddirsel + +@sametree + jsr @close_reset lda ldrlo sta sizelo - jsr @seekreset lda ldrhi - ora ldrlo - bne @jmp_zp - dec blkidx + and #1 + sta sizehi + ora sizelo + beq @link_jmpzp + jsr @seekreset + @link_jmpzp - beq @jmp_zp ;always + jmp @restore_zp @seekreset + lda #cmdseek + sta reqcmd jsr hddrdwrpart @reset lda #resetval @@ -306,7 +302,7 @@ resetval=$f0 lda @handles+1 beq @close_ret dec @handles+1 - bne @close_ret + bne @close_reset lda #>hddencbuf @patch_buffer @@ -323,12 +319,24 @@ resetval=$f0 stx dirbufpatch7+2 stx dirbufpatch9+2 stx dirbufpatch10+1 + stx dirbufpatch11+1 inx stx dirbufpatch5+2 stx dirbufpatch8+2 + inx + stx treebufpatch1+1 + stx treebufpatch2+2 + inx + stx treebufpatch3+2 @close_ret rts +@close_reset + lda #0 + sta blkofflo + sta blkoffhi + rts + @fetchbyte inc @fetchaddr+1 bne @fetchaddr @@ -391,6 +399,13 @@ resetval=$f0 @saved_zp !fill (last_zp - first_zp) + 1 +resetRoot +gRootDirectory + +LDADDR 0 ; SMC + sta (reloc + unrhddblocklo - unrelochdd) + 1 + sty (reloc + unrhddblockhi - unrelochdd) + 1 + rts + ;------------------------------------------------------------------------------ ; traverse [private] ; @@ -401,15 +416,11 @@ resetval=$f0 !ifdef PASS2 { } else { ;PASS2 !if * != itraverse { - !error "itraverse=",*, ", fix constants.a" + !error "itraverse=",*, ", fix constants.a, rebuild prelaunch" } } traverse - +LD16 gRootDirectory - sta (reloc + unrhddblocklo - unrelochdd) + 1 - sty (reloc + unrhddblockhi - unrelochdd) + 1 - sta @myreadblock+1 - sty @myreadblock+3 ; reset 'root' directory (saved at program start) + jsr resetRoot ;search for '/' character in filename @@ -419,71 +430,33 @@ traverse tay - inx dey - bmi @go ; no '/', just do the read + beq @go ; no '/', just do the read lda (namlo), y cmp #'/' bne - sty sizelo txa pha + lda #$B1 ; LDA (), y + sta pathpatch1 + lda #$68 ; PLA + sta pathpatch2 + lda #$60 ; RTS + sta pathpatch2 + 1 @myreadblock -@myx80_parms - ldx #2 - lda #0 - jsr hddreaddirsel - lda #NAME_LENGTH - sta bloklo - lda #>(hdddirbuf - 1) - sta blokhi - - ;there can be only one page crossed, so we can increment here - -@mynextent1 - inc blokhi -@mynextent - ldy #0 - lda (bloklo), y - pha - and #$0f - tax --- iny - lda (bloklo), y - cmp (namlo), y - beq @myfoundname - - ;match failed, move to next directory in this block, if possible - -- pla - -@myskiphdr - clc - lda bloklo - adc #ENTRY_SIZE - sta bloklo - bcs @mynextent1 - cmp #$ff ;4 + ($27 * $0d) - bne @mynextent - - ;read next directory block when we reach the end of this block - - lda hdddirbuf + NEXT_BLOCK_LO - ldx hdddirbuf + NEXT_BLOCK_HI - bcs + - -@myfoundname - dex - bne -- + jsr hddopendir +- tax ;parse path until last directory is seen - iny lda (namlo), y cmp #'/' - bne - - pla - and #$20 ;Volume Directory Header XOR subdirectory - bne @myskiphdr + beq + +-- jsr pathresume + bne - ; always taken ++ txa + bmi -- tya eor #$ff adc sizelo @@ -492,23 +465,31 @@ traverse tya adc namlo sta namlo + bcc + + inc namhi ++ ;cache block number of current directory ;as starting position for subsequent searches ldy #(KEY_POINTER + 1) - lda (bloklo), y + lda (scratchlo), y tax dey - lda (bloklo), y + lda (scratchlo), y sta (reloc + unrhddblocklo - unrelochdd) + 1 stx (reloc + unrhddblockhi - unrelochdd) + 1 -+ sta @myx80_parms + 1 - stx @myx80_parms + 3 -++ lda sizelo + lda sizelo bne @myreadblock tay + lda #$D1 ; CMP (), y + sta pathpatch1 + lda #$86 ; STX + sta pathpatch2 + lda #$5A + sta pathpatch2 + 1 + pla sta (namlo), y @go diff --git a/src/prodos.path.a b/src/prodos.path.a index 09bf9a7..d215200 100644 --- a/src/prodos.path.a +++ b/src/prodos.path.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am ; ; ProDOS - functions for constructing and passing around ProDOS pathnames ; @@ -24,14 +24,7 @@ kRootDirectory=*+1 ldx #0 stx gPathname ; execution falls through here -!if RELBASE != $2000 { - !ifdef PASS2 { - } else { ;PASS2 - !if * != iAddToPath { - !error "iAddToPath=",*, ", fix constants.a" - } - } -} + AddToPath +ST16 PTR ldy #0 @@ -53,42 +46,117 @@ AddToPath @done rts -kHGRTitleDirectory - !byte 10 - !raw "TITLE.HGR/" +kSearchIndexRecord + !byte 0 + !be24 0 ; SMC in 4cade.init + !le16 0 ; SMC in 4cade.init -kDHGRTitleDirectory - !byte 11 - !raw "TITLE.DHGR/" +kSearchCacheRecord + !byte 0 + !be24 0 ; SMC in 4cade.init + !le16 0 ; SMC in 4cade.init + +kPrelaunchIndexRecord + !source "src/index/prelaunch.idx.a" + +kAttractModeIndexRecord + !source "src/index/attract.idx.a" + +kMiniAttractIndexLo + !byte kMiniAttractIndexRecord0 + !byte >kMiniAttractIndexRecord1 +kMiniAttractIndexRecord0 + !source "src/index/miniattract0.idx.a" +kMiniAttractIndexRecord1 + !source "src/index/miniattract1.idx.a" + +kAttractModeSlideshowIndexRecord + !source "src/index/slideshow.idx.a" + +kFXIndexRecord + !source "src/index/fx.idx.a" + +kDFXIndexRecord + !source "src/index/dfx.idx.a" + +kSFXIndexRecord + !source "src/index/sfx.idx.a" + +kGameHelpIndexRecord + !source "src/index/gamehelp.idx.a" + +kHGRTitleIndexRecord + !source "src/index/title.idx.a" + +kDHGRTitleIndexRecord + !source "src/index/dtitle.idx.a" + +kSHRArtworkIndexRecord + !source "src/index/artwork.idx.a" + +kDHGRActionIndexRecord + !source "src/index/dhgr.idx.a" + +kGRActionIndexRecord + !source "src/index/gr.idx.a" + +kDGRActionIndexRecord + !source "src/index/dgr.idx.a" + +kHGRActionIndexLo + !byte kHGRActionIndexRecord0 + !byte >kHGRActionIndexRecord1 + !byte >kHGRActionIndexRecord2 + !byte >kHGRActionIndexRecord3 + !byte >kHGRActionIndexRecord4 + !byte >kHGRActionIndexRecord5 + !byte >kHGRActionIndexRecord6 +kHGRActionIndexRecord0 + !source "src/index/hgr0.idx.a" +kHGRActionIndexRecord1 + !source "src/index/hgr1.idx.a" +kHGRActionIndexRecord2 + !source "src/index/hgr2.idx.a" +kHGRActionIndexRecord3 + !source "src/index/hgr3.idx.a" +kHGRActionIndexRecord4 + !source "src/index/hgr4.idx.a" +kHGRActionIndexRecord5 + !source "src/index/hgr5.idx.a" +kHGRActionIndexRecord6 + !source "src/index/hgr6.idx.a" + +kCreditsRecord + !source "src/index/credits.idx.a" + +kHelpTextRecord + !source "src/index/helptext.idx.a" + +kDecrunchRecord + !source "src/index/decrunch.idx.a" + +kJoystickRecord + !source "src/index/joystick.idx.a" + +kTotalDataFile + !byte 10 + !raw "TOTAL.DATA" kAnimatedTitleDirectory !byte 15 !raw "TITLE.ANIMATED/" -kHGRActionDirectory - !byte 11 - !raw "ACTION.HGR/" - -kDHGRActionDirectory - !byte 12 - !raw "ACTION.DHGR/" - -kGRActionDirectory - !byte 10 - !raw "ACTION.GR/" - -kSHRArtworkDirectory - !byte 12 - !raw "ARTWORK.SHR/" - -kMiniAttractDirectory - !byte 8 - !raw "ATTRACT/" - -kAttractModeSlideshowDirectory - !byte 3 - !raw "SS/" - kDemoDirectory !byte 5 !raw "DEMO/" @@ -102,70 +170,27 @@ kFXDirectory !byte 3 !raw "FX/" -kPrelaunchDirectory - !byte 10 - !raw "PRELAUNCH/" - -kGameHelpDirectory - !byte 9 - !raw "GAMEHELP/" - -kStandardPrelaunch - !byte 8 - !raw "STANDARD" - kGlobalPrefsFilename !byte 10 !raw "PREFS.CONF" -kAttractModeConfFile - !byte 12 - !raw "ATTRACT.CONF" +kStandardPrelaunchRecord + !source "src/index/standard.prelaunch.a" -kFXConfFile - !byte 7 - !raw "FX.CONF" +kCoverFadeRecord + !source "src/index/coverfade.idx.a" -kDFXConfFile - !byte 8 - !raw "DFX.CONF" +kGRFizzleRecord + !source "src/index/gr.fizzle.idx.a" -kCreditsFile - !byte 7 - !raw "CREDITS" +kDGRFizzleRecord + !source "src/index/dgr.fizzle.idx.a" -kHelpBackgroundFile - !byte 4 - !raw "HELP" +kHelpBackgroundRecord + !source "src/index/res.help.idx.a" -kHelpTextFile - !byte 8 - !raw "HELPTEXT" +kTitleRecord + !source "src/index/res.title.idx.a" -kTitleFile - !byte 5 - !raw "TITLE" - -kCoverFile - !byte 5 - !raw "COVER" - -kCoverFadeFile - !byte 9 - !raw "COVERFADE" - -kGRFizzleFile - !byte 9 - !raw "GR.FIZZLE" - -kSFXFizzleFile - !byte 10 - !raw "SHR.FIZZLE" - -kDecrunchFile - !byte 8 - !raw "DECRUNCH" - -kJoystickFile - !byte 8 - !raw "JOYSTICK" +kCoverRecord + !source "src/index/res.cover.idx.a" diff --git a/src/prorwts2.a b/src/prorwts2.a index e8f3bce..10405a0 100644 --- a/src/prorwts2.a +++ b/src/prorwts2.a @@ -1,6 +1,7 @@ ;license:BSD-3-Clause ;extended open/read/write binary file in ProDOS filesystem, with random access -;copyright (c) Peter Ferrie 2013-2020 +;copyright (c) Peter Ferrie 2013-2021 +;assemble using ACME ver_02 = 1 @@ -21,6 +22,8 @@ ver_02 = 1 aligned_read = 0 ;set to 1 if all reads can be a multiple of block size enable_readseq=0 ;set to 1 to enable reading multiple sequential times from the same file without seek ;(exposes a fixed address that can be called for either floppy or hard disk support) + ;requires fast_subindex + ;can also be used for sequential writes, but size must be 512-aligned enable_write = 1 ;set to 1 to enable write support ;file must exist already and its size cannot be altered ;writes occur in multiples of block size @@ -34,22 +37,24 @@ ver_02 = 1 might_exist = 0 ;set to 1 if file is not known to always exist already ;makes use of status to indicate success or failure many_files = 0 ;set to 1 to support more than 256 files in a directory + detect_wp = 0 ;detect write-protected floppy during writes allow_aux = 1 ;set to 1 to allow read/write directly to/from aux memory ;requires load_high to be set for arbitrary memory access ;else driver must be running from same memory target ;i.e. running from main if accessing main, running from aux if accessing aux allow_saplings=1 ;enable support for saplings - allow_trees = 0 ;enable support for tree files, as opposed to only seedlings and saplings + allow_trees = 1 ;enable support for tree files, as opposed to only seedlings and saplings ;required in RWTS mode if file > 128kb - fast_trees = 0 ;keep tree block in memory, requires an additional 512 bytes of RAM + fast_trees = 1 ;keep tree block in memory, requires an additional 512 bytes of RAM always_trees = 0 ;set to 1 if the only file access involves tree files ;not compatible with allow_subdir, allow_saplings ;required in RWTS mode if allow_trees is enabled detect_treof = 0 ;detect EOF during read of tree files - fast_subindex= 0 ;keep subindex block in memory, requires an additional 512 bytes of RAM + fast_subindex= 1 ;keep subindex block in memory, requires an additional 512 bytes of RAM ;halves the disk access for double the speed (ideal for RWTS mode) allow_sparse = 1 ;enable support for reading sparse files - ;recommended if enable_write is enabled, to prevent writing to sparse blocks + write_sparse = 0 ;enable support for writing to sparse files (blocks are allocated even if empty) + ;used only by RWTS mode, writing to sparse files in non-RWTS mode will corrupt the file! bounds_check = 1 ;set to 1 to prevent access beyond the end of the file ;but limits file size to 64k-2 bytes. return_size = 0 ;set to 1 to receive file size on open in read-only mode @@ -59,22 +64,26 @@ ver_02 = 1 swap_zp = 0 ;set to 1 to include code to preserve zpage ;used only by RWTS mode swap_scrn = 1 ;set to 1 to preserve screen hole contents across SmartPort calls - ;reading directly into screen memory that includes holes (either main or aux) is not recommended - ;because SCSI firmware writes there (i.e. whichever bank is active) on exit, which will damage read content ;recommended if allow_aux is used, to avoid device reset ;requires 64 bytes to save all holes + read_scrn = 0 ;set to 1 to support reading into screen memory + ;requires swap_scrn rwts_mode = 0 ;set to 1 to enable emulation of DOS RWTS when running from hard disk ;uses a one-time open of a tree file, no other file access allowed ;use unique volume numbers to distinguish between images in the same file ;requires override_adr, allow_trees, always_trees + ;or fast_subindex if file is smaller than a tree ;not compatible with enable_floppy, allow_subdir, might_exist, bounds_check mem_swap = 0 ;set to 1 if zpage can be swapped between main and aux, and swap_zp is unsuitable ;(caches index registers in code instead of zpage) + write_ffff = 0 ;set to 1 if there might be reads to $FFxx and allow_sparse=1 load_high = 0 ;set to 1 to load to top of RAM (either main or banked, enables a himem check) load_aux = 0 ;load to aux memory load_banked = 1 ;set to 1 to load into banked RAM instead of main RAM (can be combined with load_aux for aux banked) lc_bank = 2 ;load into specified bank (1 or 2) if load_banked=1 one_page = 0 ;set to 1 if verbose mode says that you should (smaller code) + two_pages = 0 ;default size + three_pages = 1 ;set to 1 if verbose mode says that you should (code is larger than two pages) ;user-defined driver load address !if load_banked = 1 { @@ -84,7 +93,7 @@ ver_02 = 1 reloc = $fe00 ;page-aligned, as high as possible, the ideal value will be shown on mismatch } ;PASS2 } else { ;load_high = 0 - reloc = $d400 ;page-aligned, but otherwise wherever you want + reloc = $d600 ;page-aligned, but otherwise wherever you want } ;load_high = 1 } else { ;load_banked = 0 !if load_high = 1 { @@ -123,11 +132,11 @@ ver_02 = 1 ldrhi = $56 ;set to load address if override_adr=1 namlo = $57 ;name of file to access namhi = $58 ;name of file to access - ldrlo2 = $59 ;original load address read from filesystem - ldrhi2 = $5a ;original load address read from filesystem - sizelo2 = $5b ;original file size read from filesystem - sizehi2 = $5c ;original file size read from filesystem - !set last_zp = $5c ;highest address to save if swap_zp enabled (max 127 entries later) + !set last_zp = $58 ;highest address to save if swap_zp enabled (max 127 entries later) +!if write_sparse = 1 { + sparseblk = $59 ;(internal) last-read block was sparse if zero + !set last_zp = $59 ;highest address to save if swap_zp enabled (max 127 entries later) +} ;write_sparse = 1 !if enable_floppy = 1 { tmpsec = $3c ;(internal) sector number read from disk @@ -171,13 +180,13 @@ ver_02 = 1 lastblk = $5f ;(internal) previous index into sapling block list !set last_zp = $5f ;highest address to save if swap_zp enabled (max 127 entries later) } ;rwts_mode = 1 - !if (bounds_check + return_size + one_shot) > 0 { + !if ((bounds_check or return_size) > 0) and ((rwts_mode or one_shot) = 0) { bleftlo = $60 ;(internal) bytes left in file - } ;bounds_check = 1 or return_size = 1 or one_shot = 1 - !if (bounds_check + return_size + aligned_read + one_shot) > 0 { + } ;(bounds_check = 1 or return_size = 1) and (rwts_mode = 0 and one_shot = 0) + !if ((bounds_check or return_size or aligned_read) > 0) and ((rwts_mode or one_shot) = 0) { blefthi = $61 ;(internal) bytes left in file !set last_zp = $61 ;highest address to save if swap_zp enabled (max 127 entries later) - } ;bounds_check = 1 or return_size = 1 or aligned_read = 1 or one_shot = 1 + } ;(bounds_check = 1 or return_size = 1 or aligned_read = 1) and (rwts_mode and one_shot = 0) !if aligned_read = 0 { blkofflo = $62 ;(internal) offset within cache block blkoffhi = $63 ;(internal) offset within cache block @@ -185,6 +194,12 @@ ver_02 = 1 } ;aligned_read = 0 } ;mem_swap = 0 + ldrlo2 = $64 ;original load address read from filesystem + ldrhi2 = $65 ;original load address read from filesystem + sizelo2 = $66 ;original file size read from filesystem + sizehi2 = $67 ;original file size read from filesystem + !set last_zp = $67 ;highest address to save if swap_zp enabled (max 127 entries later) + !if enable_floppy = 1 { step = $64 ;(internal) state for stepper motor tmptrk = $65 ;(internal) temporary copy of current track @@ -200,6 +215,7 @@ ver_02 = 1 SETVID = $fe93 DEVNUM = $bf30 PHASEOFF = $c080 + PHASEON = $c081 MOTOROFF = $c088 MOTORON = $c089 DRV0EN = $c08a @@ -214,6 +230,7 @@ ver_02 = 1 KEY_POINTER = $11 ;ProDOS constant EOF_LO = $15 ;ProDOS constant EOF_HI = $16 ;ProDOS constant + EOF_HI2 = $17 ;ProDOS constant AUX_TYPE = $1f ;ProDOS constant ENTRY_SIZE = $27 ;ProDOS constant NEXT_BLOCK_LO = $2 ;ProDOS constant @@ -222,7 +239,7 @@ ver_02 = 1 FILE_COUNT = $25 ;ProDOS constant DEVADR01HI = $bf11 ;ProDOS constant ROMIN = $c081 - LCBANK2 = $c089 + LCBANK2 = $c08b CLRAUXRD = $c002 CLRAUXWR = $c004 SETAUXWR = $c005 @@ -249,40 +266,33 @@ init lda DEVNUM ora # 0 { + !if no_interrupts = 1 { sta unrdrvoff2 + 1 - } ;might_exist = 1 or poll_drive = 1 - !if (aligned_read + allow_aux) = 0 { - sta unrdrvoff3 + 1 - } ;aligned_read = 0 and allow_aux = 0 + } else { ;no_interrupts = 0 sta unrdrvoff4 + 1 + !if ((aligned_read xor 1) and one_shot) = 1 { + sta unrdrvoff5 + 1 + } ;aligned_read = 0 and one_shot = 1 + } ;no_interrupts = 1 + !if (might_exist + poll_drive) > 0 { + sta unrdrvoff3 + 1 + } ;might_exist = 1 or poll_drive = 1 tax inx ;MOTORON - !if allow_multi = 1 { stx unrdrvon1 + 1 - } ;allow_multi = 1 stx unrdrvon2 + 1 - !if aligned_read = 0 { - stx unrdrvon3 + 1 - } ;aligned_read = 0 - stx unrdrvon4 + 1 inx ;DRV0EN !if allow_multi = 1 { + stx unrdrvsel1 + 1 stx unrdrvsel2 + 1 + stx unrdrvsel3 + 1 } ;allow_multi = 1 inx - !if allow_multi = 1 { - stx unrdrvsel1 + 1 - } ;allow_multi = 1 inx ;Q6L stx unrread1 + 1 - !if (poll_drive + allow_multi) > 0 { stx unrread2 + 1 stx unrread3 + 1 - } ;poll_drive = 1 or allow_multi = 1 stx unrread4 + 1 stx unrread5 + 1 !if check_chksum = 1 { @@ -402,25 +412,24 @@ adjpath tya pla ;unit to slot for ProDOS interface + ;accept if slot code matches unit number +++ pla lsr lsr lsr tay - ldx DEVADR01HI, y - cpx #$c8 - bcc set_slot1 -!if use_smartport = 1 { - php -} ;use_smartport = 1 + lsr + ora #$c0 + tax + cmp DEVADR01HI, y + clc + beq set_slot + !if enable_floppy = 1 { ;check if current device is floppy - lsr - ora #$c0 - tax stx scratchhi ldy #0 sty scratchlo @@ -443,10 +452,14 @@ adjpath tya not_floppy } ;enable_floppy = 1 - - ;find SmartPort device for basic MicroDrive support - ldx #$c8 + + ;find SmartPort device for basic MicroDrive, BOOTi support + ;the BOOTi can load floppy .po images via the SmartPort interface + ;but the virtual slot behaviour differs slightly from regular ProDOS + ;so we scan for the SmartPort interface in all cases + +iterdevice - dex stx scratchhi ldy #0 @@ -468,10 +481,7 @@ not_floppy lda (scratchlo), y beq - -!if use_smartport = 1 { -set_slot plp -} ;use_smartport = 1 -set_slot1 stx slot + 2 +set_slot stx slot + 2 stx unrentry + 2 slot ldx $cfff stx unrentry + 1 @@ -481,15 +491,20 @@ slot ldx $cfff !if use_smartport = 1 { !if enable_floppy = 1 { beq + - } ;enable_floppy = 1 bcs ++ + jmp bankram +++ + } else { ;enable_floppy = 0 + bcs + + jmp bankram ++ + } ;enable_floppy = 1 -++ lda #$8c ;STY + ldy #$8c ;STY !if (rwts_mode + enable_write) > 1 { - sta unrcommand1 + sty unrcommand1 } ;rwts_mode = 1 and enable_write = 1 - sta unrcommand3 + sty unrcommand3 lda # 1 { sta unrcommand1 + 1 @@ -506,31 +521,62 @@ slot ldx $cfff sta unrcommand2 + 2 } ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1 sta unrcommand3 + 2 - lda #$8e ;STX + sta unrgetreq + 2 + iny ;STA + sty unrblokhi1 + sty unrunit1 + 2 + iny ;STX !if (rwts_mode + aligned_read + (enable_write xor 1)) = 0 { - sta unrcommand2 + sty unrcommand2 } ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1 - sta unrbloklo - lda #pblock - sta unrbloklo + 2 - lda #$8d ;STA - sta unrblokhi - lda #<(pblock + 1) - sta unrblokhi + 1 - lda #>(pblock + 1) - sta unrblokhi + 2 + sty unrbloklo1 + ;;lda #>pblock + ;;pblock_enabled=1 + sta unrbloklo1 + 2 + !if (rwts_mode + write_sparse) > 1 { + sta unrbloklo2 + 2 + } ;rwts_mode = 1 and write_sparse = 1 + ;;lda #>(pblock + 1) + ;;pblock1_enabled=1 + sta unrblokhi1 + 2 + !if (rwts_mode + write_sparse) > 1 { + sta unrblokhi2 + 2 + sta unrblokhi3 + 2 + } ;rwts_mode = 1 and write_sparse = 1 + ;;lda #>paddr + sta unrunit1 + 4 + ldy # 1 { + sty unrbloklo2 + 1 + } ;rwts_mode = 1 and write_sparse = 1 + iny + sty unrblokhi1 + 1 + !if (rwts_mode + write_sparse) > 1 { + sty unrblokhi2 + 1 + sty unrblokhi3 + 1 + } ;rwts_mode = 1 and write_sparse = 1 lda #$a5 ;LDA sta unrunit1 + !if (rwts_mode + write_sparse) > 1 { + lda #$ee ;INC + sta unrblokhi2 + ldy #$ad ;LDA + sty unrblokhi3 + sty unrgetreq + iny ;LDX + sty unrbloklo2 + } ;rwts_mode = 1 and write_sparse = 1 lda #adrlo sta unrunit1 + 1 - lda #$8d ;STA - sta unrunit1 + 2 lda #paddr - sta unrunit1 + 4 + !if (rwts_mode and write_sparse) = 0 { + lda #$ad ;LDA + sta unrgetreq + } ;if rwts_mode = 0 or write_sparse = 0 + lda #unrelocdsk ldy #((codeend - rdwrpart) + $ff) ldy #0 + !if (load_aux and (load_banked xor 1)) = 1 { + sta SETAUXWR + } ;load_aux = 1 and load_banked = 0 - lda (scratchlo), y + !if (load_aux + load_banked) > 1 { + sta SETAUXZP + } ;load_aux = 1 and load_banked = 1 reladr sta reloc, y + !if (load_aux + load_banked) > 1 { + sta CLRAUXZP + } ;load_aux = 1 and load_banked = 1 iny bne - inc scratchhi + !if (load_aux and (load_banked xor 1)) = 1 { + sta CLRAUXWR + } ;load_aux = 1 and load_banked = 0 inc reladr + 2 + !if (load_aux and (load_banked xor 1)) = 1 { + sta SETAUXWR + } ;load_aux = 1 and load_banked = 0 dex bne - plp + !if (load_aux + load_banked) > 1 { + sta SETAUXZP + } ;load_aux = 1 and load_banked = 1 + !if swap_scrn = 1 { + beq + + jsr saveslot + lda #$91 + sta initpatch + } ;swap_scrn = 1 bne ++ ++ ;build 6-and-2 denibbilisation table @@ -633,46 +703,83 @@ unrdrvon1 lda MOTORON sta trackd1 !if allow_multi = 1 { -unrdrvsel1 lda DRV0EN + 1 + lda unrunit1 + 1 + asl + lda #0 + rol + sta driveind + 1 + pha + eor #1 + tay +unrdrvsel1 lda DRV0EN, y jsr spinup jsr poll - bcs + - lda #$c8 ;iny - sta twodrives - inc driveind + 1 - jsr readadr - lda curtrk - sta trackd2 -+ + beq + + inc twodrives + 1 + lda #0 + sta phase + ldx #$22 + jsr seek ++ pla + tay +unrdrvsel2 lda DRV0EN, y } ;allow_multi = 1 unrdrvoff1 lda MOTOROFF ++ } else { ;enable_floppy = 0 + !ifdef PASS2 { + !if >(hddcodeend - reloc) > 0 { + !if one_page = 1 { + !error "one_page must be 0" + } ;one_page = 0 + !if >(hddcodeend - reloc) > 1 { + !if three_pages = 0 { + !error "three_pages must be 1" + } ;three_pages = 0 + } ;hddcodeend + } ;hddcodeend + } ;PASS2 + !if three_pages = 1 { + ldx #>(hddcodeend + $ff - reloc) + } ;three_pages = 1 ldy #0 + !if load_aux = 1 { + sta SETAUXWR + (load_banked * 4) ;SETAUXWR or SETAUXZP + } ;load_aux = 1 +multicopy - lda unrelochdd, y sta reloc, y - !if one_page = 0 { - ;hack to avoid address overflow when load_high and load_banked - ;and code is less than two pages long (e.g. aligned_read, no write) - ;can't insert code during pass two because it breaks existing offsets - + !if three_pages = 0 { + !if two_pages = 1 { lda unrelochdd + $100, y sta reloc + $100, y - lda unrelochdd + $200, y - sta reloc + $200, y - } ;one_page = 0 + } ;two_pages = 1 + } ;three_pages = 0 iny bne - -} ;enable_floppy = 1 -!if swap_scrn = 1 { + !if three_pages = 1 { + !if (load_aux and (load_banked xor 1)) = 1 { + sta CLRAUXWR + } ;load_aux = 1 and load_banked = 0 + inc multicopy + 2 + inc multicopy + 5 + !if (load_aux and (load_banked xor 1)) = 1 { + sta SETAUXWR + } ;load_aux = 1 and load_banked = 0 + dex + bne multicopy + } ;three_pages = 1 + !if (fast_subindex + swap_zp) > 1 { + sty zp_array + adrlo - first_zp + } ;fast_subindex = 1 and swap_zp = 1 + + !if swap_scrn = 1 { jsr saveslot lda #$91 sta initpatch -} ;swap_scrn = 1 -!if load_aux = 1 { - sta CLRAUXWR + (load_banked * 4) ;CLRAUXWR or CLRAUXZP -} ;load_aux = 1 + } ;swap_scrn = 1 +} ;enable_floppy = 1 !if rwts_mode = 1 { ;read volume directory key block @@ -741,12 +848,12 @@ hddfoundname iny sty zp_array + lastblk - first_zp ;guarantee no match } ;swap_zp = 0 or mem_swap = 1 - !if allow_trees = 1 { + !if (allow_trees + fast_subindex) > 0 { ;fetch KEY_POINTER ldy #KEY_POINTER lda (scratchlo), y - !if fast_trees = 0 { + !if (fast_trees + fast_subindex) = 0 { !if ((swap_zp xor 1) + mem_swap) > 0 { sta treeblklo } else { ;swap_zp = 1 and mem_swap = 0 @@ -754,20 +861,22 @@ hddfoundname iny } ;swap_zp = 0 or mem_swap = 1 } else { ;fast_trees = 1 tax - } ;fast_trees = 0 + } ;fast_trees = 0 and fast_subindex = 0 iny lda (scratchlo), y - !if fast_trees = 0 { + !if (fast_trees + fast_subindex) = 0 { !if ((swap_zp xor 1) + mem_swap) > 0 { sta treeblkhi } else { ;swap_zp = 1 and mem_swap = 0 sta zp_array + treeblkhi - first_zp } ;swap_zp = 0 or mem_swap = 1 } else { ;fast_trees = 1 + !if fast_trees = 1 { ldy #>hddtreebuf + } ;fast_trees = 1; jsr hddreaddirsect - } ;fast_trees = 0 - } ;allow_trees = 1 + } ;fast_trees = 0 and fast_subindex = 0 + } ;allow_trees = 1 or fast_subindex = 1 lda #>iob ldy #(dirbuf - 1) - sta scratchhi - +readdir + !if allow_subdir = 1 { + jsr prepdrive + } ;allow_subdir = 1 !if might_exist = 1 { lda dirbuf + FILE_COUNT ;assuming only 256 files per subdirectory sta entries @@ -847,14 +964,18 @@ firstent sta scratchlo } ;many_files = 1 } ;might_exist = 1 + lda #NAME_LENGTH + ENTRY_SIZE +firstent sta scratchlo + lda #>(dirbuf - 1) + sta scratchhi + ;there can be only one page crossed, so we can increment here nextent1 inc scratchhi nextent ldy #0 - !if (might_exist + allow_subdir + allow_saplings + (always_trees xor 1)) > 0 { + !if (might_exist + allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 { lda (scratchlo), y !if might_exist = 1 { - sty status ;skip deleted entries without counting @@ -862,7 +983,7 @@ nextent ldy #0 beq + } ;might_exist = 1 - !if (allow_subdir + allow_saplings + (always_trees xor 1)) > 0 { + !if (allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 { ;remember type ;now bits 5-4 are represented by carry (subdirectory), sign (sapling) @@ -877,8 +998,8 @@ nextent ldy #0 bit treeidx } ;allow_trees = 1 php - } ;allow_subdir = 1 or allow_saplings = 1 or always_trees = 0 - } ;might_exist = 1 or allow_subdir = 1 or allow_saplings = 1 or always_trees = 0 + } ;allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0) + } ;might_exist = 1 or allow_subdir = 1 or allow_saplings = 1 or (allows_trees = 1 and always_trees = 0) ;match name lengths before attempting to match names @@ -891,9 +1012,9 @@ nextent ldy #0 ;match failed, check if any directory entries remain - !if (allow_subdir + allow_saplings + (always_trees xor 1)) > 0 { + !if (allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 { plp - } ;allow_subdir = 1 or allow_saplings = 1 or always_trees = 0 + } ;allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0) !if might_exist = 1 { dec entries bne + @@ -903,10 +1024,14 @@ nextent ldy #0 } ;many_files = 1 } ;might_exist = 1 !if (might_exist + poll_drive) > 0 { -nodisk -unrdrvoff2 = unrelocdsk + (* - reloc) +nodisk inc status + !if detect_err = 1 { + sec + } ;detect_err = 1 + !if no_interrupts = 0 { +unrdrvoff3 = unrelocdsk + (* - reloc) lda MOTOROFF - inc status + } ;no_interrupts = 0 rts } ;might_exist = 1 or poll_drive = 1 @@ -954,7 +1079,9 @@ foundname iny !if aligned_read = 0 { ldy reqcmd cpy #cmdwrite ;control carry instead of zero + !if one_shot = 0 { bne + + } ;one_shot = 0 } ;aligned_read = 0 !if one_shot = 0 { @@ -1032,24 +1159,37 @@ foundname iny } ;one_shot = 0 } ;enable_write = 1 or aligned_read = 1 } ;bounds_check = 1 or return_size = 1 or one_shot = 1 + ;cache AUX_TYPE (load offset for binary files) !if override_adr = 0 { ldy #AUX_TYPE - jsr fetchscratch - stx ldrlo + lda (scratchlo), y + !if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 { + sta ldrlo + iny + lda (scratchlo), y sta ldrhi + } else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1 + pha + iny + lda (scratchlo), y + pha + } ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0 } ;override_adr = 0 ;cache KEY_POINTER ldy #KEY_POINTER - jsr fetchscratch + lda (scratchlo), y + tax !if (allow_subdir + allow_saplings + allow_trees) > 0 { - stx dirbuf + sta dirbuf !if (allow_trees + (fast_trees xor 1)) > 1 { - stx treeblklo + sta treeblklo } ;allow_trees = 1 and fast_trees = 0 + iny + lda (scratchlo), y sta dirbuf + 256 !if (allow_trees + (fast_trees xor 1)) > 1 { sta treeblkhi @@ -1093,8 +1233,6 @@ foundname iny jmp rdwrfilei rdwrfile -unrdrvon2 = unrelocdsk + (* - reloc) - lda MOTORON !if allow_subdir = 1 { clc } ;allow_subdir = 1 @@ -1113,10 +1251,14 @@ unrdrvon2 = unrelocdsk + (* - reloc) pha } ;detect_err = 1 plp +unrdrvoff3 = unrelocdsk + (* - reloc) + lda MOTOROFF rts + } ;no_interrupts = 1 + jsr prepdrive + rdwrfilei !if (override_adr + allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 { ;restore load offset @@ -1214,8 +1356,6 @@ copyblock ldy sizehi } ;enable_seek = 1 jsr copycache -unrdrvon3 = unrelocdsk + (* - reloc) - lda MOTORON ;copycache turns it off ;align to next block and resume read @@ -1244,11 +1384,9 @@ unrdrvon3 = unrelocdsk + (* - reloc) bne rdwrfilei } ;allow_subdir = 1 !if allow_aux = 0 { -unrdrvoff3 = unrelocdsk + (* - reloc) - lda MOTOROFF rts } else { ;allow_aux = 1 - beq rdwrdonedrv + beq rdwrdone } ;allow_aux = 0 } ;one_shot = 0 } else { ;aligned_read = 1 @@ -1326,9 +1464,6 @@ rdwrloop !if aligned_read = 0 { php } ;aligned_read = 0 - lda #>dirbuf - sta adrhi - sty adrlo ;fetch tree data block and read it @@ -1363,6 +1498,8 @@ noteof1 } ;detect_treof = 1 !if fast_trees = 0 { + lda #>dirbuf + sta adrhi jsr seekrd } else { ;fast_trees = 1 jsr readdirsel @@ -1414,16 +1551,8 @@ noteof2 !if allow_sparse = 1 { pha ora dirbuf, y - tay - pla - dey - iny ;don't affect carry - } ;allow_sparse = 1 - !if aligned_read = 0 { - php - } ;aligned_read = 0 - !if allow_sparse = 1 { beq issparse + pla } ;allow_sparse = 1 !if (aligned_read and (enable_write or enable_seek)) = 1 { ldy reqcmd @@ -1431,15 +1560,20 @@ noteof2 beq + } ;enable_seek = 1 } ;aligned_read = 1 and (enable_write = 1 or enable_seek = 1) + !if aligned_read = 0 { + php + } ;aligned_read = 0 !if enable_write = 1 { jsr seekrdwr } else { ;enable_write = 0 jsr seekrd } ;enable_write = 1 + !if aligned_read = 0 { + plp + } ;aligned_read = 0 resparse !if aligned_read = 0 { - plp + bcc + !if bounds_check = 1 { dec blefthi @@ -1450,14 +1584,15 @@ resparse dec sizehi bne rdwrloop -rdwrdonedrv -unrdrvoff4 = unrelocdsk + (* - reloc) - lda MOTOROFF !if aligned_read = 0 { lda sizelo bne rdwrloop } ;aligned_read = 0 rdwrdone + !if no_interrupts = 0 { +unrdrvoff4 = unrelocdsk + (* - reloc) + lda MOTOROFF + } ;no_interrupts = 0 !if allow_aux = 1 { ldx #0 setaux sta CLRAUXRD, x @@ -1466,7 +1601,8 @@ setaux sta CLRAUXRD, x rts !if allow_sparse = 1 { -issparse +issparse pla + tay - sta (adrlo), y iny bne - @@ -1474,8 +1610,12 @@ issparse - sta (adrlo), y iny bne - - dec adrhi + inc adrhi + !if write_ffff = 0 { bne resparse + } else { + jmp resparse + } ;write_ffff } ;allow_sparse = 1 !if aligned_read = 0 { @@ -1541,10 +1681,107 @@ copycache sta blkoffhi bcc rdwrdone ;always } else { ;one_shot = 1 + !if no_interrupts = 0 { +unrdrvoff5 = unrelocdsk + (* - reloc) + lda MOTOROFF + } ;no_interrupts = 0 rts } ;one_shot = 0 } ;aligned_read = 0 + ;no tricks here, just the regular stuff + +seek ldy #0 + sty step + asl phase + txa + asl + sta tmptrk + +copy_cur lda tmptrk + sta tmpsec + sec + sbc phase + beq +++ + bcs + + eor #$ff + inc tmptrk + bcc ++ ++ sbc #1 + dec tmptrk +++ cmp step + bcc + + lda step ++ cmp #8 + bcs + + tay + sec ++ jsr ++++ + lda step1, y + jsr delay + lda tmpsec + clc + jsr +++++ + lda step2, y + jsr delay + inc step + bne copy_cur ++++ jsr delay + clc +++++ lda tmptrk ++++++ and #3 + rol + tax + +unrseek = unrelocdsk + (* - reloc) + lda PHASEOFF, x + rts + +prepdrive + !if poll_drive = 1 { + tsx + stx callstack + 1 + } ;poll_drive = 1 + !if allow_multi = 1 { + ldy driveind + 1 + } ;allow_multi = 1 + !if (might_exist + poll_drive + detect_wp) > 0 { + !if ver_02 = 1 { + lda #0 + sta status + } else { ;ver_02 = 0 + stz status + } ;ver_02 = 1 + } ;might_exist = 1 or poll_drive = 1 or detect_wp = 1 + !if allow_multi = 1 { + asl reqcmd + bcc seldrive + tya +twodrives eor #0 ;replaced with 1 if drive exists + tay +seldrive lsr reqcmd +driveind cpy #0 + sty driveind + 1 + clc + bne newdrive + } ;allow_multi = 1 + jsr poll + !if allow_multi = 1 { + cpx #1 + } ;allow_multi = 1 + +newdrive +unrdrvon2 = unrelocdsk + (* - reloc) + sta MOTORON + + !if allow_multi = 1 { +unrdrvsel3 = unrelocdsk + (* - reloc) + sta DRV0EN, y + bcs seekret + } else { ;allow_multi = 0 + bne seekret + } ;allow_multi = 1 + spinup ldy #6 - jsr delay dey @@ -1554,77 +1791,14 @@ delay -- ldx #$11 - dex bne - - sec + inc scratchlo + bne + + inc scratchhi ++ sec sbc #1 bne -- rts - ;no tricks here, just the regular stuff - -seek ldy #0 - sty step - asl phase - txa - asl -copy_cur tax - sta tmptrk - sec - sbc phase - beq +++ - bcs + - !if ver_02 = 1 { - eor #$ff - } else { ;ver_02 = 0 - inc - } ;ver_02 = 1 - inx - bcc ++ -+ - !if ver_02 = 1 { - sbc #1 - } else { ;ver_02 = 0 - dec - } ;ver_02 = 1 - dex -++ cmp step - bcc + - lda step -+ cmp #8 - bcs + - tay - sec -+ - !if ver_02 = 1 { - txa - pha - } else { ;ver_02 = 0 - phx - } ;ver_02 = 1 - ldx step1, y -+++ php - bne + ---- clc - lda tmptrk - ldx step2, y -+ stx tmpsec - and #3 - rol - tax - lsr -unrseek = unrelocdsk + (* - reloc) - lda PHASEOFF, x --- ldx #$12 -- dex - bpl - - dec tmpsec - bne -- - bcs --- - plp - beq seekret - pla - inc step - bne copy_cur - step1 !byte 1, $30, $28, $24, $20, $1e, $1d, $1c step2 !byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c @@ -1644,13 +1818,21 @@ readadr seekret rts readd5aa + !if poll_drive = 1 { + ldx #0 + ldy #0 + } ;poll_drive = 1 +-- + !if poll_drive = 1 { + inx + beq + + } ;poll_drive = 1 -- jsr readnib - cmp #$d5 bne -- jsr readnib cmp #$aa bne - - tay ;we need Y=#$AA later readnib unrread1 = unrelocdsk + (* - reloc) @@ -1658,79 +1840,37 @@ unrread1 = unrelocdsk + (* - reloc) bpl - rts - !if (poll_drive + allow_multi) > 0 { -poll ldy #0 + !if poll_drive = 1 { ++ iny + bne --- + +callstack ldx #0 + inx + inx + txs + jmp nodisk + } ;poll_drive = 1 + +poll ldx #$ff unrread2 = unrelocdsk + (* - reloc) - lda Q6L jsr seekret pha pla unrread3 = unrelocdsk + (* - reloc) - cmp Q6L - clc + eor Q6L bne + - dey + dex bne - - sec + rts - } ;poll_drive = 1 or allow_multi = 1 readdirsel - !if ver_02 = 1 { - pha - txa - pha - } else { ;ver_02 - pha - phx - } ;ver_02 = 1 - -unrdrvon4 = unrelocdsk + (* - reloc) - lda MOTORON !if (ver_02 + allow_multi) > 0 { ldy #0 sty adrlo - !if poll_drive = 1 { - sty status - } ;poll_drive = 1 } else { ;ver_02 = 0 and allow_multi = 0 stz adrlo - !if poll_drive = 1 { - stz status - } ;poll_drive = 1 } ;ver_02 = 1 or allow_multi = 1 - !if allow_multi = 1 { - asl reqcmd - bcc seldrive -twodrives nop ;replace with INY if drive exists -seldrive lsr reqcmd -unrdrvsel2 = unrelocdsk + (* - reloc) - lda DRV0EN, y - cpy driveind + 1 - sty driveind + 1 - beq nodelay - jsr spinup - -nodelay - } ;allow_multi = 1 - !if poll_drive = 1 { - jsr poll - bcc + - pla - pla - pla - pla - jmp nodisk -+ - } ;poll_drive = 1 - !if ver_02 = 1 { - pla - tax - pla - } else { ;ver_02 - plx - pla - } ;ver_02 = 1 readdirsec !if allow_trees = 0 { @@ -1764,15 +1904,24 @@ seekrdwr rol sta reqsec -driveind ldy #0 + !if allow_multi = 1 { + ldy driveind + 1 ldx trackd1, y + } else { ;allow_multi = 0 +trackd1 = * + 1 + ldx #$d1 + } ;allow_multi = 1 ;if track does not match, then seek cpx phase beq checksec lda phase + !if allow_multi = 1 { sta trackd1, y + } else { ;allow_multi = 0 + sta trackd1 + } ;allow_multi = 1 jsr seek ;match or read/write sector @@ -1796,6 +1945,7 @@ cmpsecrd jsr readadr jsr readd5aa eor #$ad ;zero A if match bne cmpsecrd + ldy #$aa unrread4 = unrelocdsk + (* - reloc) - ldx Q6L bpl - @@ -1855,9 +2005,8 @@ cmpsecwr jsr readadr ;skip tail #$DE #$AA #$EB some #$FFs ... - ldy #6 -- jsr readnib - dey + ldy #$24 +- dey bpl - ;write sector data @@ -1866,12 +2015,13 @@ unrslot1 = unrelocdsk + (* - reloc) ldx #$d1 lda Q6H, x ;prime drive lda Q7L, x ;required by Unidisk + !if detect_wp = 1 { + asl + ror status + } ;detect_wp = 1 tya sta Q7H, x ora Q6L, x - pha ;3 cycles - pla ;4 cycles - nop ;2 cycles ;40 cycles @@ -1989,7 +2139,7 @@ loopchk7 writenib1 jsr writeret ;6 cycles writenib2 -unrslot4=unrelocdsk+(*-reloc) +unrslot4 = unrelocdsk + (* - reloc) ldx #$d1 ;2 cycles sta Q6H, x ;5 cycles ora Q6L, x ;4 cycles @@ -1997,19 +2147,20 @@ writeret rts ;6 cycles prolog !byte $ad, $aa, $d5 prolog_e - !if >(prolog - 1) != >prolog_e { + !if >(prolog - 1) != >(prolog_e - 1) { !serious "prologue crosses a page" } epilog !byte $ff, $eb, $aa, $de epilog_e - !if >(epilog - 1) != >epilog_e { + !if >(epilog - 1) != >(epilog_e - 1) { !serious "epilogue crosses a page" } } ;enable_write = 1 codeend + !if allow_multi = 1 { trackd1 !byte 0 trackd2 !byte 0 - + } ;allow_multi = 1 bit2tbl = (* + 255) & -256 nibtbl = bit2tbl + 86 !if enable_write = 1 { @@ -2024,19 +2175,16 @@ dataend = nibtbl + 106 unrelochdd !pseudopc reloc { !if rwts_mode = 1 { - !if no_interrupts = 1 { - php - sei - jsr + - plp - rts -+ - } ;no_interrupts = 1 !if swap_zp = 1 { + sta zp_array + namhi - first_zp + sty zp_array + namlo - first_zp jsr swap_zpg - } ;swap_zp = 1 + } else { ;swap_zp = 0 sta namhi sty namlo + } ;swap_zp = 1 + +loopsect !if ver_02 = 1 { lda #0 sta sizehi @@ -2051,11 +2199,11 @@ unrelochdd bcc skipinit ;read beq skipinit ;write ldy #5 ;sector - !if ver_02 = 1 { + !if ver_02 = 1 { txa - } else { ;ver_02 + } else { ;ver_02 lda #0 - } ;ver_02 = 1 + } ;ver_02 = 1 sta (namlo),y dey ;track sta (namlo),y @@ -2141,6 +2289,13 @@ lastvol = * + 1 !if enable_write = 1 { ldy #$0c ;command lda (namlo),y + !if enable_seek = 1 { + !if swap_zp = 0 { + beq + + } else { ;swap_zp = 1 + beq swap_zpg + } ;swap_zp = 0 + } ;enable_seek ldy #0 lsr bne runinit @@ -2167,28 +2322,32 @@ runinit !if enable_format = 1 { bne format } ;enable_format = 1 + !if write_sparse = 1 { + lda sparseblk + beq writesparse + } ;write_sparse = 1 - lda (scratchlo),y sta (adrlo),y iny bne - - lda adrhi - and #$fe + !if write_sparse = 0 { + lda #>hddencbuf sta adrhi ldy #cmdwrite unrcommand1 = unrelochdd + (* - reloc) sty command - !if use_smartport = 1 { + !if use_smartport = 1 { nop ;allow replacing "sty command" with "sty pcommand" in extended SmartPort mode - } ;use_smartport = 1 - !if swap_zp = 1 { + } ;use_smartport = 1 + !if swap_zp = 1 { jsr hddwriteimm - !if enable_format = 1 { + !if enable_format = 1 { bcc swap_zpg ;always - } ;enable_format = 1 - } else { ;swap_zp = 0 + } ;enable_format = 1 + } else { ;swap_zp = 0 jmp hddwriteimm - } ;swap_zp = 1 - !if enable_format = 1 { + } ;swap_zp = 1 + !if enable_format = 1 { clrcarry clc inc adrhi format lda blanksec,x @@ -2206,8 +2365,7 @@ format lda blanksec,x lda #$18 ;blocks sta namlo sty namhi - lda adrhi - and #$fe + lda #>hddencbuf sta adrhi lda #cmdwrite sta reqcmd @@ -2220,29 +2378,28 @@ format lda blanksec,x bne - dec namhi bpl - - } ;enable_format = 1 + } ;enable_format = 1 + } else { ;write_sparse = 1 + !if swap_zp = 1 { + jsr hddwriteenc + } else { ;swap_zp = 0 + jmp hddwriteenc + } ;swap_zp = 1 + } ;write_sparse = 0 } ;enable_write = 1 !if swap_zp = 1 { -swap_zpg pha - tya - pha - ldx #(last_zp - first_zp) +swap_zpg ldx #(last_zp - first_zp) - lda first_zp,x ldy zp_array,x sta zp_array,x sty first_zp,x dex bpl - - pla - tay - pla } ;swap_zp = 1 !if (enable_write + swap_zp) > 0 { - !if no_interrupts = 0 { clc - } ;no_interrupts = 0 rts } ;enable_write = 1 or swap_zp = 1 @@ -2250,53 +2407,155 @@ swap_zpg pha blanksec !text "SAN INC." } ;enable_format = 1 + !if write_sparse = 1 { +writesparse ldx #2 + tya + !if fast_subindex = 0 { + jsr hddreaddirsec + } else { ;fast_subindex = 1 + ldy #>hddencbuf + jsr hddreaddirsect + } ;fast_subindex = 0 + !if ver_02 = 1 { + lda #0 + sta sizelo + sta sizehi + } else { ;ver_02 = 0 + stz sizelo + stz sizehi + } ;ver_02 = 1 + + ;round up to block count + + lda hddencbuf + $29 + adc #$ff + lda hddencbuf + $2A + adc #1 + lsr + sta ldrhi + ldx hddencbuf + $27 + lda hddencbuf + $28 +--- ldy #>hddencbuf + sty adrhi + jsr hddseekrd + ldy #0 + + ;scan for a free block + +-- lda #$80 + sta ldrlo +- lda (adrlo), y + and ldrlo + bne foundbit + inc sizelo + lsr ldrlo + bcc - + lda sizelo + bne + + inc sizehi ++ iny + bne -- + inc adrhi + lda adrhi + cmp #(>hddencbuf) + 2 + bne -- +unrbloklo2 = unrelochdd + (* - reloc) + ldx bloklo + !if use_smartport = 1 { + nop ;allow replacing "ldx bloklo" with "ldx pblock" in extended SmartPort mode + } ;use_smartport = 1 + + inx + bne + +unrblokhi2 = unrelochdd + (* - reloc) + inc blokhi + !if use_smartport = 1 { + nop ;allow replacing "inc blokhi" with "inc pblock + 1" in extended SmartPort mode + } ;use_smartport = 1 ++ +unrblokhi3 = unrelochdd + (* - reloc) + lda blokhi + !if use_smartport = 1 { + nop ;allow replacing "lda blokhi" with "lda pblock + 1" in extended SmartPort mode + } ;use_smartport = 1 + dec ldrhi + bne --- + + ;disk full + + !if swap_zp = 0 { + clc + rts + } else { ;swap_zp = 1 + beq swap_zpg + } ;swap_zp = 0 + + ;allocate block and update bitmap + +foundbit lda (adrlo), y + eor ldrlo + sta (adrlo), y + jsr hddwriteenc + inc lasttree + lda #$60 ;RTS + sta hddskiptree + 2 + jsr hddrdfile + lda #$be ;LDX ,Y + sta hddskiptree + 2 + lda sizelo + sta hdddirbuf, y + lda sizehi + sta hdddirbuf + 256, y + jsr hddwritedir + lda #0 + jsr savebyte + ldx sizelo + lda sizehi + ldy #cmdwrite + jsr hddseekrdwr + jmp loopsect + +hddwriteenc lda #>hddencbuf + sta adrhi +hddwritedir ldy #cmdwrite + +unrcommand1 = unrelochdd + (* - reloc) + sty command + !if use_smartport = 1 { + nop ;allow replacing "sty command" with "sty pcommand" in extended SmartPort mode + } ;use_smartport = 1 + bne hddwriteimm + } ;write_sparse = 1 + seek1 sta blkidx !if enable_write = 1 { lda #cmdread sta reqcmd } ;enable_write = 1 } else { ;rwts_mode = 0 -hddopendir - !if no_interrupts = 1 { - !if detect_err = 1 { - clc - } ;detect_err = 1 - php - sei - jsr + - !if detect_err = 1 { - pla - adc #0 - pha - } ;detect_err = 1 - plp - rts -+ - } ;no_interrupts = 1 - ;read volume directory key block ;self-modified by init code +hddopendir unrhddblocklo = unrelochdd + (* - reloc) +!ifdef PASS2 { +} else { ;PASS2 + !if (* + 1) != iCurBlockLo { + !error "iCurBlockLo=",* + 1, ", fix constants.a, rebuild prelaunch" + } +} ldx #2 unrhddblockhi = unrelochdd + (* - reloc) +!ifdef PASS2 { +} else { ;PASS2 + !if (* + 1) != iCurBlockHi { + !error "iCurBlockHi=",* + 1, ", fix constants.a, rebuild prelaunch" + } +} lda #0 jsr hddreaddirsel - !if enable_floppy = 1 { - !if (* - hddopendir) < (readdir - opendir) { - ;essential padding to match offset with floppy version - !fill (readdir - opendir) - (* - hddopendir), $ea - } - } ;enable_floppy = 1 - -hddreaddir ;note that calling this location directly limits subdirectories to 14 entries! - lda #NAME_LENGTH + ENTRY_SIZE -hddfirstent sta scratchlo -dirbufpatch1 - lda #>(hdddirbuf - 1) - sta scratchhi - +hddreaddir !if might_exist = 1 { lda hdddirbuf + FILE_COUNT ;assuming only 256 files per subdirectory sta entries @@ -2306,6 +2565,12 @@ dirbufpatch1 } ;many_files = 1 } ;might_exist = 1 + lda #NAME_LENGTH + ENTRY_SIZE +hddfirstent sta scratchlo +dirbufpatch1 + lda #>(hdddirbuf - 1) + sta scratchhi + ;there can be only one page crossed, so we can increment here hddnextent1 inc scratchhi @@ -2345,6 +2610,12 @@ hddnextent ldy #0 and #$0f tax inx + + ;placeholder instructions for path patching + +pathpatch1 + cmp (namlo), y + - eor (namlo), y asl beq hddfoundname @@ -2371,6 +2642,7 @@ hddnextent ldy #0 ;move to next entry in this block, if possible +pathresume + clc lda scratchlo adc #ENTRY_SIZE @@ -2394,6 +2666,7 @@ hddfoundname iny dex bne - +pathpatch2 ;initialise essential variables !if allow_trees = 1 { @@ -2411,7 +2684,9 @@ hddfoundname iny !if aligned_read = 0 { ldy reqcmd cpy #cmdwrite ;control carry instead of zero + !if one_shot = 0 { bne + + } ;one_shot = 0 } ;aligned_read = 0 !if one_shot = 0 { @@ -2436,7 +2711,15 @@ hddfoundname iny !if (bounds_check + return_size + one_shot) > 0 { ;cache EOF (file size, loaded backwards) - ldy #EOF_HI + ldy #EOF_HI2 + lda (scratchlo), y + beq not48 + lda #$ff + tax + bne + + +not48 + dey lda (scratchlo), y !if (enable_write + aligned_read) > 0 { tax @@ -2449,9 +2732,9 @@ hddfoundname iny !if aligned_read = 0 { bcc + } else { ;aligned_read = 1 - !if enable_write = 1 { + !if (enable_write + (one_shot xor 1)) > 1 { sec - } ;enable_write = 1 + } ;enable_write = 1 and one_shot = 0 } ;aligned_read = 0 adc #$fe txa @@ -2489,50 +2772,38 @@ hddfoundname iny } ;one_shot = 0 } ;enable_write = 1 or aligned_read = 1 } ;bounds_check = 1 or return_size = 1 or one_shot = 1 + ;cache AUX_TYPE (load offset for binary files) !if override_adr = 0 { ldy #AUX_TYPE - lda (scratchlo), y - !if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 { - sta ldrlo - iny - lda (scratchlo), y + jsr fetchscratch + stx ldrlo sta ldrhi - } else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1 - pha - iny - lda (scratchlo), y - pha - } ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0 } ;override_adr = 0 ;;allow query even in override mode ldy #AUX_TYPE - lda (scratchlo), y - sta ldrlo2 - iny - lda (scratchlo), y + jsr fetchscratch + stx ldrlo2 sta ldrhi2 ;cache KEY_POINTER ldy #KEY_POINTER - lda (scratchlo), y - tax + jsr fetchscratch !if (allow_subdir + allow_saplings + allow_trees) > 0 { dirbufpatch4 - sta hdddirbuf + stx hdddirbuf !if (allow_trees + (fast_trees xor 1)) > 1 { - sta treeblklo + stx treeblklo } ;allow_trees = 1 and fast_trees = 0 - iny - lda (scratchlo), y dirbufpatch5 sta hdddirbuf + 256 !if (allow_trees + (fast_trees xor 1)) > 1 { sta treeblkhi } ;allow_trees = 1 and fast_trees = 0 + !if always_trees = 0 { plp attribpatch @@ -2541,9 +2812,11 @@ attribpatch php } ;allow_subdir = 1 !if allow_trees = 1 { +dirbufpatch11 ldy #>hdddirbuf bvc + !if fast_trees = 1 { +treebufpatch1 ldy #>hddtreebuf } ;fast_trees = 1 sty istree @@ -2577,24 +2850,6 @@ hddrdwrfilex !if allow_subdir = 1 { clc } ;allow_subdir = 1 -!if (no_interrupts + (rwts_mode xor 1)) > 1 { - !if detect_err = 1 { - !if allow_subdir = 0 { - clc - } ;allow_subdir = 0 - } ;detect_err = 1 - php - sei - jsr + - !if detect_err = 1 { - pla - adc #0 - pha - } ;detect_err = 1 - plp - rts -+ -} ;no_interrupts = 1 and rwts_mode = 0 hddrdwrfilei !if rwts_mode = 0 { @@ -2700,6 +2955,9 @@ encbufpatch1 + !if enable_seek = 1 { lda sizehi + !if read_scrn = 1 { + clv + } ;read_scrn = 1 } else { ;enable_seek = 0 ldy sizehi } ;enable_seek = 1 @@ -2726,11 +2984,10 @@ encbufpatch1 clc bne hddrdwrfilei } else { ;no_interrupts = 0 - beq hddrdwrdone + beq + jmp hddrdwrfilex ++ jmp hddrdwrdone } ;no_interrupts = 1 - } else { ;allow_subdir = 0 - bne hddrdwrfilei } ;allow_subdir = 1 !if allow_aux = 0 { rts @@ -2761,7 +3018,29 @@ hddrdwrloop lda sizehi cmp #2 + !if read_scrn = 1 { + clv + bcc redirect + !if (enable_write + enable_seek) > 0 { + txa + beq + + } ;enable_write = 1 or enable_seek = 1 + ldy ldrhi + cpy #8 bcs + + bit knownrts ;set O flag + lda sizehi + pha + lda sizelo + pha + lda #0 + sta sizelo + lda #1 + +redirect + } else { ;read_scrn = 0 + bcs + + } ;read_scrn = 1 pha ;redirect read to private buffer for partial copy @@ -2814,9 +3093,6 @@ encbufpatch2 !if aligned_read = 0 { php } ;aligned_read = 0 - lda #>hdddirbuf - sta adrhi - sty adrlo } else { ;rwts_mode = 1 !if fast_subindex = 0 { ;read whenever block index changes @@ -2829,8 +3105,8 @@ blkidx = * + 1 ldy #$d1 lastblk = * + 1 cpy #$d1 - } ;mem_swap = 0 sty lastblk + } ;mem_swap = 0 php pla !if mem_swap = 0 { @@ -2849,6 +3125,11 @@ lasttree = * + 1 bne readtree pha plp + !if enable_write = 1 { + bne readtree + lda reqcmd + lsr + } ;enable_write = 1 beq skipblk readtree @@ -2893,7 +3174,9 @@ blkidx = * + 1 !if rwts_mode = 0 { inc treeidx } ;rwts_mode = 0 +treebufpatch2 ldx hddtreebuf, y +treebufpatch3 lda hddtreebuf + 256, y } ;fast_trees = 0 !if detect_treof = 1 { @@ -2918,6 +3201,9 @@ hddnoteof1 } ;detect_treof = 1 !if fast_trees = 0 { +dirbufpatch12 + lda #>hdddirbuf + sta adrhi jsr hddseekrd } else { ;fast_trees = 1 jsr hddreaddirsel @@ -2973,7 +3259,15 @@ unrcommand2 = unrelochdd + (* - reloc) lastblk = * + 1 cpy #$d1 } ;mem_swap = 0 + !if enable_write = 0 { beq skipblk + } else { ;enable_write = 1 + bne + + lda reqcmd + lsr + beq skipblk ++ + } ;enable_write = 0 sty lastblk } ;fast_subindex = 1 } ;rwts_mode = 0 @@ -2998,37 +3292,41 @@ hddnoteof2 jmp hddseekrd } else { ;enable_write = 1 ldy reqcmd + !if enable_seek = 1 { jmp hddseekrdwr + } else { ;enable_seek = 0 + bne hddseekrdwr + } ;enable_seek = 1 } ;enable_write = 0 } ;rwts_mode = 1 } else { ;allow_sparse = 1 pha dirbufpatch9 ora hdddirbuf, y - tay - pla - !if rwts_mode = 0 { - dey - iny ;don't affect carry - } else { ;rwts_mode = 1 + !if write_sparse = 1 { + sta sparseblk + } ;write_sparse = 1 + !if rwts_mode = 1 { !if enable_write = 1 { - cpy #1 + cmp #1 + pla ldy reqcmd bcs hddseekrdwr +savebyte tay } else { ;enable_write = 0 + tay + pla dey iny ;don't affect carry bne hddseekrd } ;enable_write = 1 - } ;rwts_mode = 0 + } ;rwts_mode = 1 } ;allow_sparse = 0 !if rwts_mode = 0 { - !if aligned_read = 0 { - php - } ;aligned_read = 0 !if allow_sparse = 1 { beq hddissparse + pla } ;allow_sparse = 1 !if (aligned_read and (enable_write or enable_seek)) = 1 { ldy reqcmd @@ -3036,23 +3334,31 @@ dirbufpatch9 beq + } ;enable_seek = 1 } ;aligned_read = 1 and (enable_write = 1 or enable_seek = 1) + !if aligned_read = 0 { + php + } ;aligned_read = 0 !if enable_write = 1 { jsr hddseekrdwr } else { ;enable_write = 0 jsr hddseekrd } ;enable_write = 1 + !if aligned_read = 0 { + plp + } ;aligned_read = 0 hddresparse !if aligned_read = 0 { - plp + bcc + + } ;aligned_read = 0 + inc adrhi + inc adrhi + !if aligned_read = 0 { +resumescrn !if bounds_check = 1 { dec blefthi dec blefthi } ;bounds_check = 1 } ;aligned_read = 0 - inc adrhi - inc adrhi dec sizehi dec sizehi bne hddrdwrloop @@ -3071,6 +3377,10 @@ hddsetaux sta CLRAUXRD, x !if allow_sparse = 1 { hddissparse + !if rwts_mode = 0 { + pla + } ;rwts_mode = 0 + tay - sta (adrlo), y inc adrhi sta (adrlo), y @@ -3114,12 +3424,29 @@ hddcopycache bne - inc scratchhi inc adrhi + !if read_scrn = 1 { + bvs copyhalf + } ;read_scrn = 1 bne + +copyhalf - lda (adrlo), y sta (scratchlo), y iny + cpy sizelo bne - + !if read_scrn = 1 { + bvc ++ + pla + sta sizelo + pla + sta sizehi + ldx scratchhi + inx + stx adrhi + lda scratchlo + sta adrlo + bvs resumescrn + } ;read_scrn = 1 ++ !if one_shot = 0 { !if bounds_check = 1 { @@ -3152,24 +3479,14 @@ hddcopycache } ;allow_aux = 1 } ;one_shot = 0 } ;aligned_read = 0 -} else { ;rwts_mode = 1 - !if allow_sparse = 0 { -skipblk rts - } ;allow_sparse = 0 } ;rwts_mode = 0 hddreaddirsel !if ver_02 = 1 { ldy #0 sty adrlo - !if might_exist = 1 { - sty status - } ;might_exist = 1 } else { ;ver_02 = 0 stz adrlo - !if might_exist = 1 { - stz status - } ;might_exist = 1 } ;ver_02 = 1 !if (enable_floppy + allow_multi) > 1 { @@ -3179,9 +3496,9 @@ hddreaddirsel hddreaddirsec !if allow_trees = 0 { -dirbufpatch10 hddreaddirsect ldy #>hdddirbuf } else { ;allow_trees = 1 +dirbufpatch10 ldy #>hdddirbuf hddreaddirsect } ;allow_trees = 0 @@ -3199,12 +3516,12 @@ unrcommand3 = unrelochdd + (* - reloc) hddseekrdwr } ;aligned_read = 0 or enable_write = 0 -unrbloklo = unrelochdd + (* - reloc) +unrbloklo1 = unrelochdd + (* - reloc) stx bloklo !if use_smartport = 1 { nop ;allow replacing "stx bloklo" with "stx pblock" in extended SmartPort mode } ;use_smartport = 1 -unrblokhi = unrelochdd + (* - reloc) +unrblokhi1 = unrelochdd + (* - reloc) sta blokhi !if use_smartport = 1 { nop ;allow replacing "sta blokhi" with "sta pblock + 1" in extended SmartPort mode @@ -3225,8 +3542,11 @@ hddwriteimm lda adrhi ;for Trackstar support } ;swap_scrn = 1 unrentrysei = unrelochdd + (* - reloc) +!if no_interrupts = 1 { php sei +} ;no_interrupts = 1 +retry unrentry = unrelochdd + (* - reloc) jsr $d1d1 !if use_smartport = 1 { @@ -3235,7 +3555,23 @@ pcommand !byte $2c ;hide packet in non-SmartPort mode unrppacket = unrelochdd + (* - reloc) !word unrelochdd + (packet - reloc) } ;use_smartport = 1 + bcc goodread +unrgetreq = unrelochdd + (* - reloc) + lda reqcmd +!if use_smartport = 1 { + nop ;allow replacing "lda reqcmd" with "lda pcommand" in extended SmartPort mode +} ;use_smartport = 1 + + ;read failures are assumed to be transient + ;write failures are assumed to be permanent + + cmp #cmdread + beq retry + +goodread +!if no_interrupts = 1 { plp +} ;no_interrupts = 1 hackstar = unrelochdd + (* - reloc) pla sta adrhi ;Trackstar does not preserve adrhi @@ -3272,6 +3608,9 @@ initpatch lda ($48), y dec $4a bne -- } ;swap_scrn = 1 +!if (rwts_mode + (allow_sparse xor 1)) > 1 { +skipblk +} ;rwts_mode = 1 and allow_sparse = 0 rts fetchscratch @@ -3288,6 +3627,27 @@ unrunit2 = unrelochdd + (* - reloc) !byte 0 paddr !word readbuff + $200 pblock !byte 2, 0, 0 + !if >pcommand != >(pblock + 1) { + !if >pcommand != >pblock { + !ifdef pblock_enabled { + } else { + !ifdef PASS2 { + !warn "uncomment ';;lda #>pblock'" + !warn "uncomment ';;pblock_enabled=1'" + !warn "uncomment ';;lda #>paddr'" + } + } + } else { + !ifdef pblock1_enabled { + } else { + !ifdef PASS2 { + !warn "uncomment ';;lda #>(pblock + 1)'" + !warn "uncomment ';;pblock1_enabled=1'" + !warn "uncomment ';;lda #>paddr'" + } + } + } + } } ;use_smartport = 1 !if (rwts_mode + allow_multi) > 1 { @@ -3369,6 +3729,9 @@ hdddataend } ;aligned_read = 0 or enable_write = 1 !if allow_trees = 1 { !if fast_trees = 1 { + !if enable_write = 0 { + encbuf = dirbuf ;there is no encbuf + } ;enable_write = 0 !if ((aligned_read xor 1) + rwts_mode) > 0 { !if encbuf < reloc { treebuf = encbuf - $200 @@ -3426,7 +3789,7 @@ hdddataend !pseudopc ((dataend + $ff) & -256) { dirbuf = * } - !if aligned_read = 0 { + !if ((aligned_read xor 1) + enable_write) > 0 { encbuf = dirbuf + $200 } ;aligned_read !if allow_trees = 1 { @@ -3564,13 +3927,17 @@ hdddataend !pseudopc ((hdddataend + $ff) & -256) { hdddirbuf = $d200 } - !if aligned_read = 0 { - hddencbuf = hdddirbuf - $200 - } ;aligned_read + !if ((aligned_read xor 1) + rwts_mode) > 0 { + !if fast_subindex = 0 { + hddencbuf = hdddirbuf ;writes come from cache + } else { ;fast_subindex = 1 + hddencbuf = hdddirbuf - $200 + } ;fast_subindex + } ;aligned_read = 0 or rwts_mode = 1 !if allow_trees = 1 { !if fast_trees = 1 { !if ((aligned_read xor 1) + enable_write) > 0 { - hddtreebuf = hddencbuf + $200 + hddtreebuf = hddencbuf + $400 } else { ;aligned_read = 1 and enable_write = 0 hddtreebuf = hdddirbuf + $200 } ;aligned_read = 0 or enable_write = 1 diff --git a/src/textrank.a b/src/textrank.a index 61ebe76..f510bf3 100644 --- a/src/textrank.a +++ b/src/textrank.a @@ -4,8 +4,9 @@ ; text rank - an implementation of the Quicksilver search rank algorithm ; ; Public functions -; - BuildSearchStore +; - ReloadSearchIndex ; - ResetTextRank +; - FindTitleInCache ; - TextRankCallback (as okvs_iter_values callback) ; ; Public variables @@ -25,43 +26,61 @@ InputBuffer !text " " ;------------------------------------------------------------------------------ -; BuildSearchStore -; Build a temporary data structure in main memory to support search UI. -; Now that gGamesListStore no longer contains full game display names, we call -; this to build a store that does. It's built in main memory and will be -; clobbered as soon as we enter attract mode (mega- or mini-), run a game, -; run a demo, or sneeze. +; ReloadSearchIndex +; +; Load indexes to support search UI ; ; in: none ; out: gSearchStore populated ;------------------------------------------------------------------------------ -BuildSearchStore - jsr SwitchToBank2 - jsr EnableAcceleratorAndSwitchToBank1 - +LDADDR gSearchStore - jsr okvs_init +ReloadSearchIndex + jsr LoadIndexedFile ; load appropriate search index into $8200 + !word gSearchIndex + !word kSearchIndexRecord + jsr LoadIndexedFile ; load appropriate search cache into $B000 + !word gSearchCache + !word kSearchCacheRecord + rts - jsr okvs_iter - !word gGamesListStore - !word @callback - - jsr SwitchToBank2 - jmp DisableAcceleratorAndSwitchToBank1 -@callback -; callback called by okvs_iter on gGamesListStore - -; in: A/Y contains address of filename -; $WINDEX contains 0-based index of the current record in gGamesListStore (word) -; out: all registers and flags clobbered - +ST16 @key - jsr GetGameDisplayName - +ST16 @value -@append - jsr okvs_append - !word gSearchStore -@key !word $FDFD ; SMC -@value !word $FDFD ; SMC - !byte 0 +FindTitleInCache + ldx InputLength + cpx #5 + bcs @nomatch + lda #$20 + sta InputBuffer, x + +LDADDR gSearchCache + +ST16 PTR + ldx #$FF +-- inx + ldy #0 +- lda (PTR), y + beq @nomatch + cmp InputBuffer, x + beq @matchchar + iny + iny + iny + bne - ; always branches +@matchchar + iny + lda (PTR), y + pha + iny + lda (PTR), y + bpl @foundindex + sta PTR+1 + pla + sta PTR + cpx InputLength + bcc -- +@nomatch + sec + rts +@foundindex + sta BestMatchIndex+1 + pla + sta BestMatchIndex + clc rts ;------------------------------------------------------------------------------ diff --git a/src/ui.animation.a b/src/ui.animation.a index 67b3caa..071c960 100644 --- a/src/ui.animation.a +++ b/src/ui.animation.a @@ -13,7 +13,7 @@ ; slow down to 1 Mhz (always), then check if there is an animation for the ; title screenshot we just displayed, and if so, load it and call it ; -; in: none +; in: gSearchStore is populated ; out: C clear ; all other flags clobbered ; all registers clobbered @@ -61,7 +61,7 @@ MaybeAnimateTitle bit $c050 ; turn on graphics mode (Home set text mode) jsr Launch ; execute the animation - jsr BuildSearchStore + jsr ReloadSearchIndex jsr ResyncPage ; we don't know which HGR page is showing ; when the animation returns, so resync ; the current one with our OffscreenPage diff --git a/src/ui.attract.dgr.a b/src/ui.attract.dgr.a new file mode 100644 index 0000000..91f9603 --- /dev/null +++ b/src/ui.attract.dgr.a @@ -0,0 +1,124 @@ +;license:MIT +;(c) 2021 by 4am +; +; DGR action slideshows +; +; Public functions +; - DGRActionSlideshow +; - DGRSingle +; - BlankDGR +; - LoadIndexedDGRFile +; + +;------------------------------------------------------------------------------ +; DGRActionSlideshow +; display a slideshow of double lo-res action screenshots +; +; safe to call if machine only has 64K (does nothing and exits) +; +; in: none +; out: everything clobbered +; graphics mode set to display hi-res screen, which is blank +;------------------------------------------------------------------------------ +DGRActionSlideshow + bit MachineStatus ; only run DGR slideshow if we have 128K + bvc DGRRTS + jsr LoadDGRTransition ; load transition effect code at $6000 + jsr BlankDGR ; switch to DGR mode with initial blank screen + jsr okvs_iter ; cycle through all listed DGR files + !word gSlideshowStore + !word DGRActionCallback ; address of callback (called on each file) + jmp BlankHGRNoHome ; switch back to HGR mode with initial blank screen on exit + +;------------------------------------------------------------------------------ +; DGRSingle +; display a single lo-res screenshot, with transition effect +; +; in: none +; out: everything clobbered +; graphics mode set to display hi-res screen +;------------------------------------------------------------------------------ +DGRSingle + +ST16 IndexedDGRFilename + jsr BlankDGR ; switch to DGR mode with initial blank screen + jsr LoadIndexedDGRFile ; load DGR screen at $4000 + jsr LoadDGRTransition ; load transition effect code at $6000 + jsr ExecuteTransitionAt6000AndWait + jmp BlankHGRNoHome ; switch back to HGR mode with initial blank screen on exit + +;------------------------------------------------------------------------------ +; LoadDGRTransition [private] +; +; in: none +; out: all registers and flags clobbered +; $6000..$BFFF/main contains transition effect code (probably not all +; of that, but no promises) +;------------------------------------------------------------------------------ +LoadDGRTransition + jsr LoadIndexedFile + !word $6000 + !word kDGRFizzleRecord +DGRRTS rts + +;------------------------------------------------------------------------------ +; DGRActionCallback [private] +; callback called by okvs_iter on gSlideshowStore +; to load and display a single DGR action screenshot + +; in: A/Y contains address of filename (name only, path is always /ACTION.DGR/) +; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) +; out: all registers and flags clobbered +; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) +; $2000..$BFFF clobbered by graphics data and transition code +;------------------------------------------------------------------------------ +DGRActionCallback + bit KBD + bmi DGRRTS + + +ST16 IndexedDGRFilename + + jsr FindGame + ; if game name is not found (C will be set here), it means the game + ; can't be played due to memory or joystick requirements, so we hide + ; it from slideshows + bcs DGRRTS + + jsr LoadIndexedDGRFile + jmp ExecuteTransitionAt6000AndWait + +BlankDGR + jsr BlankDHGR ; clear and display DHGR screen + ldy #$2C ; BIT + sty PageFrom ; now clear DGR screen + ldx #$04 + stx PageTo+2 + jsr ClearToBlack + sta WRITEAUXMEM + ldx #$04 + stx PageTo+2 + jsr ClearToBlack + sta WRITEMAINMEM + lda #1 + sta OffscreenPage + bit $C056 ; display DGR screen + rts + +LoadIndexedDGRFile +; in: caller has set IndexedDGRFilename +; out: all flags & registers clobbered + jsr LoadIndexedFile ; load index file into $4000 +- !word $4000 + !word kDGRActionIndexRecord + + jsr okvs_find + !word - +IndexedDGRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load entire DGR screenshot at $7C00 + !word $7C00 ; because that's where the transition code expects to find it + ; auxmem half is first, mainmem second +@indexRecordPtr + !word $FDFD ; SMC + rts diff --git a/src/ui.attract.dhgr.a b/src/ui.attract.dhgr.a index 29306f7..3e034a1 100644 --- a/src/ui.attract.dhgr.a +++ b/src/ui.attract.dhgr.a @@ -1,5 +1,4 @@ -;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Double hi-res slideshows ; @@ -27,7 +26,7 @@ ;------------------------------------------------------------------------------ DHGRTitleSlideshow bit MachineStatus ; only run DHGR slideshow if we have 128K - bvc DHGRRTS + bvc DHGRRTS0 jsr LoadDHGRTransition ; load transition effect code at $6000 jsr BlankDHGR ; switch to DHGR mode with initial blank screen jsr okvs_iter ; cycle through all listed DHGR files @@ -48,7 +47,7 @@ DHGRTitleSlideshow ;------------------------------------------------------------------------------ DHGRActionSlideshow bit MachineStatus ; only run DHGR slideshow if we have 128K - bvc DHGRRTS + bvc DHGRRTS0 jsr LoadDHGRTransition ; load transition effect code at $6000 jsr BlankDHGR ; switch to DHGR mode with initial blank screen jsr okvs_iter ; cycle through all listed DHGR files @@ -69,13 +68,10 @@ DHGRActionSlideshow ;------------------------------------------------------------------------------ DHGRSingle bit MachineStatus ; only show DHGR screenshots if we have 128K - bvc DHGRRTS - +ST16 @fname + bvc DHGRRTS0 + +ST16 IndexedDHGRFilename jsr BlankDHGR ; switch to DHGR mode with initial blank screen - jsr LoadAuxFile ; load compressed DHGR screenshot at aux $3FF8 - !word kRootDirectory -@fname !word $FDFD ; SMC - !word $3FF8 + jsr LoadIndexedDHGRFile ; load compressed DHGR screenshot at aux $3FF8 jsr DecompressDHGR jsr LoadDHGRTransition ; load transition effect code at $6000 jsr ExecuteTransitionAt6000AndWait @@ -86,12 +82,13 @@ DHGRSingle ; clear and show HGR page 1 without flickering ; ; in: none -; out: text page clobbered (but screen holes preserved) +; out: text page clobbered ; A/X/Y=0 (guaranteed by ClearHGR1) ; $2000..$3FFF cleared ;------------------------------------------------------------------------------ BlankHGR jsr Home +BlankHGRNoHome jsr ClearHGR1 ; clear hi-res screen 1 bit PAGE1 ; show hi-res screen 1 (now blank) lda #1 @@ -109,7 +106,7 @@ HGRMode GRMode bit $C052 bit $C050 -DHGRRTS rts +DHGRRTS0 rts ;------------------------------------------------------------------------------ ; ForceHGRMode @@ -123,7 +120,7 @@ ForceHGRMode gMachineInDHGRMode=*+1 lda #$00 ; SMC bne BlankHGR - beq DHGRRTS + rts ;------------------------------------------------------------------------------ ; LoadDHGRTransition [private] @@ -136,21 +133,16 @@ gMachineInDHGRMode=*+1 ; $6000..$BFFF/main contains transition effect code ;------------------------------------------------------------------------------ LoadDHGRTransition - jsr LoadFile ; load DHGR transition effects list into $8000 - !word kRootDirectory - !word kDFXConfFile -- !word $8000 - jsr ParseKeyValueList ; parse DHGR transition effects list into $6000 - !word gDFXStore - !word - - !byte 0 + jsr LoadIndexedFile ; load DHGR transition effects list into $6000 +- !word $6000 + !word kDFXIndexRecord jsr pref_get ; get DHGR transition effect from prefs !word kNextDFX - !word gDFXStore - +ST16 ++ ; A/Y = filename (don't load file yet) + !word - + +ST16 @indexRecordPtr ; A/Y = filename (don't load file yet) ; $WINDEX = index of the transition in DFX store - +LDADDR gDFXStore + +LDADDR - jsr okvs_next ; get transition after this one +ST16 + @@ -158,11 +150,11 @@ LoadDHGRTransition !word kNextDFX + !word $FDFD ; SMC - jsr LoadFile ; now load transition effect code into $6000 - !word kFXDirectory -++ !word $FDFD ; SMC + jsr LoadIndexedFile !word $6000 - rts +@indexRecordPtr + !word $FDFD ; SMC +DHGRRTS1 rts ;------------------------------------------------------------------------------ ; DHGRTitleCallback [private] @@ -178,24 +170,35 @@ LoadDHGRTransition ;------------------------------------------------------------------------------ DHGRTitleCallback bit KBD - bmi DHGRRTS + bmi DHGRRTS1 +ST16 + + +ST16 gLastMegaAttractGame jsr FindGame ; if game is not found (C will be set here), it means it can't be played on ; this machine due to memory or joystick requirements, so we don't display ; it in slideshows - bcs DHGRRTS + bcs DHGRRTS1 +LD16 WINDEX ; save game index in case user hits RETURN +ST16 gGameToLaunch ; while it's visible (we'll launch it) - ; load DHGR screenshot at $4000/main and $4000/aux - jsr LoadDHRFile - !word kDHGRTitleDirectory -+ !word $FDFD + jsr LoadIndexedFile ; load index file into $4000 +- !word $4000 + !word kDHGRTitleIndexRecord + jsr okvs_get + !word - ++ !word $FDFD ; SMC + + jsr SwitchToBank2 + ldy #4 +- lda (PTR), y + sta OKVS_CACHE + 1, y + dey + bpl - + jsr LoadIndexedDHRFile jmp ExecuteTransitionAt6000AndWait ;------------------------------------------------------------------------------ @@ -212,24 +215,17 @@ DHGRTitleCallback ;------------------------------------------------------------------------------ DHGRActionCallback bit KBD - bmi DHGRRTS + bmi DHGRRTS1 - +ST16 + + +ST16 IndexedDHGRFilename - jsr FindGameInActionSlideshow + jsr FindGame ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows - bcs DHGRRTS - +ST16 SAVE ; (SAVE) -> game display name + game info bitfield + bcs DHGRRTS1 - +LD16 WINDEX ; save game index in case user hits RETURN - +ST16 gGameToLaunch ; while it's visible (we'll launch it) - - jsr LoadAuxFile ; load compressed DHGR screenshot at aux $3FF8 - !word kDHGRActionDirectory -+ !word $FDFD - !word $3FF8 + jsr LoadIndexedDHGRFile jsr DecompressDHGR lda #$EA ; NOP @@ -254,19 +250,17 @@ DrawGameTitleInActionSlideshow sta VTAB lda #0 ; solid horizontal bar character jsr @resetline - lda (SAVE),y ; (SAVE) -> game display name, Y = 0, so A = display length + 1 + lda (SAVE),y ; (SAVE) -> game display name, Y = 0, so A = display length clc - adc #$02 + adc #$03 sta gPathname lda #7 ; top-right rounded corner character jsr @drawline - inc VTAB lda #" " jsr @resetline - lda (SAVE),y ; A = display length + 1 + lda (SAVE),y ; A = display length tay - dey - lda (SAVE),y sta gPathname+1,y dey @@ -298,7 +292,7 @@ DrawGameTitleInActionSlideshow ; to display properly on the DHGR screen. ; ; /!\ must be called immediately after calling one of the font drawing routines -; (Draw40Chars, DrawCenteredString, DrawString, DrawBuffer) +; (Draw40Chars, DrawCenteredString, DrawString) ; ; in: gPathname contains number of bytes to transform ; DBIRow0/LC2 contains address of first byte of first row to transform @@ -330,3 +324,22 @@ RedrawForDHGR dec i bne -- jmp SwitchToBank1 + +LoadIndexedDHGRFile +; in: caller has set IndexedDHGRFilename +; out: all flags & registers clobbered + jsr LoadIndexedFile ; load index file into $4000 +- !word $4000 + !word kDHGRActionIndexRecord + + jsr okvs_find + !word - +IndexedDHGRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadAuxIndexedFile ; load compressed DHGR screenshot at aux $3FF8 + !word $3FF8 +@indexRecordPtr + !word $FDFD ; SMC + rts diff --git a/src/ui.attract.gr.a b/src/ui.attract.gr.a index bfdbeff..6dca4f6 100644 --- a/src/ui.attract.gr.a +++ b/src/ui.attract.gr.a @@ -33,14 +33,11 @@ GRActionSlideshow ; graphics mode set to display hi-res screen ;------------------------------------------------------------------------------ GRSingle - +ST16 @fname + +ST16 IndexedGRFilename jsr BlankGR ; switch to GR mode with initial blank screen - jsr LoadFile ; load GR screenshot into $6000 - !word kRootDirectory -@fname !word $FDFD ; SMC - !word $6000 - jsr LoadGRTransition ; load transition effect code at $6400 - jsr ExecuteTransitionAt6400AndWait + jsr LoadIndexedGRFile ; load GR screen at $4000 + jsr LoadGRTransition ; load transition effect code at $6000 + jsr ExecuteTransitionAt6000AndWait jmp BlankHGR ; switch back to HGR mode with initial blank screen on exit ;------------------------------------------------------------------------------ @@ -67,14 +64,13 @@ BlankGR ; ; in: none ; out: all registers and flags clobbered -; $6400..$BFFF/main contains transition effect code (probably not all +; $6000..$BFFF/main contains transition effect code (probably not all ; of that, but no promises) ;------------------------------------------------------------------------------ LoadGRTransition - jsr LoadFile - !word kFXDirectory - !word kGRFizzleFile - !word $6400 + jsr LoadIndexedFile + !word $6000 + !word kGRFizzleRecord GRRTS rts ;------------------------------------------------------------------------------ @@ -84,7 +80,6 @@ GRRTS rts ; in: A/Y contains address of filename (name only, path is always /ACTION.GR/) ; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) -; gGamesListStore must be initialized ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code @@ -93,20 +88,32 @@ GRActionCallback bit KBD bmi GRRTS - +ST16 + + +ST16 IndexedGRFilename - jsr FindGameInActionSlideshow + jsr FindGame ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows bcs GRRTS - +LD16 WINDEX ; save game index in case user hits RETURN - +ST16 gGameToLaunch ; while it's visible (we'll launch it) + jsr LoadIndexedGRFile + jmp ExecuteTransitionAt6000AndWait - jsr LoadFile ; load GR screenshot into $6000 - !word kGRActionDirectory -+ !word $FDFD ; SMC - !word $6000 +LoadIndexedGRFile +; in: caller has set IndexedGRFilename +; out: all flags & registers clobbered + jsr LoadIndexedFile ; load index file into $4600 +- !word $4600 + !word kGRActionIndexRecord - jmp ExecuteTransitionAt6400AndWait + jsr okvs_find + !word - +IndexedGRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load GR screenshot at $4000 + !word $4000 ; because that's where the transition code expects to find it +@indexRecordPtr + !word $FDFD ; SMC + rts diff --git a/src/ui.attract.hgr.a b/src/ui.attract.hgr.a index b177dd6..7d6acd7 100644 --- a/src/ui.attract.hgr.a +++ b/src/ui.attract.hgr.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; HGR title and action slideshows ; @@ -48,11 +48,8 @@ HGRActionSlideshow ; graphics mode still displaying hi-res screen with last picture visible ;------------------------------------------------------------------------------ HGRSingle - +ST16 @fname - jsr LoadFile ; load compressed HGR screenshot at $3FF8 - !word kRootDirectory -@fname !word $FDFD ; SMC - !word $3FF8 + +ST16 IndexedHGRFilename + jsr LoadIndexedHGRFile jsr DecompressHGR jsr LoadHGRTransition ; load transition effect code at $6000 jmp ExecuteTransitionAt6000AndWait @@ -67,21 +64,16 @@ HGRSingle ; $6000..$BFFF contains transition effect code ;------------------------------------------------------------------------------ LoadHGRTransition - jsr LoadFile ; load HGR transition effects list into $8000 - !word kRootDirectory - !word kFXConfFile -- !word $8000 - jsr ParseKeyValueList ; parse HGR transition effects list into $6000 - !word gFXStore - !word - - !byte 0 + jsr LoadIndexedFile ; load HGR transition effects list into $6000 +- !word $6000 + !word kFXIndexRecord jsr pref_get ; get HGR transition effect from prefs !word kNextFX - !word gFXStore - +ST16 ++ ; A/Y = filename (don't load file yet) + !word - + +ST16 @indexRecordPtr ; A/Y = filename (don't load file yet) ; $WINDEX = index of the transition in FX store - +LDADDR gFXStore + +LDADDR - jsr okvs_next ; get transition after this one +ST16 + @@ -89,10 +81,10 @@ LoadHGRTransition !word kNextFX + !word $FDFD ; SMC - jsr LoadFile ; now load transition effect code into $6000 - !word kFXDirectory -++ !word $FDFD ; SMC + jsr LoadIndexedFile !word $6000 +@indexRecordPtr + !word $FDFD ; SMC HGRRTS rts ;------------------------------------------------------------------------------ @@ -110,7 +102,8 @@ HGRTitleCallback bit KBD bmi HGRRTS - +ST16 + + +ST16 @fname + +ST16 gLastMegaAttractGame jsr FindGame ; if game is not found (C will be set here), it means it can't be played on @@ -121,11 +114,27 @@ HGRTitleCallback +LD16 WINDEX ; save game index in case user hits RETURN +ST16 gGameToLaunch ; while it's visible (we'll launch it) - jsr LoadFile ; load HGR screenshot at $4000 - !word kHGRTitleDirectory -+ !word $FDFD ; SMC - !word $4000 + jsr LoadIndexedFile ; load index file into $4000 +- !word $4000 + !word kHGRTitleIndexRecord + jsr okvs_find + !word - +@fname !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load HGR graphic at $4000 + !word $4000 +@indexRecordPtr + !word $FDFD ; SMC + + lda $5FFD + stx $5FFD ; ensure that we won't find it again if next + ; file is really compressed + cmp #$4C ; Check if screen hole now contains a JMP + beq @noUnpack ; if so, file was not packed, so skip unpack + jsr UnpackHGRTitle +@noUnpack jmp ExecuteTransitionAt6000AndWait ;------------------------------------------------------------------------------ @@ -135,7 +144,6 @@ HGRTitleCallback ; in: A/Y contains address of filename (name only, path is always /ACTION.HGR/) ; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) -; gGamesListStore must be initialized ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code @@ -144,23 +152,49 @@ HGRActionCallback bit KBD bmi HGRRTS - +ST16 + + +ST16 IndexedHGRFilename - jsr FindGameInActionSlideshow + jsr FindGame ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows bcs HGRRTS - ; found the game - +ST16 SAVE ; (SAVE) -> game display name + game info bitfield - - +LD16 WINDEX ; save game index in case user hits RETURN - +ST16 gGameToLaunch ; while it's visible (we'll launch it) - - jsr LoadFile ; load compressed HGR screenshot at $3FF8 - !word kHGRActionDirectory -+ !word $FDFD ; SMC - !word $3FF8 + jsr LoadIndexedHGRFile jsr DecompressHGR jmp DrawGameTitleInActionSlideshow + +LoadIndexedHGRFile +; in: caller has set IndexedHGRFilename +; out: all flags & registers clobbered + +LD16 IndexedHGRFilename + +ST16 PTR + ldy #1 + lda (PTR), y + sec + sbc #$41 ; A in [0..25] + lsr ; A in [0..15] + lsr ; A in [0..7] + tax + lda kHGRActionIndexLo, x + sta HGRActionIndexRecord + lda kHGRActionIndexHi, x + sta HGRActionIndexRecord+1 + + jsr LoadIndexedFile ; load index file into $4000 +HGRActionIndexPtr + !word $4000 +HGRActionIndexRecord + !word $FDFD ; SMC + + jsr okvs_find + !word HGRActionIndexPtr +IndexedHGRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load compressed HGR screenshot at $3FF8 + !word $3FF8 +@indexRecordPtr + !word $FDFD ; SMC + rts diff --git a/src/ui.attract.mode.a b/src/ui.attract.mode.a index 923bb0b..0508d56 100644 --- a/src/ui.attract.mode.a +++ b/src/ui.attract.mode.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-9 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Attract Mode - cycle through slideshows and self-running demos ; @@ -8,6 +8,16 @@ ; - MiniAttractMode ; - RunAttractModule +kAttractModeFilters + !byte ATTRACT_DEMO + !byte ATTRACT_HGR_TITLE + !byte ATTRACT_HGR_ACTION + !byte ATTRACT_DHGR_TITLE + !byte ATTRACT_DHGR_ACTION + !byte ATTRACT_SHR + !byte ATTRACT_GR + !byte ATTRACT_DGR + ;------------------------------------------------------------------------------ ; MegaAttractMode ; main entry point for Mega Attract Mode, which endlessly cycles through @@ -24,21 +34,17 @@ MegaAttractMode jsr BlankHGR ; switch to HGR page 1 (once cleared) - jsr LoadFile ; load attract-mode configuration file into $8000 - !word kRootDirectory - !word kAttractModeConfFile -- !word $8000 - jsr ParseKeyValueList ; parse attract-mode configuration into OKVS data structure at $6000 - !word gAttractModeStore - !word - - !byte 0 + jsr LoadIndexedFile ; load pre-parsed attract mode configuration data into $6000 +- !word $6000 + !word kAttractModeIndexRecord +@next jsr pref_get ; get attract mode module from prefs !word kNextAttract - !word gAttractModeStore + !word - +ST16 @mname ; A/Y = module name ; $WINDEX = index of module in attract store - +LDADDR gAttractModeStore + +LDADDR - jsr okvs_next ; get module after this one +ST16 + @@ -46,79 +52,127 @@ MegaAttractMode !word kNextAttract + !word $FDFD ; SMC - jsr okvs_get - !word gAttractModeStore + jsr okvs_get ; sets PTR + !word - @mname !word $FDFD ; SMC - +ST16 PTR ldy #1 lda (PTR),y - tax ; X = module type + tax ; X = module type as ASCII digit + + and #$0F ; do we want to display this module type + tay + lda gMegaAttractModeFilter + and kAttractModeFilters, y + beq @next + +LD16 @mname ; A/Y = address of module name jsr RunAttractModule lda KBD bpl MegaAttractMode cmp #$8D ; Enter plays the game shown on screen. bne + ; Any other key switches to Search Mode. - jsr PlayGame ; (might return if user hits Ctrl-Reset) + +LD16 gLastMegaAttractGame + jsr PlayGameInAY ; (might return if user hits Ctrl-Reset) + jmp SearchMode ;------------------------------------------------------------------------------ ; MiniAttractMode ; run attract modules related to one game ; -; in: gGameToLaunch = index in gGamesListStore (word) +; in: gGameToLaunch = index in gSearchStore (word) +; gSearchStore populated ; out: all flags and registers clobbered -; assume all of main memory has been clobbered +; assume all of main memory has been clobbered (including gSearchStore) ;------------------------------------------------------------------------------ MiniAttractMode jsr GetGameToLaunch - +ST16 + + +ST16 @GameToLaunch + +; We want to load the mini attract index into $800 so we can get the +; index record for this game, but we now have so many games that the +; entire index is larger than $1800 bytes and loading it all at once +; would visibly overwrite bytes in HGR page 1. So the index is now +; split into 2 halves based on the first letter of the game's +; directory name, and we figure out which half we want and load it. + + +ST16 PTR + ldy #1 + lda (PTR), y + sec + sbc #$41 ; A in [0..25] + lsr ; A in [0..15] + lsr ; A in [0..7] + lsr ; A in [0..3] + lsr ; A in [0..1] + tax + lda kMiniAttractIndexLo, x + sta @MiniAttractIndexRecord + lda kMiniAttractIndexHi, x + sta @MiniAttractIndexRecord+1 + + jsr LoadIndexedFile +- !word $0800 +@MiniAttractIndexRecord + !word $FDFD ; SMC + +; Find the index record for this game and copy it into LC RAM so we +; can reuse it without reloading the mini attract index over and over +; during attract mode. + + jsr okvs_find + !word - +@GameToLaunch + !word $FDFD ; SMC + jsr okvs_next_field + jsr SwitchToBank2 + sty OKVS_CACHE + ldy #4 ; length of index record (-1) +- lda (PTR), y + sta OKVS_CACHE + 1, y + dey + bpl - + +; Now, finally, start the mini attract mode jsr BlankHGR ; X = 0 - stx MiniAttractIndex - stx MiniAttractIndex+1 + stx @MiniAttractIndex+1 + stx @MiniAttractIndex+3 @loop - jsr LoadFile ; load mini attract mode configuration file into $8000 - !word kMiniAttractDirectory -+ !word $FDFD ; SMC -- !word $8000 + jsr LoadIndexedFile +- !word $6000 + !word OKVS_CACHE - jsr ParseKeyValueList ; parse configuration into OKVS data structure at $6000 - !word gAttractModeStore - !word - - !byte 0 - - +LDADDR gAttractModeStore + +LDADDR - jsr okvs_len lda WCOUNT - cmp MiniAttractIndex + cmp @MiniAttractIndex+1 bne + lda WCOUNT+1 - cmp MiniAttractIndex+1 + cmp @MiniAttractIndex+3 beq ATTRTS ; we've run through all modules, so exit to caller + - +LD16 MiniAttractIndex +@MiniAttractIndex + +LDADDR 0 ; SMC +ST16 WINDEX - +LDADDR gAttractModeStore + +LDADDR - jsr okvs_nth ; get the next module on the list +ST16 SAVE - jsr okvs_get_current ; get module type - ldy #1 + jsr okvs_next_field ; get module type + ; Y = 0 + iny lda (PTR),y tax ; X = module type +LD16 SAVE ; A/Y = address of module name jsr RunAttractModule ; execute the module - inc MiniAttractIndex + inc @MiniAttractIndex+1 bne + - inc MiniAttractIndex+1 + inc @MiniAttractIndex+3 + lda KBD bpl @loop ATTRTS rts -MiniAttractIndex - !word 0 ; SMC ;------------------------------------------------------------------------------ ; RunAttractModule @@ -141,33 +195,31 @@ RunAttractModule bne @NotDemo ; Self-running demos are loaded into main memory and executed. -; Each binary has been patched to quit on any key and jump back -; to the |Reenter| entry point. +; Each demo has been patched to check joystick and memory requirements, +; so a demo won't run if the actual game wouldn't be playable. +; Demos are also patched to jump back to the |Reenter| entry point +; on any key, or at the natural end of the demo cycle. ; All demos are strictly 48K / main memory. No demo uses the ; language card or auxiliary memory. - +LD16 @key - jsr FindGame - bcs ATTRTS ; if game doesn't exist, skip the demo - +LD16 WINDEX - +CMP16 $FFFF - beq + - +ST16 gGameToLaunch ; if this demo corresponds to a game, save its index - ; in case user presses RETURN during the demo (we will launch the game) -+ + +ST16 PTR + ldy #0 + lda (PTR), y + tay +- lda (PTR), y + sta DemoFilename, y + dey + bpl - + +LDADDR DemoFilename + +ST16 gLastMegaAttractGame ; save game filename in LC in case user hits Return to launch + jsr ClearScreens ; avoid seeing code load into the HGR page ; (clobbers $106, must do now before loading prelaunch code) - - jsr LoadFile ; load standard prelaunch code (|Launch| will call it) - !word kPrelaunchDirectory - !word kStandardPrelaunch - !word $0106 - + jsr LoadStandardPrelaunch ; load standard prelaunch code (|Launch| will call it) jsr LoadFile ; load self-running demo into its default address (varies) !word kDemoDirectory @key !word $FDFD !word 0 - jmp Launch ; will return to caller via |Reenter| ; not a demo, so maybe a slideshow or single screenshot @@ -176,17 +228,22 @@ RunAttractModule cmp #$41 ; numbers are slideshow modules, bcs @dispatchSingle ; letters are single files -; it's a slideshow, so load and parse slideshow configuration file +; it's a slideshow, so load slideshow configuration file pha ; save module type - jsr LoadFile ; load slideshow configuration file into $4000 - !word kAttractModeSlideshowDirectory -@key2 !word $FDFD ; SMC + jsr LoadIndexedFile ; load slideshow configuration file into $4000 - !word $4000 - jsr ParseKeyValueList ; parse into an OKVS data structure at $0800 - !word gSlideshowStore + !word kAttractModeSlideshowIndexRecord + jsr okvs_find !word - - !byte 0 +@key2 !word $FDFD ; SMC + +ST16 + + jsr LoadIndexedFile + !word $800 ++ !word $FDFD ; SMC pla ; restore module type + +HIDE_NEXT_2_BYTES +@dispatchSingle + adc #(@singleslo-@slideshowslo)-1 - and #$0F ; convert ASCII digit to int tax @@ -197,10 +254,6 @@ RunAttractModule +LD16 @key ; pass in module name @jmp jmp $FDFD ; SMC -@dispatchSingle - adc #(@singleslo-@slideshowslo)-1 - bne - ; always branches - @slideshowslo !byte HGRTitleSlideshow !byte >HGRActionSlideshow @@ -220,8 +275,13 @@ RunAttractModule !byte >DHGRActionSlideshow !byte >SHRSlideshow !byte >GRActionSlideshow + !byte >DGRActionSlideshow @singleshi !byte >HGRSingle !byte >DHGRSingle !byte >SHRSingle !byte >GRSingle + !byte >DGRSingle + +DemoFilename + !byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 diff --git a/src/ui.attract.shr.a b/src/ui.attract.shr.a index 4c74d85..94b3911 100644 --- a/src/ui.attract.shr.a +++ b/src/ui.attract.shr.a @@ -1,13 +1,34 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Super hi-res slideshows ; ; Public functions +; - AllSHRSlideshow ; - SHRSlideshow ; - SHRSingle ; +;------------------------------------------------------------------------------ +; AllSHRSlideshow +; execute mega-attract mode of all super hi-res artwork (and nothing else) +; +; safe to call if machine can not display super hi-res graphics (clears carry +; and exits) +; +; in: none +; out: C=0 if machine can not display SHR +; otherwise all registers and flags clobbered +;------------------------------------------------------------------------------ +AllSHRSlideshow + clc + lda MachineStatus ; only show SHR on IIgs or if we have a VidHD card + and #SUPPORTS_SHR + beq SHRRTS + lda #ATTRACT_SHR + sta gMegaAttractModeFilter + jmp MegaAttractMode + ;------------------------------------------------------------------------------ ; SHRSlideshow ; execute a slideshow of super hi-res artwork @@ -22,16 +43,15 @@ SHRSlideshow lda MachineStatus ; only show SHR on IIgs or if we have a VidHD card and #SUPPORTS_SHR - bne + -SHRRTS rts -+ jsr LoadSHRTransition + beq SHRRTS + jsr LoadSHRTransition jsr okvs_iter !word gSlideshowStore !word SHRArtworkCallback - jmp BlankHGR + beq jmpblank ; always taken ;------------------------------------------------------------------------------ -; SHRSlideshow +; SHRSingle ; display a single super hi-res artwork ; ; safe to call if machine can not display super hi-res graphics (does nothing @@ -42,34 +62,52 @@ SHRRTS rts ; graphics mode reset to display hi-res screen, which is blank ;------------------------------------------------------------------------------ SHRSingle - +ST16 + + jsr SetPath + +LDADDR gPathname + +ST16 IndexedSHRFilename lda MachineStatus ; only show SHR on IIgs or if we have a VidHD card and #SUPPORTS_SHR beq SHRRTS jsr BlankSHR - jsr LoadFile - !word kRootDirectory -+ !word $FDFD ; SMC - !word $1FF8 + jsr LoadIndexedSHRFile jsr DecompressSHR jsr LoadSHRTransition jsr ExecuteTransitionAtA000AndWait +jmpblank jmp BlankHGR ;------------------------------------------------------------------------------ -; LoadSHGRTransition [private] -; load the SHR transition effect code (currently always the same file) +; LoadSHRTransition [private] +; looks up name of next SHR transition effect in SFX.CONF and loads that file +; at $A000 ; ; in: none ; out: all registers and flags clobbered ; $A000..$BFFF/main contains transition effect code ;------------------------------------------------------------------------------ LoadSHRTransition - jsr LoadFile - !word kFXDirectory - !word kSFXFizzleFile - !word $A000 - rts + jsr LoadIndexedFile ; load SHR transition effects list into $A000 +- !word $A000 + !word kSFXIndexRecord + + jsr pref_get ; get SHR transition effect from prefs + !word kNextSFX + !word - + +ST16 @indexRecordPtr ; A/Y = filename (don't load file yet) + ; $WINDEX = index of the transition in SFX store + +LDADDR - + jsr okvs_next ; get transition after this one + +ST16 + + + jsr pref_set ; update prefs store and save to disk + !word kNextSFX ++ !word $FDFD ; SMC + + jsr LoadIndexedFile + !word $A000 ; load actual transition effect code into $A000 +@indexRecordPtr + !word $FDFD ; SMC +SHRRTS rts ;------------------------------------------------------------------------------ ; SHRArtworkCallback [private] @@ -87,7 +125,8 @@ SHRArtworkCallback bit KBD bmi SHRRTS - +ST16 @sfname + +ST16 IndexedSHRFilename + +ST16 gLastMegaAttractGame jsr FindGame ; if game is not found (C will be set here), it means it can't be played on @@ -95,19 +134,30 @@ SHRArtworkCallback ; it in slideshows bcs SHRRTS - +LD16 WINDEX ; save game index in case user hits RETURN - +ST16 gGameToLaunch ; while it's visible (we'll launch it) - jsr BlankSHR - - ; load compressed SHR artwork at $1FF0/main (not aux) - jsr LoadFile - !word kSHRArtworkDirectory -@sfname !word $FDFD - !word $1FF8 + jsr LoadIndexedSHRFile jsr DecompressSHR jmp ExecuteTransitionAtA000AndWait +LoadIndexedSHRFile +; in: caller has populated IndexedSHRFilename +; out: all flags & registers clobbered + jsr LoadIndexedFile ; load index file into $2000 +- !word $2000 + !word kSHRArtworkIndexRecord + + jsr okvs_find + !word - +IndexedSHRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load compressed SHR artwork at $1FF8/main (not aux) + !word $1FF8 +@indexRecordPtr + !word $FDFD ; SMC + rts + ;------------------------------------------------------------------------------ ; BlankSHR [private] ; clear and show SHR mode without flickering @@ -117,7 +167,7 @@ SHRArtworkCallback ; NOTE: THIS ROUTINE WILL CRASH ON AN APPLE //C due to writing to $C029, ; so it is imperative that the caller ensures the machine type. ; Thanks to John Brooks for explaining all of this to me. Twice. -; out: text page clobbered (but screen holes preserved) +; out: text page clobbered ; $2000..$9FFF/aux cleared ;------------------------------------------------------------------------------ BlankSHR diff --git a/src/ui.browse.mode.a b/src/ui.browse.mode.a index 5ce427d..3568efe 100644 --- a/src/ui.browse.mode.a +++ b/src/ui.browse.mode.a @@ -36,6 +36,7 @@ kBrowseCheat = 8 kSoftBell = 9 ; must match kInputError kBrowseJoystick = 10 kBrowseQuit = 11 +kBrowseSHR = 12 ldy #kNumBrowseKeys - dey @@ -47,8 +48,10 @@ kBrowseQuit = 11 @noKeyMatch jsr IsSearchKey +!if kBrowseSearch > 0 { bne @BrowseDispatch ldx #kBrowseSearch +} ; execution falls through here @BrowseDispatch @@ -59,6 +62,9 @@ kBrowseQuit = 11 @j jsr $FDFD ; SMC jmp @BrowseModeInputLoop +;------------------------------------------------------------------------------ +; internal functions + OnBrowseSearch sta InputBuffer lda #$01 @@ -66,9 +72,13 @@ OnBrowseSearch jmp SearchMode OnBrowsePrevious - +LDX16 gGameToLaunch - +CPX16_0 - bne @notFirstGame + jsr AnyGameSelected + ; A/Y = gGameToLaunch + bcs @goToLastGame ; if no game selected, select last game + tax ; X/Y = gGameToLaunch + tya ; set up first comparison in CPX16 macro + +CPX16_0_NE @notFirstGame ; if first game selected, select last game +@goToLastGame +LDX16 GameCount @notFirstGame +DEX16 @@ -77,14 +87,15 @@ OnBrowsePrevious OnBrowseNext +LDX16 gGameToLaunch +INX16 - +CPX16ADDR GameCount - bne notLastGame + +CPX16ADDR_NE GameCount, notLastGame ldx #0 ldy #0 notLastGame +STX16 gGameToLaunch jmp OnBrowseChanged +ReloadIndexAndLaunch + jsr ReloadSearchIndex OnBrowseLaunch jsr PlayGame jsr BlankHGR @@ -97,13 +108,15 @@ OnBrowseCheat OnBrowseTab jsr MiniAttractMode cmp #$8D - beq OnBrowseLaunch + beq ReloadIndexAndLaunch ; execution falls through here ForceBrowseChanged + jsr ReloadSearchIndex bit CLEARKBD ; execution falls through here OnBrowseChanged ; in: gGameToLaunch = game index (word) +; gSearchStore populated jsr SwitchToBank2 jsr EnableAcceleratorAndSwitchToBank1 jsr LoadGameTitleOffscreen @@ -116,8 +129,6 @@ BrowseHelpWrapper jsr Help jmp ForceBrowseChanged -;------------------------------------------------------------------------------ - BrowseDispatchTableLo !byte OnBrowseSearch !byte >OnBrowsePrevious @@ -144,39 +156,42 @@ BrowseDispatchTableHi !byte >SoftBell !byte >Joystick !byte >OnQuit + !byte >AllSHRSlideshow -kNumBrowseKeys = 14 +kNumBrowseKeys = 15 ; number of entries in next 2 tables (each) BrowseKeys + !byte $80 ; Ctrl-@ = SHR-only slideshow !byte $83 ; Ctrl-C = toggle cheat mode !byte $81 ; Ctrl-A = about !byte $AF ; '/' = help !byte $BF ; '?' = help !byte $A0 ; Space = mini attract mode !byte $89 ; TAB = mini attract mode - !byte $8D ; ENTER = launch current game - !byte $9B ; Esc = switch to search mode - !byte $8A ; down arrow = next - !byte $95 ; right arrow = next - !byte $8B ; up arrow = previous - !byte $88 ; left arrow = previous !byte $90 ; Ctrl-P = launch joystick calibration program !byte $91 ; Ctrl-Q = quit + !byte $9B ; Esc = switch to search mode + !byte $8D ; ENTER = launch current game + !byte $8B ; up arrow = previous + !byte $8A ; down arrow = next + !byte $88 ; left arrow = previous + !byte $95 ; right arrow = next BrowseKeyDispatch + !byte kBrowseSHR !byte kBrowseCheat !byte kBrowseCredits !byte kBrowseHelp !byte kBrowseHelp !byte kBrowseTab !byte kBrowseTab - !byte kBrowseLaunch - !byte kBrowseExitToSearch - !byte kBrowseNext - !byte kBrowseNext - !byte kBrowsePrevious - !byte kBrowsePrevious !byte kBrowseJoystick !byte kBrowseQuit + !byte kBrowseExitToSearch + !byte kBrowseLaunch + !byte kBrowsePrevious + !byte kBrowseNext + !byte kBrowsePrevious + !byte kBrowseNext GameCount !word 0 diff --git a/src/ui.common.a b/src/ui.common.a index 4b0a3e9..d9cae21 100755 --- a/src/ui.common.a +++ b/src/ui.common.a @@ -59,7 +59,7 @@ Home ; clear and show DHGR page 1 without flickering ; ; in: none -; out: text page clobbered (but screen holes preserved) +; out: text page clobbered ; $2000..$3FFF/main and /aux cleared ;------------------------------------------------------------------------------ BlankDHGR @@ -68,11 +68,13 @@ BlankDHGR sta WRITEAUXMEM jsr ClearHGR1 ; clear hi-res screen 1 in auxmem sta WRITEMAINMEM + lda #1 + sta OffscreenPage ; /!\ execution falls through here to DHGRMode ;------------------------------------------------------------------------------ ; DHGRMode -; switch to DHGR mode (HARDER THAN IT SOUNDS) +; switch to DHGR or DGR mode (HARDER THAN IT SOUNDS) ; ; in: none ; out: none @@ -92,9 +94,9 @@ DHGRMode sta DHIRESOFF sta DHIRESON ; then turn DHGR on - bit PAGE1 + jsr ToggleOffscreenPage + jsr ShowOtherPage lda #1 - sta OffscreenPage sta gMachineInDHGRMode jsr UnwaitForVBL jmp HGRMode diff --git a/src/ui.credits.a b/src/ui.credits.a index 5a40b56..7d84ce1 100644 --- a/src/ui.credits.a +++ b/src/ui.credits.a @@ -1,13 +1,50 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; credits page ; ; Public functions -; - Credits ; - Help +; - Credits ; +;------------------------------------------------------------------------------ +; Help +; display per-game or global help page and wait +; +; in: none +; out: see above +;------------------------------------------------------------------------------ +Help + jsr GetGameToLaunch + bcs @global + +ST16 @game + + jsr LoadIndexedFile +@okvsPtr !word gSearchCache + !word kGameHelpIndexRecord + + jsr okvs_find + !word @okvsPtr +@game !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile + !word $800 +@indexRecordPtr + !word $FDFD ; SMC + + clc + bcc .clearAndDisplayHelp ; always branches + +@global jsr LoadIndexedFile ; load help text into $800 + !word $800 + !word kHelpTextRecord + + jsr LoadHelpOffscreen ; load fancy backdrop + ldx #7 + bne .displayHelp ; always branches + ;------------------------------------------------------------------------------ ; Credits ; display credits page and wait @@ -17,17 +54,50 @@ ; all other flags and registers clobbered ;------------------------------------------------------------------------------ Credits - jsr LoadFile ; load credits text into $8000 - !word kRootDirectory - !word kCreditsFile - !word $8000 --- jsr ForceHGRMode + jsr LoadIndexedFile ; load credits text into $800 + !word $800 + !word kCreditsRecord +.clearAndDisplayHelp + jsr ForceHGRMode jsr ClearOffscreen - ldx #0 -- lda OffscreenPage + ldx #0 ; left margin (0 for credits, different for global help) +.displayHelp + lda OffscreenPage ror ; draw on offscreen page - +LDADDR $8000 - jsr DrawPage ; draw credits + +LDADDR $800 + +ST16 PTR +;DrawPage inlined here +; +; PTR contains address of array of length-prefixed strings +; length #$FF terminates +; X contains 0-indexed left margin (HTAB) +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; drawing starts at VTAB 0 +; each line starts at column X which was passed in (0-indexed) +; clobbers $FF +; clobbers A/X/Y +; preserves C, other flags clobbered + stx $FF + ldx #0 + stx VTAB + php ; save C, but Z=1 because of ldx #0 +@drawLine + lda $FF + sta HTAB + jsr DrawString_PTR_is_already_set + bmi @donePage + clc + adc PTR + sta PTR + bcc + + inc PTR+1 ++ plp ; restore C to whatever it was on entry + php + beq @drawLine ; always branches +@donePage + plp +;end inline jsr ShowOtherPage ; show credits jsr WaitForKeyFor30Seconds; wait bit CLEARKBD ; don't care about key @@ -41,28 +111,3 @@ Credits jsr ToggleCheat + sec ; if called from search mode, tell caller to refresh rts - -;------------------------------------------------------------------------------ -; Help -; display per-game or global help page and wait -; -; in: none -; out: see above -;------------------------------------------------------------------------------ -Help - jsr GetGameToLaunch - bcs @global - +ST16 @fname - jsr LoadFile - !word kGameHelpDirectory -@fname !word $FDFD ; SMC - !word $8000 - clc - bcc -- ; always branches -@global jsr LoadFile ; load help text into $8000 - !word kRootDirectory - !word kHelpTextFile - !word $8000 - jsr LoadHelpOffscreen ; load fancy backdrop - ldx #7 - bne - ; always branches diff --git a/src/ui.font.a b/src/ui.font.a index 5d28cbc..9670c0d 100644 --- a/src/ui.font.a +++ b/src/ui.font.a @@ -3,40 +3,162 @@ ; ; hi-res font drawing routines ; -; Glue functions that handle bank switching and calling the real font drawing routines -; that live in LC RAM 2 now. -; ; Public functions -; - DrawPage ; - Draw40Chars ; - DrawCenteredString ; - DrawString -; - DrawBuffer ; -DrawString - jsr SwitchToBank2 - jsr DrawStringInternal - bmi JmpSwitch ; always - -DrawPage - jsr SwitchToBank2 - jsr DrawPageInternal - -JmpSwitch - jmp SwitchToBank1 - Draw40Chars - jsr SwitchToBank2 - jsr Draw40CharsInternal - beq JmpSwitch ; always +; A/Y contains address of character buffer +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; drawing starts at HTAB 0 +; increments VTAB on exit +; sets HTAB to 0 on exit +; Z=1 on exit +; clobbers A/X/Y + jsr + + ldx #40 + jsr .DrawBufferInternal ++ ldx #0 + stx HTAB + rts DrawCenteredString - jsr SwitchToBank2 - jsr DrawCenteredStringInternal - bmi JmpSwitch ; always +; A/Y contains address of length-prefixed string +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; clobbers A/X/Y + +ST16 PTR + php + ldy #0 + lda #40 + sec + sbc (PTR),y + lsr + sta HTAB + plp + jmp DrawString_PTR_is_already_set -DrawBuffer - jsr SwitchToBank2 - jsr DrawBufferInternal - bmi JmpSwitch ; always +DrawString +; A/Y contains address of length-prefixed string +; length can be 0 +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $24 contains starting column (0..39) (this is the standard HTAB address) +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; clobbers A/X/Y + +ST16 PTR +DrawString_PTR_is_already_set + ldy #0 + lda (PTR),y + inc PTR + bne + + inc PTR+1 ++ tax + bpl + + rts ++ + +LD16 PTR + ; /!\ execution falls through here to .DrawBufferInternal + +.DrawBufferInternal +; [private] +; A/Y contains address of character buffer +; X contains buffer length (0..40) +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; characters MUST have high bit off (0x00..0x7F) +; special characters (0x00..0x1F) will be drawn +; $24 contains starting column (0..39) (this is the standard HTAB address) +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; all characters are drawn on the same line +; HTAB is incremented for each character +; clobbers X,Y +; increments VTAB on exit +; A=buffer length on exit +; N=0,Z=0 on exit + +ST16 DBISrc+1 + php + lda VTAB + asl + asl + asl +; routine to calculate memory address within HGR page +; and self-modify addresses within draw loop that follows +; (routine clobbers A and Y but preserves X) + asl + tay + and #$F0 + bpl @calc1 + ora #$05 +@calc1 bcc @calc2 + ora #$0A +@calc2 asl + asl + sta @hgrlo+1 + tya + and #$0E + adc #$10 + asl @hgrlo+1 + rol + plp + bcc + + eor #$60 + clc ++ + sta DBIRow0+2 + adc #$04 + sta DBIRow1+2 + adc #$04 + sta DBIRow2+2 + adc #$04 + sta DBIRow3+2 + adc #$04 + sta DBIRow4+2 + adc #$04 + sta DBIRow5+2 + adc #$04 + sta DBIRow6+2 + adc #$04 + sta DBIRow7+2 +@hgrlo lda #$FD + adc HTAB + sta DBIRow0+1 + sta DBIRow1+1 + sta DBIRow2+1 + sta DBIRow3+1 + sta DBIRow4+1 + sta DBIRow5+1 + sta DBIRow6+1 + sta DBIRow7+1 + txa + pha + bpl + ; always branches because X is 0..40 +DBILoop +DBISrc ldy $FDFD,x + lda FontDataRow0,y +DBIRow0 sta $FDFD,x + lda FontDataRow1,y +DBIRow1 sta $FDFD,x + lda FontDataRow2,y +DBIRow2 sta $FDFD,x + lda FontDataRow3,y +DBIRow3 sta $FDFD,x + lda FontDataRow4,y +DBIRow4 sta $FDFD,x + lda FontDataRow5,y +DBIRow5 sta $FDFD,x + lda FontDataRow6,y +DBIRow6 sta $FDFD,x + lda FontDataRow7,y +DBIRow7 sta $FDFD,x + inc HTAB ++ dex + bpl DBILoop + pla ; A = buffer length (passed in in X) + inc VTAB + rts diff --git a/src/ui.font.data.lc2.a b/src/ui.font.data.a similarity index 100% rename from src/ui.font.data.lc2.a rename to src/ui.font.data.a diff --git a/src/ui.font.lc2.a b/src/ui.font.lc2.a deleted file mode 100644 index 0958ce0..0000000 --- a/src/ui.font.lc2.a +++ /dev/null @@ -1,221 +0,0 @@ -;license:MIT -;(c) 2018-2020 by 4am -; -; hi-res font drawing routines -; -; /!\ These live in LC RAM 2 and rely on the font data which is also in LC RAM 2. /!\ -; Code in LC RAM 1 (which is most program code) should call the functions in ui.font -; which handle bank switching for you. -; - -DrawPageInternal -; A/Y contains address of character buffer -; X contains 0-indexed left margin (HTAB) -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; drawing starts at VTAB 0 -; each line starts at column X which was passed in (0-indexed) -; clobbers PTR -; clobbers $FF -; clobbers A/X/Y -; preserves all flags, by a quirk of implementation - php - stx $FF - ldx #0 - stx VTAB - +ST16 PTR -@drawLine - lda $FF - sta HTAB - ldy #0 -@parseLine - lda (PTR),y - cmp #$5B ; '[' at beginning on line - bne + ; ends the parsing - tya - beq @donePage -+ cmp #$0A - beq @doneParsingLine - ldx #5 -- cmp @subs_a,x - bne @nosub - lda @subs_b,x - sta (PTR),y -@nosub - dex - bpl - - iny - bne @parseLine -@doneParsingLine - sty SAVE - tya - beq @skip - ldx SAVE - +LD16 PTR - plp - php - jsr DrawBufferInternal -@skip inc SAVE ; skip carriage return - lda SAVE ; advance PTR to start of next line - clc - adc PTR - sta PTR - bcc + - inc PTR+1 -+ inc VTAB ; this will print 255 lines if you give it - bne @drawLine ; 255 lines, so don't do that -@donePage - plp - rts -@subs_a - !byte $2A,$7E,$3C,$3E,$24,$25 -@subs_b - !byte $10,$11,$08,$15,$0E,$0F - -Draw40CharsInternal -; A/Y contains address of character buffer -; carry bit clear -> draw on page 1 -;v carry bit set -> draw on page 2 -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; drawing starts at HTAB 0 -; increments VTAB -; sets HTAB to 0 on exit -; clobbers A/X/Y - jsr + - ldx #40 - jsr DrawBufferInternal - inc VTAB -+ ldx #0 - stx HTAB - rts - -DrawCenteredStringInternal -; A/Y contains address of length-prefixed string -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; clobbers A/X/Y -; clobbers PTR/PTR+1 - +ST16 PTR - - ldy #0 - php - lda #40 - sec - sbc (PTR),y - lsr - sta HTAB - plp - beq + - -DrawStringInternal -; A/Y contains address of length-prefixed string -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; $24 contains starting column (0..39) (this is the standard HTAB address) -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; clobbers A/X/Y -; clobbers PTR/PTR+1 - +ST16 PTR - - ldy #0 -+ lda (PTR),y - tax - inc PTR - bne + - inc PTR+1 -+ - +LD16 PTR - ; /!\ execution falls through here to DrawBufferInternal - -DrawBufferInternal -; A/Y contains address of character buffer -; X contains buffer length (1..40) -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; characters MUST have high bit off (0x00..0x7F) -; special characters (0x00..0x1F) will be drawn -; $24 contains starting column (0..39) (this is the standard HTAB address) -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; all characters are drawn on the same line -; HTAB is incremented for each character -; VTAB is NOT incremented -; clobbers A/X/Y - +ST16 DBISrc+1 - php - dex - lda VTAB - asl - asl - asl -; routine to calculate memory address within HGR page -; and self-modify addresses within draw loop that follows -; (routine clobbers A and Y but preserves X) - asl - tay - and #$F0 - bpl @calc1 - ora #$05 -@calc1 bcc @calc2 - ora #$0A -@calc2 asl - asl - sta @hgrlo+1 - tya - and #$0E - adc #$10 - asl @hgrlo+1 - rol - plp - bcc + - eor #$60 - clc -+ - sta DBIRow0+2 - adc #$04 - sta DBIRow1+2 - adc #$04 - sta DBIRow2+2 - adc #$04 - sta DBIRow3+2 - adc #$04 - sta DBIRow4+2 - adc #$04 - sta DBIRow5+2 - adc #$04 - sta DBIRow6+2 - adc #$04 - sta DBIRow7+2 -@hgrlo lda #$FD - clc - adc HTAB - sta DBIRow0+1 - sta DBIRow1+1 - sta DBIRow2+1 - sta DBIRow3+1 - sta DBIRow4+1 - sta DBIRow5+1 - sta DBIRow6+1 - sta DBIRow7+1 -DBILoop -DBISrc ldy $FDFD,x - lda FontDataRow0,y -DBIRow0 sta $FDFD,x - lda FontDataRow1,y -DBIRow1 sta $FDFD,x - lda FontDataRow2,y -DBIRow2 sta $FDFD,x - lda FontDataRow3,y -DBIRow3 sta $FDFD,x - lda FontDataRow4,y -DBIRow4 sta $FDFD,x - lda FontDataRow5,y -DBIRow5 sta $FDFD,x - lda FontDataRow6,y -DBIRow6 sta $FDFD,x - lda FontDataRow7,y -DBIRow7 sta $FDFD,x - inc HTAB - dex - bpl DBILoop - rts diff --git a/src/ui.offscreen.a b/src/ui.offscreen.a index b117260..1884fa9 100644 --- a/src/ui.offscreen.a +++ b/src/ui.offscreen.a @@ -8,8 +8,10 @@ ; - LoadCoverOffscreen ; - LoadHelpOffscreen ; - LoadGameTitleOffscreen +; - UnpackHGRTitle ; - ResyncPage ; - ShowOtherPage +; - ShowOtherDHGRPage ; - ToggleOffscreenPage ; - ClearScreens ; - ClearOffscreen @@ -48,7 +50,7 @@ OffscreenPage = * + 1 ; out: all flags and registers clobbered ;------------------------------------------------------------------------------ LoadTitleOffscreen - lda #kCoverFile ; all of these are on the same page - !byte $00 -+ !byte $FD ; SMC - rts - -LoadGameTitleOffscreen -; in: gGameToLaunch = index into gGamesListStore (word) - jsr GetGameToLaunch - +ST16 @fname - bit MachineStatus ; if < 128K, don't bother checking for DHGR title - bvc @hgr - jsr okvs_get_current - ; (PTR) -> game display name + bitfield of game info - ; Y = 0 - lda (PTR),y ; A = game display name length + 1 - sta SAVE - tay - lda (PTR),y ; A = game info bitfield - ;;and #HAS_DHGR_TITLE - bmi @dhgr -@hgr + sta @indexlo jsr ForceHGRMode jsr GetOffscreenAddress sta @addrhi - jsr LoadFile - !word kHGRTitleDirectory -@fname !word $FDFD ; SMC + jsr LoadIndexedFile !byte $00 @addrhi !byte $FD ; SMC +@indexlo !byte $FD ; SMC + !byte >kCoverRecord ; all of these are on the same page rts -@dhgr - jsr BlankDHGR - +LD16 @fname - +ST16 + - jsr LoadDHRFile - !word kDHGRTitleDirectory -+ !word $FDFD + +LoadGameTitleOffscreen +; in: gGameToLaunch = index into gSearchStore (word) + jsr GetGameToLaunch + jsr okvs_next_field + jsr okvs_next_field_PTR_is_already_set + ; (PTR) -> length-prefixed game info bitfield + ; Y = 0 + iny ; Y = 1 + lda (PTR), y ; A = game info bitfield + bpl .LoadHGRGameTitleOffscreen ; bit 7 = 1 if game has DHGR title, 0 if HGR title + + jsr SwitchToBank2 +- iny + lda (PTR), y + sta OKVS_CACHE-1, y + cpy #6 + bne - +LoadIndexedDHRFile + jsr SwitchToBank2 + lda #0 + sta OKVS_CACHE + lda #$20 ; load first $2000 bytes into auxiliary memory + sta OKVS_CACHE + 5 + jsr GetOffscreenAddress + sta @dhgr_addr_aux + 1 + sta @dhgr_addr_main + 1 + jsr LoadAuxIndexedFile +@dhgr_addr_aux + !word $FD00 ; SMC high byte + !word OKVS_CACHE + jsr SwitchToBank2 + lda OKVS_CACHE + 2 ; offset += $2000 (note: stored in big-endian) + clc + adc #$20 + sta OKVS_CACHE + 2 + bcc + + inc OKVS_CACHE + 1 ++ jsr LoadIndexedFile ; load next $2000 bytes into main memory +@dhgr_addr_main + !word $FD00 ; SMC high byte + !word OKVS_CACHE + rts + +.LoadHGRGameTitleOffscreen + jsr ForceHGRMode + jsr GetOffscreenAddress + sta @hgr_addr + 1 + eor #$1F + sta @poke+2 + sta @peek+2 +@poke sta $3FFD ; SMC high byte to clear screen hole before load + +LD16 PTR + +ST16 @hgrIndexRecordPtr + jsr LoadIndexedFile +@hgr_addr + !word $FD00 ; SMC high byte +@hgrIndexRecordPtr + !word $FDFD ; SMC +@peek lda $3FFD ; SMC high byte + cmp #$4C ; Check if screen hole now contains a JMP + beq OFFSCREENRTS ; if so, file was not packed, so skip unpack + ; /!\ execution falls through here to UnpackHGRTitle +;------------------------------------------------------------------------------ +; UnpackHGRTitle +; unpack data from screen holes of the off screen HGR page +; +;------------------------------------------------------------------------------ +UnpackHGRTitle + jsr GetOffscreenAddress + sta src+2 + ora #$1E + sta dest+2 + lda #$00 + sta src+1 + sta dest+1 + lda #3 + sta $E0 +loop + ldx #0 +-- ldy #$78 +src +- lda $0000,y ;smc +dest + sta $0000,x ;smc + inx + iny + bpl - + tya ; y = #$80 + eor src+1 + sta src+1 + bne + + inc src+2 ++ cpx #$78 + bne -- + lda dest+1 + eor #$80 + sta dest+1 + bne + + inc dest+2 ++ dec $E0 + bpl loop +OFFSCREENRTS rts ;------------------------------------------------------------------------------ @@ -162,14 +233,15 @@ ClearMem ;------------------------------------------------------------------------------ CopyHGR ldx #$20 - ldy #$B9 ; LDY + ldy #$B9 ; LDA $0000,Y opcode + sty PageFrom sta PageTo+2 +ClearToBlack lda #$00 ClearGR ldy #0 -PageFrom lda $FD00,y ; SMC -PageTo sta $FD00,y ; SMC +PageFrom lda $FD00,y ; SMC address high byte, also SMC opcode (might be BIT) +PageTo sta $FD00,y ; SMC address high byte iny bne PageFrom inc PageFrom+2 @@ -198,6 +270,10 @@ ShowOtherPage + bit PAGE1 ; show page 1 rts +ShowOtherDHGRPage + jsr ToggleOffscreenPage + jmp DHGRMode + ;------------------------------------------------------------------------------ ; ToggleOffscreenPage ; switch the internal variable that tracks which HGR page is showing diff --git a/src/ui.overlay.a b/src/ui.overlay.a index 8ded1f8..74a3eaf 100644 --- a/src/ui.overlay.a +++ b/src/ui.overlay.a @@ -20,12 +20,14 @@ ReturnToPlay !byte $0D !text " to play" -kCheatsEnabled = 6 ; index of 'cheats enabled' string in following table +kCheatsEnabled = 8 ; index of 'cheats enabled' string in following table kCheatDescriptionLo !byte sInfiniteLives !byte >sInfiniteWeapons !byte >sInfiniteLivesAndWeapons + !byte >sInfiniteLivesAndTime + !byte >sInfiniteTime !byte >sInvincibility !byte >sInGame !byte >sCheatsEnabled @@ -42,46 +46,60 @@ sNoCheats !text "no cheat" sInfiniteLives !byte 18 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "infinite lives" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sInfiniteWeapons !byte 20 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "infinite weapons" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sInfiniteLivesAndWeapons !byte 28 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "infinite lives & weapons" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character +sInfiniteLivesAndTime + !byte 25 ; length + !byte $16 ; padlock character + !text " " + !text "infinite lives & time" + !text " " + !byte $16 ; padlock character +sInfiniteTime + !byte 17 ; length + !byte $16 ; padlock character + !text " " + !text "infinite time" + !text " " + !byte $16 ; padlock character sInvincibility !byte 14 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "invincible" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sInGame !byte 18 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "in-game cheats" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sCheatsEnabled !byte 18 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "cheats enabled" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sCheatDescriptionPrefix !byte 2 ; length !byte $03 ; vertical line character @@ -124,16 +142,18 @@ DrawUI jsr GetGameToLaunch ; get current game, if any bcs @doneWithLine2 ; if no game, nothing more to do on UI line 2 - jsr GetGameDisplayName - ; A/Y -> game display name + bitfield of game info - +ST16 PTR - ldy #0 - lda (PTR),y ; A = game display name length + 1 - sta SAVE + ; A/Y -> key of current game (in gSearchStore) + jsr okvs_next_field ; (PTR) -> display name of current game + ; Y = 0 + lda (PTR), y tay - lda (PTR),y ; A = game info bitfield + iny + sty SAVE + iny + lda (PTR), y ; A = game info bitfield sta gGameToLaunchInfo ldy #0 + - iny @printCursor lda #$FD ; SMC @@ -194,7 +214,7 @@ DrawUI ldy #0 @dotloop iny - lda (PTR),y ; (PTR) still points to game display name + game info bitfield + lda (PTR),y ; (PTR) still points to game display name ora #$20 ; force lower-case always cmp InputBuffer,x bne + @@ -253,17 +273,25 @@ gDrawingOnscreen=*+1 jsr AddToPath +LDADDR sCheatDescriptionSuffix jsr AddToPath - inc VTAB plp +LDADDR gPathname jsr DrawCenteredString ; draw cheat UI line 2 jsr MaybeRedrawUIForDHGR ; transform for DHGR if this is a DHGR title screen @uidone lda #0 sta gDrawingOnscreen - clc - jmp ShowOtherPage + bit MachineStatus + bvc + + bit gGameToLaunchInfo + bpl + + jmp ShowOtherDHGRPage ++ jmp ShowOtherPage + +;------------------------------------------------------------------------------ +; internal functions CheckCheats +; out: (SAVE) -> length-prefixed string, either a game-specific description +; or the global 'cheats enabled' message ldx #kCheatsEnabled jsr AnyGameSelected bcs + @@ -276,11 +304,19 @@ gGameToLaunchInfo=*+1 sta SAVE lda kCheatDescriptionHi,x sta SAVE+1 -- rts +OVERLAYRTS + rts MaybeRedrawUIForDHGR +; If this is a DHGR title screen, then redraw the already-drawn overlay +; for double hi-res. This allows us to use a single font and drawing +; routines for both HGR and DHGR. There is a small amount of flicker +; if we're redrawing directly on the visible screen without swapping +; pages (e.g. adding a dot without changing the selected game), but +; gDrawingOnscreen tracks this and we reduce the redrawing to an +; absolute minimum to reduce flicker. bit MachineStatus - bvc - + bvc OVERLAYRTS bit gGameToLaunchInfo - bpl - + bpl OVERLAYRTS jmp RedrawForDHGR diff --git a/src/ui.search.mode.a b/src/ui.search.mode.a index cf69fde..c6f5c17 100644 --- a/src/ui.search.mode.a +++ b/src/ui.search.mode.a @@ -21,6 +21,7 @@ kInputCheat = 8 kInputError = 9 kInputJoystick = 10 kInputQuit = 11 +kInputSHR = 12 InputDispatchTableLo !byte OnSearch !byte >OnClear @@ -48,8 +50,9 @@ InputDispatchTableHi !byte >OnError !byte >Joystick !byte >OnQuit + !byte >AllSHRSlideshow -kNumInputKeys = 12 +kNumInputKeys = 13 ; number of entries in next 2 tables (each) InputKeys !byte $83 ; Ctrl-C = toggle cheat mode @@ -66,6 +69,7 @@ InputKeys ; or switch to mega attract mode !byte $90 ; Ctrl-P = launch joystick calibration program !byte $91 ; Ctrl-Q = quit + !byte $80 ; Ctrl-@ = SHR-only slideshow InputKeyDispatch !byte kInputCheat !byte kInputCredits @@ -79,6 +83,7 @@ InputKeyDispatch !byte kInputClear !byte kInputJoystick !byte kInputQuit + !byte kInputSHR .noKeyMatch jsr IsSearchKey @@ -112,7 +117,8 @@ SearchMode txs stx gGameToLaunch ; $FFFF = no game selected stx gGameToLaunch+1 - jsr BuildSearchStore + stx gMegaAttractModeFilter ; $FF = all module types + jsr ReloadSearchIndex jsr Home ; clear screen (switches to text mode) stx OffscreenPage ; don't show text page 2 by accident jsr OnInputChanged ; draw UI offscreen @@ -162,7 +168,8 @@ OnTab jsr MiniAttractMode cmp #$8D ; if we exited mini attract mode bne .req_redraw ; by pressing Enter, launch the game - + jsr ReloadSearchIndex ; must reload search index before calling PlayGame + ; /!\ execution falls through here OnLaunch ldx gGameToLaunch+1 inx @@ -170,7 +177,7 @@ OnLaunch jsr PlayGame .req_redraw - sec ; tell caller to redraw UI + sec ; tell caller to reload search index and redraw UI from scratch rts OnCheat @@ -199,8 +206,10 @@ FindMatchingTitle jsr SwitchToBank2 jsr EnableAcceleratorAndSwitchToBank1 - jsr ResetTextRank + jsr FindTitleInCache + bcc + ; sets BestMatchIndex on success + jsr ResetTextRank jsr okvs_iter_values ; iterate through all game display names !word gSearchStore ; and rank them for the best match !word TextRankCallback ; to the current input buffer diff --git a/src/ui.wait.a b/src/ui.wait.a index 4a78aad..2d00328 100644 --- a/src/ui.wait.a +++ b/src/ui.wait.a @@ -4,7 +4,6 @@ ; UI functions for doing things then waiting, or waiting then doing things ; ; - ExecuteTransitionAt6000AndWait -; - ExecuteTransitionAt6400AndWait ; - ExecuteTransitionAtA000AndWait ; - ExecuteTransitionAndWait ; - WaitForKeyFor30Seconds @@ -13,9 +12,6 @@ ExecuteTransitionAt6000AndWait ldy #$60 +HIDE_NEXT_2_BYTES -ExecuteTransitionAt6400AndWait - ldy #$64 - +HIDE_NEXT_2_BYTES ExecuteTransitionAtA000AndWait ldy #$A0 ; /!\ execution falls through here to ExecuteTransitionAndWait @@ -31,6 +27,8 @@ ExecuteTransitionAndWait lda #0 +ST16 @j+1 @j jsr $FDFD ; SMC call transition effect code + sta WRITEMAINMEM ; several transition effects exit with + ; auxmem writeable so we reset it here ldx #$20 ; picture is showing so now we wait - lda #0 jsr WaitForKeyWithTimeout @@ -85,10 +83,9 @@ CoverFade jsr ShowOtherPage lda OffscreenPage beq CoverFade - jsr LoadFile ; load transition effect code at $6000 - !word kFXDirectory - !word kCoverFadeFile + jsr LoadIndexedFile ; load transition effect code at $6000 !word $6000 + !word kCoverFadeRecord jsr $6000 ; call transition effect jmp MegaAttractMode ; exit via mega attract mode !if (RELBASE != $2000) and (>WaitForKeyFor30Seconds != >*) {