GERLA.CC

tutorial · commodore 64tutorial · commodore 64

Gli sprite del C64, spiegati mettendoli in stradaC64 sprites, explained by putting them on the road

Matteo85 è alle prime esperienze con la grafica sul Commodore 64, e mi ha mandato due disegni: un SUV e una rana. Uno sprite però si capisce molto prima vedendolo muovere che leggendone la definizione, quindi ho fatto la cosa più diretta: in un paio d'ore, in una domenica, li ho messi in strada. È venuto fuori Save The Frogs, il nome gliel'ha dato lui. Questa è la spiegazione che ci è cresciuta intorno. Matteo85 is just starting out with Commodore 64 graphics, and he sent me two drawings: a SUV and a frog. But a sprite is understood far sooner by watching one move than by reading its definition, so I did the most direct thing: in a couple of hours, on a Sunday, I put them on the road. Out came Save The Frogs, and the name is his. This is the explanation that grew around it.

01 · che cos'èwhat it is

Otto disegni che il chip video sposta da soloEight drawings the video chip moves on its own

Su questa macchina uno sprite non è un'immagine che disegni tu sullo schermo: è una cosa che il chip video mette sopra lo sfondo, per conto suo, mentre il pennello elettronico attraversa lo schermo. Tu gli dici dove va, e lui ce lo mette. Lo sfondo sotto non viene toccato, quindi quando l'oggetto si sposta non devi ridisegnare la strada.

On this machine a sprite isn't an image you draw on the screen: it's something the video chip puts over the background, on its own, while the electron beam crosses the screen. You tell it where it goes, and it puts it there. The background underneath is never touched, so when the object moves you don't have to redraw the road.

Questo è il vero motivo per cui gli sprite esistono, e vale la pena dirlo prima di tutto il resto. Su una macchina che fa un milione di operazioni al secondo, cancellare e ridisegnare un'automobile cinquanta volte al secondo si mangerebbe da sola buona parte del tempo. Gli sprite tolgono quel lavoro alla CPU e lo danno a un circuito che lo fa gratis.

That's the real reason sprites exist, and it's worth saying before anything else. On a machine doing a million operations a second, erasing and redrawing a car fifty times a second would eat a good part of the budget on its own. Sprites take that work off the CPU and hand it to a circuit that does it for free.

Gli sprite sono otto. Non nove. È un numero fisso, cablato nel chip, e la maggior parte del mestiere su questa macchina consiste nel far bastare otto cose in movimento.

There are eight sprites. Not nine. It's a fixed number, wired into the chip, and most of the craft on this machine is making eight moving things be enough.

morale: uno sprite non è un disegno, è un disegno più un pezzo di hardware che lo porta in giro. Se ti ricordi solo questo, il resto sono dettagli.

moral: a sprite isn't a drawing, it's a drawing plus a piece of hardware carrying it around. If you remember only this, the rest is detail.

02 · la grigliathe grid

24 per 21, e due modi di riempirla24 by 21, and two ways to fill it

Ogni sprite nasce su una griglia di 24 colonne per 21 righe. Sono misure che sembrano arbitrarie e non lo sono: 24 punti sono esattamente tre byte per riga, e ventuno righe per tre byte fanno 63 byte, che è quasi un blocco tondo di memoria. Torneremo su quel «quasi».

Every sprite is born on a grid of 24 columns by 21 rows. Those look like arbitrary numbers and aren't: 24 points are exactly three bytes per row, and twenty-one rows of three bytes make 63 bytes, which is almost a round block of memory. We'll come back to that "almost".

Quella griglia si può riempire in due modi, e la scelta è per sprite.

That grid can be filled in two ways, and the choice is per sprite.

In alta risoluzione ogni punto è un bit: acceso o spento. Hai la forma più fine che la macchina sappia fare, ma due soli esiti, trasparente oppure il colore assegnato a quello sprite. Un colore. Uno.

In high resolution each point is one bit: on or off. You get the finest shape the machine can make, but only two outcomes, transparent or the colour assigned to that sprite. One colour. One.

