# C64 Demo — Teletype Games slide show (Oscar64) A Commodore 64 slide show, C-ben, az [Oscar64](https://github.com/drmortalwombat/oscar64) fordítóval. Az eredetileg 6502 assemblyben (ACME) írt [c64-demo](../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ékunk** — *DEFINITELY NOT AN IMPOSTOR* nagy 3×5-ös blokkbetűkkel, arany wash-sal, „introduced on TIC-80". 3. **A második játékunk** — *IS 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 ```sh 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.c` … `slide5.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.