Files
c64-demo-cpp/README.md
T
2026-07-18 20:34:55 +02:00

6.4 KiB
Raw Blame History

C64 Demo — Teletype Games slide show (Oscar64)

A Commodore 64 slide show, C-ben, az Oscar64 fordítóval. Az eredetileg 6502 assemblyben (ACME) írt c64-demo portja: öt slide váltakozik automatikusan, slide-onkénti átmenetekkel feketén keresztül, és a show billentyűzetről is vezérelhető.

A slide-ok

  1. TTG logó + credits scroller — óriás TTG betűk 8×8-as bitmapekből, arany színfutással, pulzáló TELETYPE GAMES felirat, sima pixel-scroller a stáblistával.
  2. Az első játékunkDEFINITELY NOT AN IMPOSTOR nagy 3×5-ös blokkbetűkkel, arany wash-sal, „introduced on TIC-80".
  3. A második játékunkIS COMING nagybetűkkel, vetett árnyékkal; a raszterbárok csak a kereten futnak, így a szöveg olvasható marad.
  4. Kapcsolat — pulzáló CONTACT cím, web / BBS / IRC sorok, 12 cellás háromrétegű parallax csillagmező és hat hardveres sprite (négyágú csillagok) szinusz-pályán a szöveg mögött.
  5. Az assembly vallomás — sorkizárt szöveg arról, hogy ez a slide show egy kis AI-segítséggel készült; a törzs élőben gépelődik be (karakterenként egy frame, fehér blokk-kurzorral), a záró sor a gépelés végén jelenik meg és pulzál.

Minden slide 8 másodpercig látszik (SLIDE_TIME a src/defs.h-ban, PAL frame-ekben); az 5-ös slide 9 másodpercet kap (S5_TIME), hogy az írógép végezzen.

Vezérlés

Billentyű Funkció
SPACE következő slide azonnal
INST/DEL (backspace) előző slide
P pause — a visszaszámlálás megáll, fehér P jelző a jobb felső sarokban; az effektek futnak tovább, SPACE/DEL működik
M némítás — a SID zene ki/be

A billentyűket közvetlenül a CIA1 mátrixból olvassuk (a KERNAL IRQ le van tiltva).

Fordítás és futtatás

make build       # fordítás -> build/demo.prg (első futáskor a fordítót is megépíti)
make run         # futtatás VICE emulátorban (x64sc kell hozzá)
make rebuildrun  # tiszta újrafordítás + futtatás
make clean       # build mappa törlése
make deps        # macOS-en: VICE telepítése Homebrew-val

Ugyanezek a .vscode/tasks.json-ból VS Code taskként is futtathatók (a build az alapértelmezett build task).

Betöltés igazi vagy emulált C64-en:

LOAD"*",8,1
RUN

Forrás-elrendezés

Fájl Tartalom
src/main.c főciklus, slide-szekvenszer, billentyűolvasás (SPACE / DEL / P / M), slide-táblák
src/defs.h hardvermutatók, színek, elrendezés/időzítés konstansok, screen code charmap
src/transitions.c átmenet-motor: show/hide, három átmenettípus (fade, dissolve, wipe), wait_frame raszter-szinkron, színsnapshot
src/common.c közös rutinok (clear_screen, print_text, draw_big), közös táblák (sor×40, 3×5 blokkfont, wash/pulse/fade rámpák)
src/music.c SID zenemotor: háromszólamú pattern-lejátszó (basszus, dob, echo lead) az Impostor dallam adataival
src/slide1.cslide5.c slide-onként egy fájl: sN_init (képernyőrajzolás), sN_update (frame-enként egyszer fut) + slide-lokális adatok

A fordítási egységeket az Oscar64 #pragma compile("file.c") mechanizmusa fűzi össze: minden header behúzza a hozzá tartozó .c-t, ezért a make-nek elég a src/main.c-t átadni.

Hogyan működik

Slide-keretrendszer

Minden slide egy init rutinból (megrajzolja a teljes képernyőt), egy update rutinból (frame-enként egyszer hívódik, pontosan egy frame-et fut) és egy frame-ben mért időtartamból áll. A main.c főciklusa hívja az aktuális update-et, számolja vissza a frame-eket, és lejáratkor — vagy SPACE/DEL-re azonnal — a következő slide-ra lép.

Időzítés

Nincs megszakítás: a kód a raszterregisztert ($D012, vic.raster) pollozza, és minden képernyőfrissítést az alsó keretben végez (RAS_BOTTOM). Az 1-es slide ezen felül képközépen megbontja a frame-et, hogy csak a scroller sorára kapcsolja be a vízszintes finomscrollt (vic.ctrl2); a 3-as slide a sugarat üldözve 4 soronként átszínezi a keretet a raszterbárokhoz.

Átmenetek

Minden slide-nak saját be- és kilépő átmenete van (tin_tbl / tout_tbl a main.c-ben), három típusból:

  • Fade — minden color RAM cellát a fadetbl rámpán léptet (minden szín → egy árnyalattal sötétebb; minden lánc legfeljebb 4 lépésben fekete). Az új slide kikapcsolt képernyővel rajzolódik, színei a $C000-es bufferbe mentődnek és feketére váltanak, majd a fade-in cellánként visszasétál a mentett színre.
  • Dissolve — egy 10 bites Galois LFSR (periódus 1023) minden cellát pontosan egyszer, álvéletlen sorrendben jár be. 25 cella/frame = 40 frame (~0,8 s).
  • Wipe — oszloponkénti söprés balról jobbra, oszloponként egy frame.

Minden átmenet rövid fehér-szürke keretvillanással indul.

Zene

A src/music.c háromszólamú SID pattern-lejátszó; a dallam az Impostor TIC-80 cart 0-s trackje („room work"), kézzel konvertálva 128 soros pattern-ráccsá (basszus: 50% pulzus, dob: zaj, echo-kánon: háromszög pluck 3 oktávval feljebb, 2 sorral késleltetve). Egy sor egy bájt szólamonként: $00 = semmi, $01 = key off, $80|n = n. hang. A music_play frame-enként egyszer tickel: a főciklusból és a wait_frame-ből is, így az átmenetek alatt sem áll meg.

Memóriatérkép

$0801 .. ...     BASIC stub + gépi kód (Oscar64 alapértelmezés)
$0340 .. $037E   sprite-alakzat (kazettabuffer, 64-re igazított)
$0400 .. $07E7   képernyő RAM (közvetlen írás)
$C000 .. $C3E7   color RAM snapshot buffer az átmenetekhez
$D000 .. $D02E   VIC-II regiszterek (kép, sprite-ok, raszter)
$D400 .. $D418   SID regiszterek (zene)
$D800 ..         color RAM
$DC00 / $DC01    CIA1 billentyűmátrix

Az eredetihez képest

  • A szövegek a #pragma charmap(97, 1, 26) révén fordítási időben screen code-dá alakulnak, így a C string literálok közvetlenül a képernyőre írhatók.
  • Az önmódosító vektorok és zeropage-mutatók helyett függvénypointerek és normál C tömbindexelés; a viselkedés (időzítés, effektek, zene) megegyezik.
  • A fordítás -n -O2-vel történik (teljes natív 6502 kód), hogy a raszter-pollozó részek elég gyorsak legyenek.