In multicolor i bit si leggono a coppie, e ogni coppia fa un punto largo il doppio. Le combinazioni sono quattro, e qui sta tutto il senso della modalità:

In multicolor the bits are read in pairs, and each pair makes a point that's twice as wide. There are four combinations, and that's where the whole point of the mode lies:

00 trasparente, si vede lo sfondo 01 colore comune 1 ($d025) uguale per TUTTI gli sprite 10 colore dello sprite ($d027 + n) suo, e solo suo 11 colore comune 2 ($d026) uguale per TUTTI gli sprite
le quattro combinazioni della modalità multicolorthe four multicolor combinations

Quindi non è «quattro colori a scelta libera»: è un colore tuo più due presi in prestito da tutti, più la trasparenza. Se cambi il comune 1 per far contenta la rana, lo cambi anche al SUV. È un vincolo che decide come si disegna, e che non si aggira: si progetta intorno.

So it isn't "four colours of your choosing": it's one colour of your own plus two borrowed from everybody, plus transparency. If you change shared colour 1 to please the frog, you change it for the SUV too. It's a constraint that decides how you draw, and it can't be dodged: you design around it.

E si paga: i punti sono larghi il doppio, quindi in orizzontale sono dodici, non ventiquattro. Le forme vengono a blocchi. Matteo ha scelto il multicolor, ed è la scelta giusta per questi due soggetti: con un colore solo, un SUV che deve avere carrozzeria, vetri e ruote diventa una sagoma.

And you pay for it: the points are twice as wide, so across you have twelve, not twenty-four. Shapes come out blocky. Matteo chose multicolor, and it's the right choice for these two subjects: with a single colour, a SUV that needs bodywork, windows and wheels turns into a silhouette.

La griglia 24 per 21 dei tre sprite di Save The Frogs

i tre sprite sulla griglia vera. Si vedono i punti larghi il doppio, e si vede che il SUV occupa due griglie e la rana una. the three sprites on the real grid. You can see the double-width points, and that the SUV takes two grids while the frog takes one.

03 · i datithe data

63 byte usati, 64 occupati, e un puntatore63 bytes used, 64 taken, and a pointer

Il disegno finisce in memoria come una sequenza piatta: tre byte per riga, ventuno righe, in ordine dall'alto in basso. Sessantatré byte. Il chip però non va a prendersi i dati a un indirizzo qualunque: legge un puntatore, un numero solo, e lo moltiplica per 64. Ecco il «quasi» di prima: i blocchi sono da 64, il disegno ne usa 63, e il sessantaquattresimo byte è lì e non serve a niente.

The drawing ends up in memory as a flat sequence: three bytes per row, twenty-one rows, top to bottom. Sixty-three bytes. But the chip doesn't fetch the data from an arbitrary address: it reads a pointer, a single number, and multiplies it by 64. That's the "almost" from before: blocks are 64 bytes, the drawing uses 63, and the sixty-fourth byte sits there doing nothing.

; il puntatore sta negli ultimi 8 byte della memoria dello schermo ; indirizzo dei dati = puntatore x 64 lda #$0d ; 13 x 64 = $0340 sta $07f8 ; sprite 0 -> disegna quello che c'e' a $0340 ; dove va, e di che colore e' lda #172 sta $d000 ; sprite 0, colonna lda #180 sta $d001 ; sprite 0, riga lda #%00000001 sta $d015 ; accendi lo sprite 0 sta $d01c ; ...e leggilo in multicolor
accendere uno sprite, dall'inizioswitching on a sprite, from scratch

Il vantaggio di quel puntatore è che cambiare disegno costa una scrittura sola. Un'animazione non sposta byte: cambia un numero, e al quadro dopo lo sprite è un altro disegno. Nel gioco è così che la rana schiacciata diventa una rana schiacciata.

The advantage of that pointer is that changing the drawing costs a single write. An animation doesn't move bytes: it changes one number, and on the next frame the sprite is a different drawing. In the game, that's how a run-over frog becomes a run-over frog.

morale: sul C64 le animazioni sono economiche e la memoria è cara. Tutti i quadri stanno già lì, e quello che si muove è il dito che li indica.

moral: on the C64 animations are cheap and memory is dear. All the frames are already there, and what moves is the finger pointing at them.

04 · metterne dueusing two

Perché il SUV sono due sprite sovrappostiWhy the SUV is two overlapping sprites

Ventiquattro punti di larghezza, che in multicolor diventano dodici, sono pochi per un'automobile vista da sopra che deve leggersi come un'automobile. E soprattutto un colore proprio per sprite è poco: la carrozzeria se lo prende, e per i vetri restano solo i due colori comuni.

Twenty-four points wide, which in multicolor becomes twelve, is little for a car seen from above that has to read as a car. And above all one colour per sprite is little: the bodywork takes it, and only the two shared colours are left for the windows.

La via d'uscita classica è metterne due, uno sopra l'altro, alla stessa posizione. Costa un secondo sprite su otto, ma raddoppia i colori propri, perché ognuno dei due porta il suo. Il SUV è fatto così, la rana no: le basta uno.

The classic way out is to use two, one on top of the other, at the same position. It costs a second sprite out of eight, but it doubles the colours you own, because each of the two brings its own. The SUV is built that way, the frog isn't: one is enough for it.

Ed è qui che il numero otto comincia a pesare. Due li ha già presi il SUV, quindi per le rane in strada ne restano sei. Non è un limite teorico: è la ragione per cui il gioco ha quel numero di rane e non il doppio.

And this is where the number eight starts to bite. The SUV has already taken two, so six are left for the frogs on the road. It isn't a theoretical limit: it's the reason the game has that many frogs and not twice as many.

05 · l'ombrathe shadow

Non disegnata: calcolataNot drawn: computed

Le ombre sotto il SUV e sotto la rana non le ha disegnate nessuno. Le tira fuori una routine che gira prima del gioco, sul computer, e che fa una cosa sola: per ogni punto pieno del disegno guarda la posizione spostata di uno in basso e uno a destra, e se lì c'è trasparenza ci mette un punto nero.

The shadows under the SUV and under the frog weren't drawn by anyone. They come out of a routine that runs before the game, on the computer, and does one thing only: for every filled point in the drawing it looks at the position one down and one to the right, and if there's transparency there it puts a black point.

per ogni punto (x, y) del disegno: se il punto e' pieno: se il punto (x+1, y+1) e' trasparente: metti nero in (x+1, y+1)
tutta l'ombra, in quattro righethe whole shadow, in four lines

Quattro righe, e il risultato è che i due soggetti smettono di stare appiccicati all'asfalto. È il tipo di trucco che mi piace far vedere a chi comincia, perché ribalta l'idea di partenza: non tutto quello che si vede va disegnato. Una parte si scrive, e la scrive il programma.

Four lines, and the result is that the two subjects stop looking glued to the asphalt. It's the kind of trick I like showing to someone starting out, because it turns the starting idea on its head: not everything you see has to be drawn. Some of it gets written, and the program writes it.

C'è un motivo pratico in più. L'ombra calcolata resta giusta se Matteo cambia il disegno: ridisegna il SUV, rilancia la conversione, e l'ombra nuova esce da sola. Un'ombra disegnata a mano invece si scollega dal disegno alla prima modifica, e non se ne accorge nessuno finché non si guarda con attenzione.

There's a further practical reason. A computed shadow stays right if Matteo changes the drawing: he redraws the SUV, reruns the conversion, and the new shadow comes out on its own. A hand-drawn shadow instead comes unstuck from the drawing at the first change, and nobody notices until they look closely.

06 · muoverlomoving it

Il disegno non sa sterzareThe drawing doesn't know how to steer

Uno sprite acceso e fermo è ancora soltanto un disegno. La posizione sono due numeri in due registri, e muoverlo vuol dire scrivere in quei registri. Il comportamento, cioè il fatto che vada a destra quando spingi a destra, non c'è: lo scrivi tu.

A sprite switched on and standing still is still only a drawing. Its position is two numbers in two registers, and moving it means writing into those registers. Behaviour, the fact that it goes right when you push right, isn't there: you write it.

lda $dc00 ; leggi il joystick and #%00001000 ; il bit della destra: 0 = premuto bne fine lda $d000 ; colonna dello sprite 0 clc adc #2 ; spingila di due sta $d000 fine:
leggi, decidi, scrivi: e questo e' tutto il movimentoread, decide, write: and that's all the movement there is

C'è una trappola in agguato, ed è la prima in cui inciampano tutti. Il registro della colonna è di un byte, quindi arriva a 255, ma lo schermo è più largo. I bit che mancano stanno tutti insieme in un altro registro, uno per sprite: se lo dimentichi, il tuo oggetto arriva a metà schermo e si teletrasporta a sinistra. Non è un difetto del tuo codice, è il nono bit che non hai scritto.

There's a trap waiting, and it's the first one everybody falls into. The column register is one byte, so it goes up to 255, but the screen is wider. The missing bits all live together in another register, one bit per sprite: if you forget it, your object gets to the middle of the screen and teleports to the left. It isn't a fault in your code, it's the ninth bit you didn't write.

07 · quello che NON è uno spritewhat is NOT a sprite

La strada è fatta di caratteriThe road is made of characters

Guardando il gioco sembra che il SUV corra. Non corre: resta quasi alla stessa altezza, ed è la strada che gli scorre sotto come un tappeto mobile. E la strada non è uno sprite, perché non potrebbe esserlo: gli sprite sono otto e sono piccoli.

Watching the game it looks like the SUV is racing. It isn't: it stays at almost the same height, and it's the road that slides underneath it like a moving carpet. And the road isn't a sprite, because it couldn't be: sprites are eight, and small.

La pista è una tabella di righe. Ogni voce dice dove stanno i bordi e che fascia di colore usare, e il programma legge una voce, sceglie i tasselli, li scrive nella memoria dello schermo e passa alla riga dopo. Fuori dalla carreggiata erba, ai lati guardrail e cordoli, al centro asfalto e mezzeria discontinua. Sono caratteri, cioè pezzetti da otto per otto ridisegnati una volta e riusati ovunque.

The track is a table of rows. Each entry says where the edges are and which colour band to use, and the program reads an entry, picks the tiles, writes them into screen memory and moves to the next row. Off the carriageway grass, at the sides guardrails and kerbs, in the middle asphalt and a broken centre line. They're characters, that is eight-by-eight pieces redrawn once and reused everywhere.

Le curve vengono a gradini, e non è un difetto: è la conseguenza visibile di quella scelta. Riusare tasselli costa molto meno che ridisegnare ogni punto, e su questa macchina il prezzo lo paghi in aspetto, non in tempo.

The curves come out stepped, and that isn't a flaw: it's the visible consequence of that choice. Reusing tiles costs far less than redrawing every point, and on this machine you pay the price in looks, not in time.

Save The Frogs in esecuzione: la strada, i bordi, la mezzeria e il pannello dei punteggi

tutto quello che si vede qui, tranne il SUV, è fatto di caratteri: l'erba, i cordoli, l'asfalto, la mezzeria a tratti e il pannello dei punteggi in alto. Gli sprite sono due, e sono l'automobile. everything visible here except the SUV is made of characters: the grass, the kerbs, the asphalt, the broken centre line and the score panel at the top. There are two sprites, and they're the car.

morale: la regola pratica è questa. Sprite per le poche cose che si muovono da sole; caratteri per tutto il resto, compreso quello che sembra muoversi ma in realtà scorre. Sbagliare questa divisione è il modo più veloce per restare senza macchina.

moral: the practical rule is this. Sprites for the few things that move by themselves; characters for everything else, including what looks like it's moving but is really scrolling. Getting that split wrong is the fastest way to run out of machine.

08 · gli urticollisions

Il chip te lo dice, ma non abbastanzaThe chip tells you, but not enough

Il chip video sa fare da solo una cosa comoda: si accorge quando due sprite si toccano, o quando uno sprite tocca lo sfondo, e lo scrive in due registri. Sembra la risposta a tutto, e per un gioco come questo non lo è.

