mirror of
https://github.com/pkali/scorch_src.git
synced 2026-05-20 22:34:21 +02:00
5 bits workinggit status!
This commit is contained in:
@@ -2157,5 +2157,83 @@ zeroth_talk
|
||||
ldy #0
|
||||
rts
|
||||
.endp
|
||||
|
||||
;-------------------------------------------------
|
||||
.proc _calc_packed_display
|
||||
; Find Nth packed string inside a [len][packed-bytes] stream.
|
||||
;
|
||||
; in:
|
||||
; TextNumberOff = index (0..)
|
||||
; LineAddress4x4 = base address of the packed stream (points to first len byte)
|
||||
; out:
|
||||
; LineAddress4x4 = address of selected record (points to its len byte)
|
||||
; trashes: A, X, Y, temp, temp2
|
||||
;
|
||||
; Record size in bytes = 1 + ceil(len*5/8)
|
||||
; where `len` is the 1-byte character count (max 63).
|
||||
;-------------------------------------------------
|
||||
@idx = temp+1
|
||||
lda TextNumberOff
|
||||
sta @idx
|
||||
beq done
|
||||
|
||||
next_record
|
||||
ldy #0
|
||||
lda (LineAddress4x4),y
|
||||
sta temp ; len (low byte)
|
||||
|
||||
; advance past len byte
|
||||
inw LineAddress4x4
|
||||
|
||||
; temp2 = len*5 + 7
|
||||
lda temp
|
||||
sta temp2
|
||||
lda #0
|
||||
sta temp2+1
|
||||
|
||||
; temp2 = len*4
|
||||
asl temp2
|
||||
rol temp2+1
|
||||
asl temp2
|
||||
rol temp2+1
|
||||
; temp2 = len*5
|
||||
clc
|
||||
lda temp2
|
||||
adc temp
|
||||
sta temp2
|
||||
lda temp2+1
|
||||
adc #0
|
||||
sta temp2+1
|
||||
; +7 for ceil
|
||||
clc
|
||||
lda temp2
|
||||
adc #7
|
||||
sta temp2
|
||||
bcc @+
|
||||
inc temp2+1
|
||||
@
|
||||
; >>3 (divide by 8)
|
||||
lsr temp2+1
|
||||
ror temp2
|
||||
lsr temp2+1
|
||||
ror temp2
|
||||
lsr temp2+1
|
||||
ror temp2
|
||||
|
||||
; LineAddress4x4 += temp2
|
||||
clc
|
||||
lda LineAddress4x4
|
||||
adc temp2
|
||||
sta LineAddress4x4
|
||||
lda LineAddress4x4+1
|
||||
adc temp2+1
|
||||
sta LineAddress4x4+1
|
||||
|
||||
dec @idx
|
||||
bne next_record
|
||||
|
||||
done
|
||||
rts
|
||||
.endp
|
||||
|
||||
.endif
|
||||
@@ -376,6 +376,84 @@ DisplayAngle
|
||||
zeroth_talk
|
||||
rts
|
||||
.endp
|
||||
|
||||
;-------------------------------------------------
|
||||
.proc _calc_packed_display
|
||||
; Find Nth packed string inside a [len][packed-bytes] stream.
|
||||
;
|
||||
; in:
|
||||
; TextNumberOff = index (0..)
|
||||
; LineAddress4x4 = base address of the packed stream (points to first len byte)
|
||||
; out:
|
||||
; LineAddress4x4 = address of selected record (points to its len byte)
|
||||
; trashes: A, X, Y, temp, temp2
|
||||
;
|
||||
; Record size in bytes = 1 + ceil(len*5/8)
|
||||
; where `len` is the 1-byte character count (max 63).
|
||||
;-------------------------------------------------
|
||||
@idx = temp+1
|
||||
lda TextNumberOff
|
||||
sta @idx
|
||||
beq done
|
||||
|
||||
next_record
|
||||
ldy #0
|
||||
lda (LineAddress4x4),y
|
||||
sta temp ; len (low byte)
|
||||
|
||||
; advance past len byte
|
||||
inw LineAddress4x4
|
||||
|
||||
; temp2 = len*5 + 7
|
||||
lda temp
|
||||
sta temp2
|
||||
lda #0
|
||||
sta temp2+1
|
||||
|
||||
; temp2 = len*4
|
||||
asl temp2
|
||||
rol temp2+1
|
||||
asl temp2
|
||||
rol temp2+1
|
||||
; temp2 = len*5
|
||||
clc
|
||||
lda temp2
|
||||
adc temp
|
||||
sta temp2
|
||||
lda temp2+1
|
||||
adc #0
|
||||
sta temp2+1
|
||||
; +7 for ceil
|
||||
clc
|
||||
lda temp2
|
||||
adc #7
|
||||
sta temp2
|
||||
bcc @+
|
||||
inc temp2+1
|
||||
@
|
||||
; >>3 (divide by 8)
|
||||
lsr temp2+1
|
||||
ror temp2
|
||||
lsr temp2+1
|
||||
ror temp2
|
||||
lsr temp2+1
|
||||
ror temp2
|
||||
|
||||
; LineAddress4x4 += temp2
|
||||
clc
|
||||
lda LineAddress4x4
|
||||
adc temp2
|
||||
sta LineAddress4x4
|
||||
lda LineAddress4x4+1
|
||||
adc temp2+1
|
||||
sta LineAddress4x4+1
|
||||
|
||||
dec @idx
|
||||
bne next_record
|
||||
|
||||
done
|
||||
rts
|
||||
.endp
|
||||
;-------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Pack Scorch talk texts into 5-bit stream.
|
||||
|
||||
Reads artwork/talk.asm and generates artwork/talk_packed.asm.
|
||||
|
||||
Design goals:
|
||||
- Keep the original artwork/talk.asm as editable source of strings.
|
||||
- Generate a MADS-friendly .asm include with:
|
||||
- .proc talk (namespace-compatible)
|
||||
- talk5_alphabet (32 chars)
|
||||
- talk5_data: records of [len][packed bytes...]
|
||||
- constants (NumberOfOffensiveTexts, etc.) copied verbatim
|
||||
- hoverFull/hoverEmpty blocks copied verbatim (uncompressed)
|
||||
|
||||
Bit packing:
|
||||
- 5-bit codes are packed LSB-first.
|
||||
- For each string record:
|
||||
- 1 byte length (0..63)
|
||||
- packed bytes little-endian (first char in bits 0..4)
|
||||
|
||||
The decoder in 6502 should read 5-bit codes from the low bits.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Iterable, List, Tuple
|
||||
|
||||
|
||||
# 32-symbol alphabet.
|
||||
# Note: We intentionally omit 'X' to make room for punctuation.
|
||||
# Order must match the decoder table.
|
||||
ALPHABET = " ABCDEFGHIJKLMNOPQRSTUVWYZ'!,-.?" # length must be 32
|
||||
|
||||
|
||||
_DTA_STR_RE = re.compile(r"^\s*dta\s+d\"(.*?)\"\^\s*(?:;.*)?$")
|
||||
|
||||
|
||||
def _iter_lines(path: Path) -> List[str]:
|
||||
return path.read_text(encoding="utf-8", errors="replace").splitlines()
|
||||
|
||||
|
||||
def _find_section(lines: List[str], start_pat: re.Pattern[str], end_pat: re.Pattern[str]) -> Tuple[int, int]:
|
||||
start_idx = None
|
||||
for i, line in enumerate(lines):
|
||||
if start_pat.search(line):
|
||||
start_idx = i
|
||||
break
|
||||
if start_idx is None:
|
||||
raise ValueError(f"Start pattern not found: {start_pat.pattern}")
|
||||
|
||||
for j in range(start_idx + 1, len(lines)):
|
||||
if end_pat.search(lines[j]):
|
||||
return start_idx, j
|
||||
raise ValueError(f"End pattern not found: {end_pat.pattern}")
|
||||
|
||||
|
||||
def extract_talk_strings(lines: List[str]) -> List[str]:
|
||||
# Only pack strings inside `.proc talk` up to the `LEND` marker.
|
||||
proc_start, _ = _find_section(lines, re.compile(r"^\s*\.proc\s+talk\b"), re.compile(r"^\s*\.endp\b"))
|
||||
|
||||
lend_idx = None
|
||||
for i in range(proc_start, len(lines)):
|
||||
if re.match(r"^\s*LEND\b", lines[i]):
|
||||
lend_idx = i
|
||||
break
|
||||
if lend_idx is None:
|
||||
raise ValueError("LEND marker not found inside .proc talk")
|
||||
|
||||
strings: List[str] = []
|
||||
for line in lines[proc_start:lend_idx]:
|
||||
m = _DTA_STR_RE.match(line)
|
||||
if m:
|
||||
strings.append(m.group(1))
|
||||
|
||||
if not strings:
|
||||
raise ValueError("No talk strings found to pack")
|
||||
|
||||
return strings
|
||||
|
||||
|
||||
def extract_constants_block(lines: List[str]) -> List[str]:
|
||||
# Copy constant definitions from after LEND up to `.endp` (inclusive of constants, exclusive of .endp).
|
||||
proc_start, proc_end = _find_section(lines, re.compile(r"^\s*\.proc\s+talk\b"), re.compile(r"^\s*\.endp\b"))
|
||||
|
||||
lend_idx = None
|
||||
for i in range(proc_start, proc_end + 1):
|
||||
if re.match(r"^\s*LEND\b", lines[i]):
|
||||
lend_idx = i
|
||||
break
|
||||
if lend_idx is None:
|
||||
raise ValueError("LEND marker not found inside .proc talk")
|
||||
|
||||
# Keep from LEND line through the line before `.endp`.
|
||||
return lines[lend_idx:proc_end]
|
||||
|
||||
|
||||
def extract_tail_after_talk_proc(lines: List[str]) -> List[str]:
|
||||
# Copy everything after `.endp` for talk proc. This includes hoverFull/hoverEmpty.
|
||||
_, proc_end = _find_section(lines, re.compile(r"^\s*\.proc\s+talk\b"), re.compile(r"^\s*\.endp\b"))
|
||||
return lines[proc_end + 1 :]
|
||||
|
||||
|
||||
def validate_alphabet() -> None:
|
||||
if len(ALPHABET) != 32:
|
||||
raise ValueError(f"ALPHABET must be 32 chars, got {len(ALPHABET)}")
|
||||
if len(set(ALPHABET)) != len(ALPHABET):
|
||||
raise ValueError("ALPHABET has duplicate characters")
|
||||
|
||||
|
||||
def pack_string_5bit(s: str, mapping: dict[str, int]) -> bytes:
|
||||
if len(s) > 63:
|
||||
raise ValueError(f"String too long ({len(s)}): {s!r}")
|
||||
|
||||
out = bytearray()
|
||||
out.append(len(s) & 0xFF)
|
||||
|
||||
bitbuf = 0
|
||||
bitcount = 0
|
||||
|
||||
for ch in s:
|
||||
try:
|
||||
code = mapping[ch]
|
||||
except KeyError as e:
|
||||
raise ValueError(f"Character {ch!r} not in alphabet") from e
|
||||
|
||||
bitbuf |= (code & 0x1F) << bitcount
|
||||
bitcount += 5
|
||||
|
||||
while bitcount >= 8:
|
||||
out.append(bitbuf & 0xFF)
|
||||
bitbuf >>= 8
|
||||
bitcount -= 8
|
||||
|
||||
if bitcount:
|
||||
out.append(bitbuf & 0xFF)
|
||||
|
||||
return bytes(out)
|
||||
|
||||
|
||||
def format_dta_bytes(data: bytes, indent: str = " ", per_line: int = 16) -> List[str]:
|
||||
lines: List[str] = []
|
||||
for i in range(0, len(data), per_line):
|
||||
chunk = data[i : i + per_line]
|
||||
nums = ",".join(f"${b:02x}" for b in chunk)
|
||||
lines.append(f"{indent}dta b({nums})")
|
||||
return lines
|
||||
|
||||
|
||||
def generate_output(
|
||||
source_path: Path,
|
||||
strings: List[str],
|
||||
constants_block: List[str],
|
||||
tail_lines: List[str],
|
||||
) -> str:
|
||||
mapping = {ch: i for i, ch in enumerate(ALPHABET)}
|
||||
|
||||
packed_records: List[bytes] = [pack_string_5bit(s, mapping) for s in strings]
|
||||
|
||||
out_lines: List[str] = []
|
||||
out_lines.append("; AUTO-GENERATED FILE - DO NOT EDIT")
|
||||
out_lines.append(f"; Generated by {source_path.name} -> pack_talk5.py")
|
||||
out_lines.append("; Source: artwork/talk.asm")
|
||||
out_lines.append("")
|
||||
|
||||
out_lines.append(".proc talk")
|
||||
out_lines.append("; 5-bit packed talk strings (len + packed bytes)")
|
||||
out_lines.append(f"talk5_alphabet dta d\"{ALPHABET}\"")
|
||||
out_lines.append("talk5_data")
|
||||
|
||||
for rec in packed_records:
|
||||
out_lines.extend(format_dta_bytes(rec))
|
||||
|
||||
out_lines.append(";")
|
||||
out_lines.append("; Constants copied from source")
|
||||
out_lines.extend(constants_block)
|
||||
out_lines.append(".endp")
|
||||
|
||||
if tail_lines:
|
||||
out_lines.append("")
|
||||
out_lines.append("; Tail copied from source (uncompressed)")
|
||||
out_lines.extend(tail_lines)
|
||||
|
||||
out_lines.append("")
|
||||
return "\n".join(out_lines)
|
||||
|
||||
|
||||
def main(argv: List[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Pack artwork/talk.asm into a 5-bit blob for MADS.")
|
||||
parser.add_argument(
|
||||
"--src",
|
||||
default="artwork/talk.asm",
|
||||
help="Path to source talk.asm (default: artwork/talk.asm)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--out",
|
||||
default="artwork/talk_packed.asm",
|
||||
help="Path to output .asm include (default: artwork/talk_packed.asm)",
|
||||
)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
validate_alphabet()
|
||||
|
||||
src_path = Path(args.src)
|
||||
out_path = Path(args.out)
|
||||
|
||||
lines = _iter_lines(src_path)
|
||||
strings = extract_talk_strings(lines)
|
||||
constants_block = extract_constants_block(lines)
|
||||
tail_lines = extract_tail_after_talk_proc(lines)
|
||||
|
||||
content = generate_output(src_path, strings, constants_block, tail_lines)
|
||||
|
||||
out_path.write_text(content, encoding="utf-8")
|
||||
print(f"Wrote {out_path} ({len(content.encode('utf-8'))} bytes text)")
|
||||
print(f"Packed {len(strings)} strings")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
+4
-4
@@ -101,23 +101,23 @@
|
||||
dta d"I LET YOU HIT ME!"^
|
||||
dta d"SUCKER SHOT!"^
|
||||
dta d"I DIDN'T WANT TO LIVE ANYWAY."^
|
||||
dta d"-<SOB>-"^
|
||||
dta d".-SOB-."^
|
||||
dta d"WAS THAT AS CLOSE AS I THINK IT WAS?"^
|
||||
dta d"JOIN THE ARMY, SEE THE WORLD THEY SAID."^
|
||||
dta d"IT WASN'T JUST A JOB, IT WAS AN ADVENTURE!"^
|
||||
dta d"I DIDN'T LIKE VIOLENCE ANYWAY!"^
|
||||
dta d"I THOUGHT YOU LIKED ME?"^
|
||||
dta d"CTO XYEB"^
|
||||
dta d"RUSH B!"^
|
||||
dta d"I THINK THIS GUY'S A LITTLE CRAZY."^
|
||||
dta d"SOMEHOW I DON'T FEEL LIKE KILLING ANYMORE."^
|
||||
dta d"HEY! KILLIN' AIN'T COOL."^
|
||||
dta d"GEE... THANKS."^
|
||||
dta d"I'VE FALLEN AND I CAN'T GET UP!"^
|
||||
dta d"911?"^
|
||||
dta d"NINE ONE ONE?"^
|
||||
dta d"OH NO! HERE I BLOW AGAIN!"^
|
||||
dta d"I'LL BE BACK..."^
|
||||
dta d"I'VE GOT LAWYERS!"^
|
||||
dta d"CALL 1-900-SUE-TANK."^
|
||||
dta d"CALL MY LAWYERS!"^
|
||||
dta d"YOU BIG DUMMY!"^ ;(sanford and son)
|
||||
LEND
|
||||
NumberOfOffensiveTexts=55
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
; AUTO-GENERATED FILE - DO NOT EDIT
|
||||
; Generated by talk.asm -> pack_talk5.py
|
||||
; Source: artwork/talk.asm
|
||||
|
||||
.proc talk
|
||||
; 5-bit packed talk strings (len + packed bytes)
|
||||
talk5_alphabet dta d" ABCDEFGHIJKLMNOPQRSTUVWYZ'!,-.?"
|
||||
talk5_data
|
||||
dta b($04,$24,$95,$0d)
|
||||
dta b($10,$a6,$4a,$40,$4a,$a5,$73,$20,$16,$1c,$d9)
|
||||
dta b($11,$f8,$55,$2d,$0b,$20,$25,$10,$d0,$4a,$a0,$1e)
|
||||
dta b($0f,$24,$15,$30,$5e,$6b,$a9,$00,$98,$ce,$06)
|
||||
dta b($08,$36,$0d,$fa,$24,$de)
|
||||
dta b($11,$24,$15,$0e,$02,$4b,$c5,$81,$79,$93,$2b,$1b)
|
||||
dta b($08,$e1,$ca,$ba,$f6,$de)
|
||||
dta b($09,$03,$af,$00,$04,$0b,$14)
|
||||
dta b($0a,$34,$ac,$02,$28,$4a,$73,$03)
|
||||
dta b($0e,$25,$50,$d0,$30,$98,$e8,$49,$3a,$37)
|
||||
dta b($0d,$f8,$55,$2d,$0b,$a0,$2f,$4c,$ba,$01)
|
||||
dta b($07,$22,$b8,$1c,$d2,$06)
|
||||
dta b($0a,$0f,$16,$07,$6e,$22,$65,$03)
|
||||
dta b($09,$28,$00,$14,$00,$0a,$1e)
|
||||
dta b($07,$03,$05,$79,$ca,$06)
|
||||
dta b($07,$81,$d2,$30,$d6,$06)
|
||||
dta b($0f,$24,$15,$0e,$68,$70,$ab,$cf,$51,$db,$06)
|
||||
dta b($0d,$c9,$01,$fc,$aa,$04,$26,$8c,$b2,$01)
|
||||
dta b($0c,$34,$ac,$02,$02,$40,$69,$95,$0d)
|
||||
dta b($0c,$2d,$ac,$02,$1a,$06,$24,$60,$0f)
|
||||
dta b($0d,$cb,$bd,$b1,$38,$58,$ee,$8d,$e5,$01)
|
||||
dta b($23,$46,$be,$06,$50,$61,$4c,$4f,$80,$4a,$90,$14,$24,$30,$69,$10)
|
||||
dta b($20,$50,$40,$51,$29,$de,$7b)
|
||||
dta b($18,$e4,$01,$fc,$2a,$30,$a5,$30,$c0,$ea,$58,$98,$03,$1a,$dc,$fa)
|
||||
dta b($12,$f8,$55,$2d,$0b,$78,$95,$d2,$00,$50,$91,$c5,$03)
|
||||
dta b($11,$37,$50,$3a,$03,$68,$81,$d2,$00,$f0,$ab,$1f)
|
||||
dta b($16,$46,$96,$92,$0b,$07,$4f,$82,$a4,$19,$03,$13,$bd,$47,$37)
|
||||
dta b($21,$b7,$80,$f1,$5a,$01,$c9,$01,$58,$c2,$28,$a0,$83,$89,$de,$a3)
|
||||
dta b($80,$3e,$b0,$12,$63,$1b)
|
||||
dta b($2a,$09,$b0,$67,$0b,$a0,$a8,$80,$d9,$0a,$63,$e0,$19,$e0,$02,$0c)
|
||||
dta b($ac,$81,$e4,$00,$45,$05,$b4,$27,$5d,$72,$c7,$03)
|
||||
dta b($12,$13,$bd,$0b,$e6,$6b,$05,$c8,$32,$61,$19,$d4,$03)
|
||||
dta b($1e,$aa,$4e,$0a,$2e,$7a,$80,$3c,$80,$5f,$05,$14,$25,$b7,$00,$7e)
|
||||
dta b($15,$04,$59,$3e)
|
||||
dta b($0f,$ec,$bd,$05,$5e,$a5,$40,$14,$f6,$ee,$06)
|
||||
dta b($10,$ec,$bd,$05,$9e,$2d,$12,$50,$54,$64,$f1)
|
||||
dta b($1f,$a7,$96,$39,$c1,$45,$81,$ea,$09,$c6,$6b,$c9,$1d,$60,$9e,$04)
|
||||
dta b($24,$39,$57,$e4,$07)
|
||||
dta b($10,$ad,$48,$89,$c1,$40,$32,$4d,$da,$c2,$f4)
|
||||
dta b($14,$a8,$c8,$02,$ce,$2b,$13,$b8,$47,$51,$72,$c7,$7b,$0f)
|
||||
dta b($23,$e4,$39,$4d,$c1,$7d,$52,$62,$0e,$12,$05,$69,$3a,$4d,$41,$00)
|
||||
dta b($2c,$d9,$02,$e4,$ab,$8e,$78)
|
||||
dta b($16,$82,$bd,$47,$38,$80,$21,$39,$0e,$6c,$7a,$ac,$b8,$51,$36)
|
||||
dta b($11,$34,$ac,$02,$28,$4a,$93,$83,$99,$e6,$c4,$1b)
|
||||
dta b($14,$09,$4c,$14,$18,$03,$86,$05,$4a,$8b,$03,$f8,$d5,$0d)
|
||||
dta b($1d,$09,$4c,$14,$18,$03,$b3,$85,$89,$00,$7e,$55,$82,$7a,$18,$06)
|
||||
dta b($34,$b8,$b5,$01)
|
||||
dta b($1f,$09,$dc,$e7,$48,$91,$e0,$a2,$40,$01,$45,$69,$02,$51,$29,$7d)
|
||||
dta b($0e,$90,$57,$e6,$07)
|
||||
dta b($1b,$e4,$39,$4d,$01,$0d,$ab,$00,$8a,$d2,$04,$b0,$c8,$f9,$5c,$60)
|
||||
dta b($0c,$7b)
|
||||
dta b($18,$f7,$55,$46,$00,$45,$69,$82,$16,$56,$01,$f8,$55,$d0,$02,$f9)
|
||||
dta b($24,$09,$d0,$c7,$08,$c0,$af,$02,$fa,$00,$2b,$c1,$16,$d0,$30,$98)
|
||||
dta b($69,$d2,$22,$41,$60,$cf,$95,$0d)
|
||||
dta b($1b,$09,$8c,$57,$19,$01,$13,$06,$59,$00,$7e,$95,$03,$51,$29,$b8)
|
||||
dta b($08,$7f)
|
||||
dta b($1d,$0d,$03,$f1,$9a,$00,$69,$02,$91,$ce,$29,$12,$50,$14,$1c,$c0)
|
||||
dta b($af,$ca,$e9,$01)
|
||||
dta b($16,$e4,$39,$4d,$81,$79,$f2,$14,$0a,$82,$78,$95,$82,$56,$36)
|
||||
dta b($15,$28,$4c,$1a,$00,$0b,$c0,$a6,$49,$03,$07,$22,$08,$bc,$01)
|
||||
dta b($1d,$14,$a5,$09,$d2,$04,$f8,$55,$09,$84,$0c,$c9,$81,$e7,$c0,$1c)
|
||||
dta b($4f,$0e,$e4,$01)
|
||||
dta b($24,$14,$a5,$09,$e6,$90,$a5,$38,$10,$92,$d3,$14,$88,$74,$40,$71)
|
||||
dta b($af,$1e,$04,$cc,$93,$a0,$4e,$0f)
|
||||
dta b($26,$09,$4c,$14,$18,$03,$2f,$31,$d0,$30,$a0,$55,$ca,$42,$c1,$4d)
|
||||
dta b($14,$01,$fc,$aa,$04,$82,$bd,$47,$3c)
|
||||
dta b($1a,$49,$37,$70,$9e,$73,$01,$08,$59,$c2,$02,$f8,$55,$09,$4c,$18)
|
||||
dta b($65,$03)
|
||||
dta b($18,$2d,$b4,$00,$66,$48,$04,$2c,$f7,$c6,$02,$f8,$55,$f0,$2a,$dd)
|
||||
dta b($16,$09,$a0,$07,$0b,$c0,$af,$82,$e2,$d4,$c3,$00,$86,$e4,$36)
|
||||
dta b($24,$e8,$5d,$4d,$00,$7e,$15,$b0,$b4,$0a,$78,$ae,$80,$30,$e4,$9b)
|
||||
dta b($13,$e0,$57,$25,$60,$09,$ce,$0f)
|
||||
dta b($24,$30,$48,$9a,$dc,$01,$69,$82,$59,$07,$02,$f3,$96,$42,$c1,$7c)
|
||||
dta b($52,$be,$eb,$bd,$07,$ee,$d1,$0d)
|
||||
dta b($04,$f5,$a0,$0d)
|
||||
dta b($06,$21,$c8,$83,$36)
|
||||
dta b($09,$21,$84,$73,$10,$42,$1b)
|
||||
dta b($0c,$49,$37,$d0,$0a,$a3,$c9,$9d,$0d)
|
||||
dta b($05,$ef,$19,$ef,$01)
|
||||
dta b($03,$0f,$6d)
|
||||
dta b($05,$a5,$94,$b5,$01)
|
||||
dta b($06,$21,$8c,$81,$36)
|
||||
dta b($1c,$09,$a0,$40,$0b,$48,$14,$5c,$54,$1c,$a0,$28,$50,$80,$02,$84)
|
||||
dta b($c5,$4d,$0f)
|
||||
dta b($20,$cf,$15,$80,$12,$05,$23,$38,$20,$6b,$72,$00,$bf,$2a,$c1,$45)
|
||||
dta b($8f,$15,$40,$02,$f6)
|
||||
dta b($06,$0f,$01,$f7,$36)
|
||||
dta b($07,$ee,$51,$d0,$ca,$06)
|
||||
dta b($05,$af,$0e,$e4,$01)
|
||||
dta b($11,$0f,$01,$f7,$38,$70,$8f,$82,$70,$42,$72,$1e)
|
||||
dta b($1b,$c1,$3d,$8a,$8a,$04,$cf,$15,$20,$12,$2d,$13,$50,$54,$00,$a9)
|
||||
dta b($93,$7a)
|
||||
dta b($08,$e7,$3d,$22,$70,$f1)
|
||||
dta b($08,$a8,$30,$08,$5a,$d9)
|
||||
dta b($16,$26,$c8,$72,$0b,$63,$1c,$0c,$59,$0b,$03,$f7,$49,$46,$3c)
|
||||
dta b($13,$b2,$b4,$d2,$44,$91,$80,$a2,$02,$02,$0b,$ed,$6d)
|
||||
dta b($07,$0f,$81,$16,$dc,$06)
|
||||
dta b($07,$e4,$bd,$7a,$d0,$06)
|
||||
dta b($12,$ae,$5c,$40,$02,$e6,$c0,$95,$0b,$c4,$6b,$c2,$03)
|
||||
dta b($20,$14,$a5,$09,$d2,$04,$14,$15,$50,$1c,$e1,$a0,$61,$f0,$1c,$c3)
|
||||
dta b($c0,$c8,$54,$1c,$f1)
|
||||
dta b($0b,$b6,$48,$0c,$4c,$75,$0e,$7b)
|
||||
dta b($12,$14,$15,$60,$02,$05,$2c,$10,$0c,$66,$70,$c7,$03)
|
||||
dta b($16,$17,$61,$40,$5e,$99,$00,$05,$08,$8b,$03,$f4,$81,$56,$3e)
|
||||
dta b($0f,$49,$37,$70,$5e,$72,$07,$90,$77,$9d,$07)
|
||||
dta b($17,$49,$db,$02,$ce,$a3,$20,$00,$11,$08,$30,$a5,$b0,$e4,$8e,$07)
|
||||
dta b($08,$43,$06,$f8,$58,$f0)
|
||||
dta b($04,$f0,$dd,$0d)
|
||||
dta b($04,$22,$99,$0d)
|
||||
dta b($04,$22,$b4,$0d)
|
||||
dta b($05,$f9,$b9,$b5,$01)
|
||||
dta b($1f,$09,$4c,$f4,$2a,$23,$da,$16,$c0,$d2,$a4,$c5,$15,$02,$e8,$03)
|
||||
dta b($0d,$83,$f6,$9a,$07)
|
||||
dta b($2a,$09,$dc,$c0,$16,$a0,$48,$be,$7a,$10,$a0,$a8,$00,$1b,$18,$2b)
|
||||
dta b($18,$3c,$03,$28,$2a,$60,$a2,$40,$de,$f5,$de,$03)
|
||||
dta b($14,$17,$05,$0a,$6e,$98,$80,$a2,$40,$81,$7b,$69,$96,$0f)
|
||||
dta b($24,$2d,$b4,$00,$66,$48,$04,$50,$54,$64,$d1,$04,$88,$02,$48,$c0)
|
||||
dta b($13,$b0,$b4,$0a,$a0,$28,$4d,$0f)
|
||||
dta b($1e,$89,$ea,$09,$54,$9d,$14,$3c,$57,$c0,$33,$80,$a2,$37,$0b,$20)
|
||||
dta b($01,$4f,$ef,$3d)
|
||||
dta b($17,$09,$cc,$52,$40,$00,$42,$a6,$83,$28,$60,$e9,$20,$ea,$bd,$07)
|
||||
dta b($13,$ed,$b5,$86,$3f,$48,$13,$50,$14,$28,$c0,$af,$7e)
|
||||
dta b($11,$09,$b0,$42,$01,$7e,$15,$a0,$44,$41,$2b,$1b)
|
||||
dta b($0c,$b3,$8e,$55,$24,$98,$e8,$d1,$0d)
|
||||
dta b($1d,$09,$90,$44,$9c,$a6,$e0,$06,$47,$01,$7d,$80,$25,$5b,$40,$70)
|
||||
dta b($f8,$06,$ec,$01)
|
||||
dta b($07,$be,$cf,$27,$ba,$07)
|
||||
dta b($24,$37,$4c,$40,$51,$a0,$20,$4c,$30,$d8,$9b,$05,$84,$09,$12,$a0)
|
||||
dta b($28,$b9,$05,$12,$05,$37,$cc,$0f)
|
||||
dta b($27,$ea,$25,$07,$28,$2a,$20,$c8,$86,$39,$98,$a5,$00,$8a,$0a,$b8)
|
||||
dta b($4f,$32,$02,$28,$2a,$18,$cc,$90,$88,$07)
|
||||
dta b($2a,$89,$82,$1b,$a6,$d3,$14,$a8,$3a,$29,$08,$40,$3d,$c1,$41,$a2)
|
||||
dta b($e0,$86,$09,$82,$03,$81,$d8,$e2,$68,$95,$65,$03)
|
||||
dta b($1e,$09,$90,$44,$9c,$a6,$80,$a5,$55,$80,$4d,$8f,$15,$37,$0a,$08)
|
||||
dta b($0e,$df,$80,$37)
|
||||
dta b($17,$09,$50,$f4,$ea,$41,$14,$e0,$57,$01,$4b,$ab,$10,$d0,$ca,$07)
|
||||
dta b($07,$b2,$4e,$04,$c4,$06)
|
||||
dta b($22,$09,$50,$94,$dc,$02,$14,$a5,$09,$4e,$c5,$7a,$82,$00,$58,$a2)
|
||||
dta b($94,$15,$30,$64,$c8,$d8,$03)
|
||||
dta b($2a,$f3,$b5,$82,$de,$05,$09,$90,$e7,$34,$05,$a6,$14,$06,$58,$5a)
|
||||
dta b($05,$ac,$c4,$58,$72,$07,$04,$87,$db,$93,$c5,$03)
|
||||
dta b($18,$a8,$e0,$0d,$56,$62,$2c,$39,$0d,$42,$72,$9a,$82,$f1,$1e,$f3)
|
||||
dta b($0e,$a7,$14,$ef,$3d,$a0,$28,$b8,$35,$3d)
|
||||
dta b($1f,$49,$db,$02,$4c,$60,$ac,$38,$10,$1c,$01,$09,$8c,$e0,$34,$05)
|
||||
dta b($a7,$50,$50,$e1,$06)
|
||||
dta b($0d,$2e,$b9,$02,$9e,$2b,$e0,$b9,$f2,$01)
|
||||
dta b($19,$0f,$01,$f7,$36,$40,$45,$16,$90,$80,$60,$ef,$82,$70,$42,$72)
|
||||
dta b($1b)
|
||||
dta b($0f,$49,$33,$06,$44,$01,$22,$8c,$e5,$bd,$07)
|
||||
dta b($11,$49,$db,$02,$ce,$a3,$80,$85,$8b,$8b,$9c,$1b)
|
||||
dta b($10,$23,$30,$06,$1a,$06,$2c,$5c,$5c,$e4,$dc)
|
||||
dta b($0e,$f8,$55,$20,$d2,$01,$a4,$b6,$86,$37)
|
||||
;
|
||||
; Constants copied from source
|
||||
LEND
|
||||
NumberOfOffensiveTexts=55
|
||||
NumberOfDeffensiveTexts=62
|
||||
NumberOfPropagandaTexts=21
|
||||
VeryFunnyText=79
|
||||
.endp
|
||||
|
||||
; Tail copied from source (uncompressed)
|
||||
hoverFull dta d"MY HOVERCRAFT IS FULL OF EELS!"^
|
||||
hoverFullEnd
|
||||
hoverEmpty dta d"RUNNING OUT OF EELS"^
|
||||
hoverEmptyEnd
|
||||
+134
-12
@@ -1422,22 +1422,35 @@ notZero
|
||||
sta plot4x4color
|
||||
tya
|
||||
tax ; save Y
|
||||
mwa #talk LineAddress4x4
|
||||
jsr _calc_inverse_display
|
||||
|
||||
; now find length of the text
|
||||
@ iny
|
||||
lda (LineAddress4x4),y
|
||||
bpl @-
|
||||
iny
|
||||
sty fx
|
||||
mwa #talk.talk5_data LineAddress4x4
|
||||
jsr _calc_packed_display
|
||||
|
||||
; record starts with length byte
|
||||
ldy #0
|
||||
lda (LineAddress4x4),y
|
||||
sta fx
|
||||
inw LineAddress4x4 ; point to packed payload
|
||||
|
||||
txa ; load Y
|
||||
tay
|
||||
jmp Display4x4AboveTankPacked
|
||||
.endp
|
||||
|
||||
;--------------------------------------------------------
|
||||
.proc Display4x4AboveTankPacked ;
|
||||
; Displays packed texts using PutChar4x4 above tank and mountains.
|
||||
;parameters are:
|
||||
;Y - number of tank above which text is displayed
|
||||
;fx - length of text
|
||||
;LineAddress4x4 - address of packed payload
|
||||
|
||||
lda xtankstableL,y
|
||||
sta temp
|
||||
lda xtankstableH,y
|
||||
sta temp+1
|
||||
jsr Calculate4x4TextPosition
|
||||
jmp TypeLine4x4Packed.noLengthNoColor
|
||||
|
||||
;jsr Display4x4AboveTank
|
||||
;rts
|
||||
; POZOR !!!
|
||||
.endp
|
||||
|
||||
;--------------------------------------------------------
|
||||
@@ -1627,6 +1640,115 @@ EndOfTypeLine4x4
|
||||
rts
|
||||
.endp
|
||||
|
||||
;-------------------------------
|
||||
.proc TypeLine4x4Packed ;
|
||||
;-------------------------------
|
||||
;this routine prints packed line of length `fx`
|
||||
;packed payload address in LineAddress4x4
|
||||
;starting from LineXdraw, LineYdraw
|
||||
|
||||
lda #14 ; default length of 4x4 texts
|
||||
sta fx
|
||||
|
||||
variableLength
|
||||
lda #$ff ; $ff - visible characters, $00 - clearing
|
||||
|
||||
staplot4x4color
|
||||
sta plot4x4color
|
||||
noLengthNoColor
|
||||
|
||||
; init packed bitstream
|
||||
; Reuse ZP vars:
|
||||
; - LineAddress4x4 is the packed byte pointer (advanced during decoding)
|
||||
; - Multiplier/Multiplier_ are used as bit buffer/state
|
||||
lda #0
|
||||
sta Multiplier
|
||||
sta Multiplier+1
|
||||
sta Multiplier_
|
||||
|
||||
ldy #0
|
||||
sty LineCharNr
|
||||
|
||||
TypeLine4x4PackedLoop
|
||||
ldy LineCharNr
|
||||
|
||||
jsr _packed_get5bits
|
||||
tay
|
||||
lda talk.talk5_alphabet,y
|
||||
sta CharCode4x4
|
||||
mwa LineXdraw dx
|
||||
mva LineYdraw dy
|
||||
mva #0 dy+1 ; dy is 2 bytes value
|
||||
jsr PutChar4x4 ;type empty pixels as well!
|
||||
adw LineXdraw #4
|
||||
inc:lda LineCharNr
|
||||
cmp fx
|
||||
bne TypeLine4x4PackedLoop
|
||||
|
||||
rts
|
||||
.endp
|
||||
|
||||
;--------------------------------
|
||||
; Packed 5-bit bitstream decoder
|
||||
;
|
||||
; Uses a 16-bit shift register where the lowest bits are the next bits to read.
|
||||
; Bytes are appended little-endian (LSB-first) at bit position PackedBitCount4x4.
|
||||
;--------------------------------
|
||||
.proc _packed_get5bits
|
||||
; ensure at least 5 bits available
|
||||
lda Multiplier_
|
||||
cmp #5
|
||||
bcs have_bits
|
||||
|
||||
; read next byte and append at current bit count
|
||||
ldy #0
|
||||
lda (LineAddress4x4),y
|
||||
sta temp2 ; new byte
|
||||
lda #0
|
||||
sta temp2+1
|
||||
inw LineAddress4x4
|
||||
|
||||
ldx Multiplier_
|
||||
beq append_ready
|
||||
append_shift
|
||||
asl temp2
|
||||
rol temp2+1
|
||||
dex
|
||||
bne append_shift
|
||||
append_ready
|
||||
lda Multiplier
|
||||
ora temp2
|
||||
sta Multiplier
|
||||
lda Multiplier+1
|
||||
ora temp2+1
|
||||
sta Multiplier+1
|
||||
|
||||
lda Multiplier_
|
||||
clc
|
||||
adc #8
|
||||
sta Multiplier_
|
||||
|
||||
have_bits
|
||||
lda Multiplier
|
||||
and #$1f
|
||||
sta temp2
|
||||
|
||||
; shift register right by 5
|
||||
ldx #5
|
||||
@ lsr Multiplier+1
|
||||
ror Multiplier
|
||||
dex
|
||||
bne @-
|
||||
|
||||
lda Multiplier_
|
||||
sec
|
||||
sbc #5
|
||||
sta Multiplier_
|
||||
|
||||
lda temp2
|
||||
rts
|
||||
.endp
|
||||
|
||||
|
||||
;--------------------------------
|
||||
.proc AreYouSure
|
||||
|
||||
+1
-1
@@ -535,7 +535,7 @@ noingame
|
||||
;----------------------------------------------
|
||||
icl 'ai.asm'
|
||||
;----------------------------------------------
|
||||
icl 'artwork/talk.asm'
|
||||
icl 'artwork/talk_packed.asm'
|
||||
;----------------------------------------------
|
||||
TankFont
|
||||
ins 'artwork/tanksv4.fnt',+0,384 ; 48 characters only
|
||||
|
||||
Binary file not shown.
+1
-1
@@ -315,7 +315,7 @@ noShellDelay
|
||||
;----------------------------------------------
|
||||
icl 'ai.asm'
|
||||
;----------------------------------------------
|
||||
icl 'artwork/talk.asm'
|
||||
icl 'artwork/talk_packed.asm'
|
||||
;----------------------------------------------
|
||||
TankFont
|
||||
ins 'artwork/tanksv4.fnt',+0,384 ; 48 characters only
|
||||
|
||||
+7
-11
@@ -399,19 +399,15 @@ nexttext
|
||||
bcs @-
|
||||
|
||||
sta TextNumberOff
|
||||
; all text start from `talk` and end with an inverse.
|
||||
; we go through the `talk`, count number of inverses.
|
||||
; if equal to TextNumberOff, it is our text, printit
|
||||
lda #$ff
|
||||
sta plot4x4color
|
||||
mwa #talk LineAddress4x4
|
||||
jsr _calc_inverse_display
|
||||
; now find length of the text
|
||||
@ iny
|
||||
mwa #talk.talk5_data LineAddress4x4
|
||||
jsr _calc_packed_display
|
||||
; record starts with length byte
|
||||
ldy #0
|
||||
lda (LineAddress4x4),y
|
||||
bpl @-
|
||||
iny
|
||||
sty fx
|
||||
sta fx
|
||||
inw LineAddress4x4 ; point to packed payload
|
||||
mwa tempXROLLER temp ; X coordinate of hitpoint
|
||||
; calculate position of message
|
||||
jsr Calculate4x4TextPosition
|
||||
@@ -436,7 +432,7 @@ nexttext
|
||||
dec LineXdraw+1
|
||||
DisplayMessage
|
||||
; display propaganda message
|
||||
jsr TypeLine4x4.noLengthNoColor
|
||||
jsr TypeLine4x4Packed.noLengthNoColor
|
||||
|
||||
ldy #7
|
||||
jsr PauseYFrames
|
||||
|
||||
Reference in New Issue
Block a user