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

139 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.