The video chip can do one handy thing on its own: it notices when two sprites touch, or when a sprite touches the background, and it writes that into two registers. It looks like the answer to everything, and for a game like this one it isn't.

Il registro ti dice quali sprite sono coinvolti, ma non dove, e soprattutto si azzera quando lo leggi: se lo leggi due volte nello stesso giro, la seconda volta l'urto non è mai successo. Poi il chip considera contatto qualunque punto non trasparente che si sovrappone, ombra compresa. Un'ombra che sfiora una rana non è un investimento.

The register tells you which sprites are involved, but not where, and above all it clears itself when you read it: read it twice in the same pass and the second time the collision never happened. On top of that the chip counts as contact any non-transparent point that overlaps, shadow included. A shadow brushing a frog isn't running it over.

Quindi nel gioco l'urto non lo chiedo al chip: lo calcolo. Il programma sa dove sono le cose, confronta la riga della rana con quella dell'auto e poi la distanza in orizzontale, e se è sotto una certa soglia considera avvenuto l'investimento. Non è una simulazione fisica, ed è meglio così: i risultati devono essere prevedibili per chi gioca, non fedeli alla realtà. Una soglia in numeri la puoi allargare o stringere finché il gioco non è giusto; il registro del chip non si può regolare.

So in the game I don't ask the chip about collisions: I compute them. The program knows where things are, compares the frog's row with the car's and then the horizontal distance, and if it's under a certain threshold it counts the hit. It isn't a physics simulation, and that's better: results have to be predictable for the player, not faithful to reality. A threshold in numbers can be widened or tightened until the game feels right; the chip's register can't be tuned.

in sintesiin short

Cosa resta, se resta una cosa solaWhat sticks, if only one thing does

Uno sprite è un disegno da 24 per 21 che un circuito ti porta in giro gratis, ne hai otto, e ognuno ha un colore suo più due presi in prestito da tutti. Tutto il resto della schermata sono caratteri. Il disegno non sa sterzare, non sa cadere e non sa morire: quello lo scrive il programma, e il programma è la parte in cui un disegno diventa un gioco.

A sprite is a 24 by 21 drawing that a circuit carries around for you for free, you get eight, and each has a colour of its own plus two borrowed from everybody. Everything else on screen is characters. The drawing doesn't know how to steer, or fall, or die: the program writes that, and the program is the part where a drawing becomes a game.

Save The Frogs è nato in un paio d'ore e si vede: è una corsa senza fine, tre vite, punti che salgono con la velocità, e nessun traguardo. Non doveva essere altro. Serviva a rispondere a una domanda concreta, i miei disegni funzionano?, e la risposta si dà più in fretta facendoli girare che spiegandoli.

Save The Frogs was born in a couple of hours and it shows: an endless run, three lives, points that climb with speed, and no finish line. It was never meant to be anything else. It was there to answer a concrete question, do my drawings work?, and that answer comes faster by running them than by explaining them.

Otto minuti, dal disegno al giocoEight minutes, from drawing to game

Se preferisci sentirtelo raccontare, tutto quello che c'è qui sopra sta anche in un video: gli sprite, la strada, il ciclo di gioco, gli urti, i menu e il difetto di scorrimento che ho dovuto sistemare. If you'd rather be told it, everything above is also in a video: the sprites, the road, the game loop, collisions, the menus and the scrolling fault I had to fix.

i sottotitoli si accendono dal menu del lettore, il fumetto in basso a destra: non partono da soli. subtitles can be switched on from the player menu, the speech bubble at the bottom right: they don't start on their own.

savethefrogs.prg

14 KB · Commodore 64 · si carica in VICE o su macchina vera14 KB · Commodore 64 · loads in VICE or on real hardware
si carica a $0801 e parte conloads at $0801 and starts with RUN

Scarica il PRGDownload the PRG

Crediti. Game design e grafica degli sprite: Matteo85, che ha anche dato il nome al test. La programmazione è mia. Credits. Game design and sprite graphics: Matteo85, who also named the test. The programming is mine.

← Tutti i tutorial← All tutorials Il C64 su questo sito →The C64 on this site →