More performance work
This commit is contained in:
parent
9b95c79c20
commit
41f33b0dfe
37 changed files with 319 additions and 24 deletions
Binary file not shown.
BIN
generated/amiga/tiles/tilebank0.tbk
Normal file
BIN
generated/amiga/tiles/tilebank0.tbk
Normal file
Binary file not shown.
Binary file not shown.
BIN
generated/atarist/tiles/tilebank0.tbk
Normal file
BIN
generated/atarist/tiles/tilebank0.tbk
Normal file
Binary file not shown.
BIN
generated/iigs/font.tbk
Normal file
BIN
generated/iigs/font.tbk
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level01.dat
Normal file
BIN
generated/iigs/levels/level01.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level02.dat
Normal file
BIN
generated/iigs/levels/level02.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level03.dat
Normal file
BIN
generated/iigs/levels/level03.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level04.dat
Normal file
BIN
generated/iigs/levels/level04.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level05.dat
Normal file
BIN
generated/iigs/levels/level05.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level06.dat
Normal file
BIN
generated/iigs/levels/level06.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level07.dat
Normal file
BIN
generated/iigs/levels/level07.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level08.dat
Normal file
BIN
generated/iigs/levels/level08.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level09.dat
Normal file
BIN
generated/iigs/levels/level09.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level10.dat
Normal file
BIN
generated/iigs/levels/level10.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level11.dat
Normal file
BIN
generated/iigs/levels/level11.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level12.dat
Normal file
BIN
generated/iigs/levels/level12.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level13.dat
Normal file
BIN
generated/iigs/levels/level13.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level14.dat
Normal file
BIN
generated/iigs/levels/level14.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level15.dat
Normal file
BIN
generated/iigs/levels/level15.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level16.dat
Normal file
BIN
generated/iigs/levels/level16.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level17.dat
Normal file
BIN
generated/iigs/levels/level17.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level18.dat
Normal file
BIN
generated/iigs/levels/level18.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level19.dat
Normal file
BIN
generated/iigs/levels/level19.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level20.dat
Normal file
BIN
generated/iigs/levels/level20.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level21.dat
Normal file
BIN
generated/iigs/levels/level21.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level22.dat
Normal file
BIN
generated/iigs/levels/level22.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level23.dat
Normal file
BIN
generated/iigs/levels/level23.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/level24.dat
Normal file
BIN
generated/iigs/levels/level24.dat
Normal file
Binary file not shown.
BIN
generated/iigs/levels/title.dat
Normal file
BIN
generated/iigs/levels/title.dat
Normal file
Binary file not shown.
BIN
generated/iigs/sprites/sprites.spr
Normal file
BIN
generated/iigs/sprites/sprites.spr
Normal file
Binary file not shown.
BIN
generated/iigs/tiles/tbank0.tbk
Normal file
BIN
generated/iigs/tiles/tbank0.tbk
Normal file
Binary file not shown.
BIN
generated/iigs/tiles/tbank1.tbk
Normal file
BIN
generated/iigs/tiles/tbank1.tbk
Normal file
Binary file not shown.
BIN
generated/iigs/tiles/tbank2.tbk
Normal file
BIN
generated/iigs/tiles/tbank2.tbk
Normal file
Binary file not shown.
160
scripts/bench-staxi-title.sh
Executable file
160
scripts/bench-staxi-title.sh
Executable file
|
|
@ -0,0 +1,160 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# bench-staxi-title.sh - Space Taxi title-screen logo cadence measurement
|
||||||
|
# (the PERF-AUDIT #3 acceptance test: the logo repaints via 103
|
||||||
|
# jlTilePasteMono calls, intended every 4th frame -- stRender.c
|
||||||
|
# titleAnimateLogo's `& 3u` divider mirroring the C64 original).
|
||||||
|
#
|
||||||
|
# Boots GS/OS under headless MAME with a WORK COPY of joey.2mg (must
|
||||||
|
# contain STAXI + its DATA tree; build with
|
||||||
|
# JOEY_DISK_EXAMPLES="STAXI" scripts/make-iigs-disk.sh),
|
||||||
|
# launches STAXI via the standard Finder keystroke timeline, then
|
||||||
|
# samples 8 known logo tile cells from the SHR framebuffer EVERY frame.
|
||||||
|
# Each frame the sampled 256 bytes fold into a rolling hash; a hash
|
||||||
|
# change means the logo visibly changed on screen (the flip-book tile
|
||||||
|
# differs on every 4-frame step, so a healthy title changes every 4
|
||||||
|
# frames; a slow repaint stretches the observed period).
|
||||||
|
#
|
||||||
|
# Emits "STAXI-CHG frame=N sum=XXXXXX" per change, heartbeats, and a
|
||||||
|
# final verify-style summary. Post-process the change frames into
|
||||||
|
# periods with the analysis snippet in the acceptance report.
|
||||||
|
#
|
||||||
|
# Usage: scripts/bench-staxi-title.sh [label]
|
||||||
|
# MAME_ROMPATH override ROM dir (default ~/.mame/roms)
|
||||||
|
# STAXI_MAX_FRAMES frame cap (default 15000)
|
||||||
|
# STAXI_MAX_CHANGES stop after this many logo changes (default 80)
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
|
: "${LLVM816_ROOT:?bench-staxi-title.sh: source toolchains/env.sh first}"
|
||||||
|
CADIUS="${CADIUS:-$LLVM816_ROOT/tools/cadius/cadius}"
|
||||||
|
|
||||||
|
sys_disk=$repo/toolchains/emulators/support/gsos-system.po
|
||||||
|
data_disk=$repo/build/iigs/bin/joey.2mg
|
||||||
|
rompath="${MAME_ROMPATH:-$HOME/.mame/roms}"
|
||||||
|
maxFrames="${STAXI_MAX_FRAMES:-15000}"
|
||||||
|
maxChanges="${STAXI_MAX_CHANGES:-80}"
|
||||||
|
label="${1:-run}"
|
||||||
|
|
||||||
|
for f in "$sys_disk" "$data_disk"; do
|
||||||
|
[ -f "$f" ] || { echo "bench-staxi-title: missing $f" >&2; exit 2; }
|
||||||
|
done
|
||||||
|
if ! "$CADIUS" CATALOG "$data_disk" 2>/dev/null | grep -qE '^ STAXI +S16'; then
|
||||||
|
echo "bench-staxi-title: STAXI not on joey.2mg (JOEY_DISK_EXAMPLES=\"STAXI\" scripts/make-iigs-disk.sh)" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
work=$(mktemp -d -t joeylib-staxi.XXXXXX)
|
||||||
|
trap 'rm -rf "$work"' EXIT
|
||||||
|
cp "$sys_disk" "$work/boot.po"
|
||||||
|
cp "$data_disk" "$work/joey.2mg"
|
||||||
|
|
||||||
|
cat > "$work/staxi.lua" <<LUA
|
||||||
|
local cpu = manager.machine.devices[":maincpu"]
|
||||||
|
local mem = cpu.spaces["program"]
|
||||||
|
local nat = manager.machine.natkeyboard
|
||||||
|
local frame = 0
|
||||||
|
local idx = 1
|
||||||
|
|
||||||
|
local function field(port, name)
|
||||||
|
local p = manager.machine.ioport.ports[port]
|
||||||
|
if p == nil then return nil end
|
||||||
|
return p.fields[name]
|
||||||
|
end
|
||||||
|
local key_cmd = field(":macadb:KEY3", "Command / Open Apple")
|
||||||
|
local function press(f) if f then f:set_value(1) end end
|
||||||
|
local function release(f) if f then f:set_value(0) end end
|
||||||
|
|
||||||
|
-- 8 logo tile cells (bx,by) chosen from title.dat's 0x84 map: byte
|
||||||
|
-- offset in SHR = 0xE12000 + (by*8 + r)*160 + bx*4, 4 bytes per row.
|
||||||
|
-- Every repaint pastes a different flip tile into these cells, so
|
||||||
|
-- their content changes on every animation step.
|
||||||
|
local cells = { {6,1},{11,1},{24,1},{29,1},{12,7},{16,8},{12,9},{15,10} }
|
||||||
|
local function logoSum()
|
||||||
|
local sum = 0
|
||||||
|
for _, c in ipairs(cells) do
|
||||||
|
local base = 0xE12000 + (c[2] * 8) * 160 + c[1] * 4
|
||||||
|
for r = 0, 7 do
|
||||||
|
local off = base + r * 160
|
||||||
|
for b = 0, 3 do
|
||||||
|
sum = (sum * 33 + mem:read_u8(off + b)) % 16777213
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return sum
|
||||||
|
end
|
||||||
|
|
||||||
|
local steps = {
|
||||||
|
{3000, function() nat:post("J") end},
|
||||||
|
{3120, function() press(key_cmd) end},
|
||||||
|
{3126, function() nat:post("o") end},
|
||||||
|
{3180, function() release(key_cmd) end},
|
||||||
|
{3540, function() nat:post("STAXI") end},
|
||||||
|
{3660, function() press(key_cmd) end},
|
||||||
|
{3666, function() nat:post("o") end},
|
||||||
|
{3720, function() release(key_cmd) end},
|
||||||
|
}
|
||||||
|
|
||||||
|
local prevSum = -1
|
||||||
|
local nChanges = 0
|
||||||
|
|
||||||
|
local function summary(tag)
|
||||||
|
local distinct = {}
|
||||||
|
local nonzero = 0
|
||||||
|
local checksum = 0
|
||||||
|
for i = 0, 31999 do
|
||||||
|
local b = mem:read_u8(0xE12000 + i)
|
||||||
|
if b ~= 0 then nonzero = nonzero + 1 end
|
||||||
|
distinct[b & 0x0F] = true
|
||||||
|
distinct[(b >> 4) & 0x0F] = true
|
||||||
|
checksum = (checksum + b) & 0xFFFFFF
|
||||||
|
end
|
||||||
|
local n = 0
|
||||||
|
for _ in pairs(distinct) do n = n + 1 end
|
||||||
|
io.write(string.format("STAXI-%s label=$label frame=%d changes=%d distinctNibbles=%d nonZeroBytes=%d checksum=%06X\n",
|
||||||
|
tag, frame, nChanges, n, nonzero, checksum))
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
emu.register_frame_done(function()
|
||||||
|
frame = frame + 1
|
||||||
|
while idx <= #steps and frame >= steps[idx][1] do
|
||||||
|
steps[idx][2]()
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
if frame >= 3800 then
|
||||||
|
local s = logoSum()
|
||||||
|
if s ~= prevSum then
|
||||||
|
io.write(string.format("STAXI-CHG frame=%d sum=%06X\n", frame, s))
|
||||||
|
io.flush()
|
||||||
|
prevSum = s
|
||||||
|
nChanges = nChanges + 1
|
||||||
|
if nChanges >= $maxChanges then
|
||||||
|
summary("DONE")
|
||||||
|
manager.machine:exit()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if frame % 1500 == 0 then
|
||||||
|
io.write(string.format("STAXI-HEART frame=%d changes=%d\n", frame, nChanges))
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
if frame >= $maxFrames then
|
||||||
|
summary("TIMEOUT")
|
||||||
|
manager.machine:exit()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
LUA
|
||||||
|
|
||||||
|
echo "bench-staxi-title[$label]: running STAXI headless under MAME (cap $maxFrames frames, $maxChanges changes)..." >&2
|
||||||
|
cd "$work"
|
||||||
|
out=$(QT_QPA_PLATFORM=offscreen SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
||||||
|
timeout "${STAXI_WALL_TIMEOUT:-900}" mame apple2gs \
|
||||||
|
-rompath "$rompath" \
|
||||||
|
-flop3 "$work/boot.po" -flop4 "$work/joey.2mg" \
|
||||||
|
-video none -sound none -nothrottle \
|
||||||
|
-autoboot_script "$work/staxi.lua" </dev/null 2>&1) || true
|
||||||
|
|
||||||
|
echo "$out" | grep -E '^STAXI-(CHG|HEART|DONE|TIMEOUT)' > "$repo/build/iigs/bin/staxi-title-$label.log" || true
|
||||||
|
tail -3 "$repo/build/iigs/bin/staxi-title-$label.log" >&2
|
||||||
|
lines=$(grep -c '^STAXI-CHG' "$repo/build/iigs/bin/staxi-title-$label.log" || true)
|
||||||
|
echo "bench-staxi-title[$label]: $lines change events -> build/iigs/bin/staxi-title-$label.log" >&2
|
||||||
143
scripts/diag-staxi-screen.sh
Executable file
143
scripts/diag-staxi-screen.sh
Executable file
|
|
@ -0,0 +1,143 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# diag-staxi-screen.sh - one-off diagnostic for the STAXI title test:
|
||||||
|
# boot + launch STAXI, dump the full SHR framebuffer + palettes as hex
|
||||||
|
# at a target frame, then extract JOEYLOG.TXT from the work disk so the
|
||||||
|
# game's own init/asset-load log is visible. Outputs land in
|
||||||
|
# build/iigs/bin/ (staxi-shr.hex, staxi-joeylog.txt).
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
|
: "${LLVM816_ROOT:?diag-staxi-screen.sh: source toolchains/env.sh first}"
|
||||||
|
CADIUS="${CADIUS:-$LLVM816_ROOT/tools/cadius/cadius}"
|
||||||
|
|
||||||
|
sys_disk=$repo/toolchains/emulators/support/gsos-system.po
|
||||||
|
data_disk=$repo/build/iigs/bin/joey.2mg
|
||||||
|
rompath="${MAME_ROMPATH:-$HOME/.mame/roms}"
|
||||||
|
dumpFrame="${STAXI_DUMP_FRAME:-9000}"
|
||||||
|
|
||||||
|
work=$(mktemp -d -t joeylib-staxidiag.XXXXXX)
|
||||||
|
trap 'rm -rf "$work"' EXIT
|
||||||
|
cp "$sys_disk" "$work/boot.po"
|
||||||
|
cp "$data_disk" "$work/joey.2mg"
|
||||||
|
|
||||||
|
cat > "$work/diag.lua" <<LUA
|
||||||
|
local cpu = manager.machine.devices[":maincpu"]
|
||||||
|
local mem = cpu.spaces["program"]
|
||||||
|
local nat = manager.machine.natkeyboard
|
||||||
|
local frame = 0
|
||||||
|
local idx = 1
|
||||||
|
|
||||||
|
local function field(port, name)
|
||||||
|
local p = manager.machine.ioport.ports[port]
|
||||||
|
if p == nil then return nil end
|
||||||
|
return p.fields[name]
|
||||||
|
end
|
||||||
|
local key_cmd = field(":macadb:KEY3", "Command / Open Apple")
|
||||||
|
local function press(f) if f then f:set_value(1) end end
|
||||||
|
local function release(f) if f then f:set_value(0) end end
|
||||||
|
|
||||||
|
local steps = {
|
||||||
|
{3000, function() nat:post("J") end},
|
||||||
|
{3120, function() press(key_cmd) end},
|
||||||
|
{3126, function() nat:post("o") end},
|
||||||
|
{3180, function() release(key_cmd) end},
|
||||||
|
{3540, function() nat:post("STAXI") end},
|
||||||
|
{3660, function() press(key_cmd) end},
|
||||||
|
{3666, function() nat:post("o") end},
|
||||||
|
{3720, function() release(key_cmd) end},
|
||||||
|
}
|
||||||
|
local pcs = {}
|
||||||
|
|
||||||
|
emu.register_frame_done(function()
|
||||||
|
frame = frame + 1
|
||||||
|
while idx <= #steps and frame >= steps[idx][1] do
|
||||||
|
steps[idx][2]()
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
-- Hang localization: sample the PC over 60 frames before the dump,
|
||||||
|
-- and probe NEWVIDEO (0xE0C029: bit7 = SHR on -> jlpInit ran).
|
||||||
|
if frame == $dumpFrame - 120 then
|
||||||
|
io.write(string.format("SHRPROBE newvideo=%02X shadow=%02X\n",
|
||||||
|
mem:read_u8(0xE0C029), mem:read_u8(0xE0C035)))
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
if frame >= $dumpFrame - 100 and frame < $dumpFrame - 40 then
|
||||||
|
local pc = cpu.state["PC"].value
|
||||||
|
local k = string.format("%06X", pc)
|
||||||
|
pcs[k] = (pcs[k] or 0) + 1
|
||||||
|
end
|
||||||
|
if frame == $dumpFrame - 40 then
|
||||||
|
for k, v in pairs(pcs) do
|
||||||
|
io.write(string.format("SHRPC %s count=%d\n", k, v))
|
||||||
|
end
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
if frame == $dumpFrame - 20 then
|
||||||
|
-- Locate the jlLog RAM ring without UBER's mailbox: bulk-read every
|
||||||
|
-- RAM bank and emit it as hex; the host greps for the build-stamp
|
||||||
|
-- text. read_range failures are reported, not swallowed.
|
||||||
|
local banks = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,0xE0,0xE1}
|
||||||
|
for _, bank in ipairs(banks) do
|
||||||
|
local base = bank * 65536
|
||||||
|
local ok, buf = pcall(function() return mem:read_range(base, base + 65535, 8) end)
|
||||||
|
if ok and buf ~= nil then
|
||||||
|
for off = 0, 65535, 256 do
|
||||||
|
local chunk = string.sub(buf, off + 1, off + 256)
|
||||||
|
local hex = {}
|
||||||
|
for i = 1, #chunk do
|
||||||
|
hex[#hex + 1] = string.format("%02X", string.byte(chunk, i))
|
||||||
|
end
|
||||||
|
io.write(string.format("SHRMEM %02X%04X %s\n", bank, off, table.concat(hex)))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
io.write(string.format("SHRMEM-FAIL bank=%02X err=%s\n", bank, tostring(buf)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
if frame == $dumpFrame then
|
||||||
|
-- SHR pixel dump: 200 rows x 160 bytes as hex lines.
|
||||||
|
for row = 0, 199 do
|
||||||
|
local parts = {}
|
||||||
|
for b = 0, 159 do
|
||||||
|
parts[#parts + 1] = string.format("%02X", mem:read_u8(0xE12000 + row * 160 + b))
|
||||||
|
end
|
||||||
|
io.write("SHRROW " .. table.concat(parts) .. "\n")
|
||||||
|
end
|
||||||
|
-- SCBs + palettes.
|
||||||
|
local scb = {}
|
||||||
|
for i = 0, 15 do scb[#scb + 1] = string.format("%02X", mem:read_u8(0xE19D00 + i)) end
|
||||||
|
io.write("SHRSCB " .. table.concat(scb, " ") .. "\n")
|
||||||
|
local pal = {}
|
||||||
|
for i = 0, 31 do pal[#pal + 1] = string.format("%02X", mem:read_u8(0xE19E00 + i)) end
|
||||||
|
io.write("SHRPAL " .. table.concat(pal, " ") .. "\n")
|
||||||
|
io.flush()
|
||||||
|
manager.machine:exit()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
LUA
|
||||||
|
|
||||||
|
echo "diag-staxi: dumping SHR at frame $dumpFrame..." >&2
|
||||||
|
cd "$work"
|
||||||
|
out=$(QT_QPA_PLATFORM=offscreen SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
||||||
|
timeout 900 mame apple2gs \
|
||||||
|
-rompath "$rompath" \
|
||||||
|
-flop3 "$work/boot.po" -flop4 "$work/joey.2mg" \
|
||||||
|
-video none -sound none -nothrottle \
|
||||||
|
-autoboot_script "$work/diag.lua" </dev/null 2>&1) || true
|
||||||
|
|
||||||
|
echo "$out" | grep -E '^SHR(PROBE|PC)|^SHRMEM-FAIL' | sed 's/^/diag-staxi: /' >&2
|
||||||
|
echo "$out" | grep -E '^SHRMEM ' > "$repo/build/iigs/bin/staxi-mem.hex" || true
|
||||||
|
echo "$out" | grep -E '^SHR(ROW|SCB|PAL)' > "$repo/build/iigs/bin/staxi-shr.hex"
|
||||||
|
wc -l "$repo/build/iigs/bin/staxi-shr.hex" >&2
|
||||||
|
|
||||||
|
# The game flushed its log to the volume root; pull it off the WORK copy.
|
||||||
|
rm -f "$repo/build/iigs/bin/staxi-joeylog.txt" "$work/JOEYLOG.TXT"* 2>/dev/null || true
|
||||||
|
"$CADIUS" EXTRACTFILE "$work/joey.2mg" "/JOEYLIB/JOEYLOG.TXT" "$work/" >/dev/null 2>&1 || true
|
||||||
|
found=$(ls "$work"/JOEYLOG.TXT* 2>/dev/null | head -1)
|
||||||
|
if [ -n "$found" ]; then
|
||||||
|
tr -d '\r' < "$found" > "$repo/build/iigs/bin/staxi-joeylog.txt"
|
||||||
|
echo "diag-staxi: extracted JOEYLOG.TXT:" >&2
|
||||||
|
else
|
||||||
|
echo "diag-staxi: no JOEYLOG.TXT on work disk (flush never ran?)" >&2
|
||||||
|
fi
|
||||||
40
stRender.c
40
stRender.c
|
|
@ -1139,42 +1139,34 @@ static void destroySprites(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The 1000-glyph font streams straight onto the font surface via
|
||||||
|
// jlTileBankLoadToSurface -- no 32KB staging buffer. The old
|
||||||
|
// malloc(32000) was lethal on IIgs (the clang libc heap is ~665
|
||||||
|
// bytes and malloc returns 1, not NULL, at exhaustion -- LLVM816-ASKS
|
||||||
|
// item 4 -- so jlTileBankLoad fread the payload through pointer 1 and
|
||||||
|
// shredded bank 0 before the first present), and a 32KB static blows
|
||||||
|
// the bank-0 BSS ceiling. The streaming loader exists for exactly
|
||||||
|
// this case; its block grid matches ST_FONT_COLS row-major layout.
|
||||||
static bool loadFontSheet(jlSurfaceT *stage) {
|
static bool loadFontSheet(jlSurfaceT *stage) {
|
||||||
jlTileT *fontTiles;
|
uint16_t count;
|
||||||
uint16_t count;
|
uint16_t palette[16];
|
||||||
uint16_t i;
|
|
||||||
uint16_t palette[16];
|
|
||||||
|
|
||||||
(void)stage;
|
(void)stage;
|
||||||
// Load font.tbk into a temp tile array, then paste each glyph
|
|
||||||
// into a regular surface that jlDrawText can sample. ~32 KB of
|
|
||||||
// temp memory for the 1000-tile font; freed before returning.
|
|
||||||
fontTiles = (jlTileT *)malloc(sizeof(jlTileT) * ST_FONT_TILES_MAX);
|
|
||||||
if (fontTiles == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
count = jlTileBankLoad(ST_FONT_PATH, fontTiles, ST_FONT_TILES_MAX,
|
|
||||||
NULL, palette);
|
|
||||||
if (count == 0u) {
|
|
||||||
free(fontTiles);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
gRender.fontSurface = jlSurfaceCreate();
|
gRender.fontSurface = jlSurfaceCreate();
|
||||||
if (gRender.fontSurface == NULL) {
|
if (gRender.fontSurface == NULL) {
|
||||||
free(fontTiles);
|
return false;
|
||||||
|
}
|
||||||
|
count = jlTileBankLoadToSurface(ST_FONT_PATH, gRender.fontSurface, palette);
|
||||||
|
if (count == 0u) {
|
||||||
|
jlSurfaceDestroy(gRender.fontSurface);
|
||||||
|
gRender.fontSurface = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Font palette is authoritative for the font surface so jlDrawText
|
// Font palette is authoritative for the font surface so jlDrawText
|
||||||
// reads back the authored colors. Stage palette is untouched.
|
// reads back the authored colors. Stage palette is untouched.
|
||||||
jlPaletteSet(gRender.fontSurface, 0u, palette);
|
jlPaletteSet(gRender.fontSurface, 0u, palette);
|
||||||
jlScbSetRange(gRender.fontSurface, 0, SURFACE_HEIGHT - 1, 0);
|
jlScbSetRange(gRender.fontSurface, 0, SURFACE_HEIGHT - 1, 0);
|
||||||
for (i = 0u; i < count; i++) {
|
|
||||||
uint8_t bx = (uint8_t)(i % ST_FONT_COLS);
|
|
||||||
uint8_t by = (uint8_t)(i / ST_FONT_COLS);
|
|
||||||
jlTilePaste(gRender.fontSurface, bx, by, &fontTiles[i]);
|
|
||||||
}
|
|
||||||
gRender.fontReady = true;
|
gRender.fontReady = true;
|
||||||
free(fontTiles);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue