Autore Topic: Sprites, In Linguaggio Macchina...  (Letto 9942 volte)

djwiper

  • Utente
  • **
  • Post: 197
  • Gioco Preferito: Sim City
Sprites, In Linguaggio Macchina...
« il: 25 Luglio 2004, 11:38:16 »
 Se non ricordo male mediante basic si potevano gestire fino a 7 sprites (o forse erano 8?). Ai tempi in cui possedevo un commodore mi pare di aver modificato il famoso listato basic della mongolfiera marchiata C=, presente nel manuale per far si che ne apparissero 7 (o 8?). Ma in linguaggio macchina si possono "muovere" più sprites rispetto a quanti se ne possono gestire con il BASIC, giusto? Dico questo perchè alcuni giochi, tra personaggi e altri oggetti moventi, arrivano tranquillamente ad una ventina di sprites. O forse si utilizza qualche espediente e il numero di sprites rimane fisso a 7 (o 8?)?

Un'altra cosa per evitare di aprire un nuovo topic:

Ma il colore di trasparenza, ossia quello che fa "fondere" lo sprites con il fondo qual'è? Nonostante abbia letto i doc a riguardo non ho ancora capito. Se ho uno sprites: (facciamo finta che row e colums siano correti in numero)

****
*  
*  
****

qual'è l'equivalente colore del cancelletto?

####
****#
*###  
*###  
****#
####

Spero di non aver scritto in arabo...  
Ho capito di odiare le firme...

Alberto

  • Utente
  • **
  • Post: 589
  • Gioco Preferito: Grand Prix Circuit
Sprites, In Linguaggio Macchina...
« Risposta #1 il: 25 Luglio 2004, 11:54:31 »
 Ciao e ben tornato :)
Citazione
forse si utilizza qualche espediente e il numero di sprites rimane fisso a 7 (o 8?)?
Sia in basic che in LM si possono gestire fino a 8 sprite (limite fisico del chip video).
Tuttavia,gestendo adeguatamente gli interrupt del raster (il fascio di elettroni che disegna lo schermo 50 volte al secondo in un C64 PAL,60 volte al secondo in un C64 NTSC) è possibile "ingannare" il VIC,ottenendo più di 8 sprite in una stessa schermata.
Ad esempio,compila questo sorgente e lancia l'eseguibile con una SYS 49152
Codice: [Seleziona]
* = $c000

          SEI
          JSR INIT      ; inizializza sprites
          LDA #< IRQ
          STA $0314
          LDA #> IRQ
          STA $0315    ; setta vettore di interruzione
          LDA #$01
          STA $D01A
          LDA $D011
          AND #$7F
          STA $D011
          LDA #$32
          STA $D012    ; abilita prima interruzione del raster
                            ; alla riga 50
          CLI
          RTS

INIT      LDA #$00
          STA $FB      ; inizializza contatore                  
          LDA #$FF
          LDX #$00
STORE     STA $02C0,X
          INX
          CPX #$3F
          BNE STORE    ; setta la forma degli sprite
          LDA #$0B
          LDX #$00
POINTER   STA $07F8,X
          INX
          CPX #$08
          BNE POINTER  ; setta i puntatori agli sprite
          LDY #$00
          LDX #$00
SETX      LDA XCOORD,Y
          STA $D000,X
          INX
          INX
          INY
          CPY #$08
          BNE SETX      ; setta coordinata X
          LDX #$00
          LDA #$40
SETY      STA $D001,X
          INX
          INX
          CPX #$10
          BNE SETY      ; setta coordinata Y
          LDA #$00
          STA $D010    ; setta coordinata X di pagina 1
          LDA #$07
          LDX #$00
FILL      STA $D027,X
          INX
          CPX #$08
          BNE FILL      ; colora gli sprite di giallo
          LDA #$FF
          STA $D015    ; visualizza gli sprite
          RTS

IRQ       LDA $91
          BPL RESET    ; [RUN-STOP] premuto,esci
          LDA $D019
          STA $D019    ; sblocca il registro per le interruzioni s
                            ; successive
          AND #$01
          BEQ EXIT      ; se interruzione non del raster,esce
          LDX $FB
          LDA YCOORD,X
          STA $D001
          STA $D003
          STA $D005
          STA $D007
          STA $D009
          STA $D00B
          STA $D00D
          STA $D00F    ; cambia l'ordinata degli sprite    
          LDA RASTER,X
          CPX #$03
          BNE CONT
          LDX #$FF
CONT      INX
          STX $FB      ; aggiorna/resetta contatore
          STA $D012    ; setta la prossima linea di raster
          LDA $D011
          AND #$7F
          STA $D011
          JMP $EA31    ; salta alla normale routine di IRQ                   
EXIT      JMP $FEBC    ; torna dall'interruzione  
RESET     JMP $FE66                

;*** LINEE DI INTERRUZIONE DEL RASTER ***

RASTER .BYTE $63,$95,$C7,$32

;*** COORDINATE SPRITES ***

XCOORD .BYTE $18,$34,$50,$6C,$88,$A4,$C0,$DC  ; X
YCOORD .BYTE $40,$72,$A4,$D6              ; Y
Questa routine sfrutta gli interrupt del raster per visualizzare a schermo 32 sprite in contemporanea. :)
Citazione
Ma il colore di trasparenza, ossia quello che fa "fondere" lo sprites con il fondo qual'è?
E' il colore del fondo stesso (quello contenuto nella locazione 53281).

P.S.:Se qualcuno ha domande da porre sul listato,non esiti ;)
Bye

MarC=ello

  • Utente
  • **
  • Post: 337
  • Gioco Preferito: CBM BASIC 2.0
Sprites, In Linguaggio Macchina...
« Risposta #2 il: 25 Luglio 2004, 12:01:46 »
 
Citazione
LDA $D019
         STA $D019    ; sblocca il registro per le interruzioni successive
         AND #$01

Forse ho capito...

io sono abituato a sbloccare il latch in un altro punto del programma e a controllare in un altro momento se l'interruzione è del raster oppure no... ma è lo stesso anche come fai tu ;)  
-=MarC=ellO=-

Alberto

  • Utente
  • **
  • Post: 589
  • Gioco Preferito: Grand Prix Circuit
Sprites, In Linguaggio Macchina...
« Risposta #3 il: 25 Luglio 2004, 12:06:17 »
 
No,non è sbagliato,perchè si vuole sbloccare il registro $D019 per avere altri interrupt,e poi si vede se si è verificato un interrupt del raster.  

Roberto

  • Administrator
  • Utente
  • *****
  • Post: 2431
    • https://ready64.org
  • Gioco Preferito: Impossible Mission
Sprites, In Linguaggio Macchina...
« Risposta #4 il: 25 Luglio 2004, 12:14:43 »
 
Citazione
e non ricordo male mediante basic si potevano gestire fino a 7 sprites (o forse erano 8?). Ai tempi in cui possedevo un commodore mi pare di aver modificato il famoso listato basic della mongolfiera marchiata C=, presente nel manuale per far si che ne apparissero 7 (o 8?). Ma in linguaggio macchina si possono "muovere" più sprites rispetto a quanti se ne possono gestire con il BASIC, giusto? Dico questo perchè alcuni giochi, tra personaggi e altri oggetti moventi, arrivano tranquillamente ad una ventina di sprites. O forse si utilizza qualche espediente e il numero di sprites rimane fisso a 7 (o 8?)?

Il Commodore 64 riesce a gestire graficamente 8 Sprites alla volta. Quindi più di 8 allo stesso tempo sullo schermo non se ne possono mostrare.
Con l'evoluzione delle tecniche di programmazione però, è stato creato un nuovo metodo di gestire gli sprite, che si chiama Multiplexing.
Con il multiplexing si possono gestire un numero molto superiore di sprite adottando un semplice trucchetto che consiste nell' "accendere e spegnere" molto velocemente 8 sprites alla volta.
In questo modo, l'occhio umano viene ingannato facendogli credere che sullo schermo siano presenti più di otto oggetti nello stesso tempo, cosa effettivamente non vera :)

Citazione
Ma il colore di trasparenza, ossia quello che fa "fondere" lo sprites con il fondo qual'è? Nonostante abbia letto i doc a riguardo non ho ancora capito. Se ho uno sprites: (facciamo finta che row e colums siano correti in numero)

In modo multicolor, ogni sprite può utilizzare 4 colori.
I colori li decidi tutti tu, ma con alcune limitazioni.
In particolare, i colori 1 e 2 sono gli stessi per TUTTI gli sprites, vale a dire che se tu cambi il colore 1 o 2, questo cambiamento ha effetto su tutti gli sprites.
Poi c'è il "colore custom" che può essere uno qualsiasi dei 16 che la palette del C64 ti mette a disposizione, e varia da sprite a sprite.
Per imparare non c'è niente di meglio che cominciare a 'smanettare' con uno sprite editor. Prova e persevera, vedrai che dopo un pò ti sarà tutto chiaro.
Per collaborare, segnalare un errore (o qualsiasi altra comunicazione importante) utilizzare la pagina dei contatti:
https://ready64.org/informazioni/contatti.php

djwiper

  • Utente
  • **
  • Post: 197
  • Gioco Preferito: Sim City
Sprites, In Linguaggio Macchina...
« Risposta #5 il: 25 Luglio 2004, 12:40:22 »
 
Citazione
Ad esempio,compila questo sorgente e lancia l'eseguibile con una SYS 49152
Lo farò senz'altro, prima però vorrei approfondire l'argomento sul rasterbeam che mi incuriosisce molto e di cui sono "bianco" allo stato attuale. Una domanda sul sorgente mi permetto di fartela:

Codice: [Seleziona]
JSR INIT     ; inizializza sprites

JSR sarebbe l'equivalente x86 di JMP, giusto? Cioè "salta" alla label INIT, la quale

Citazione
INIT      LDA #$00
         STA $FB      ; inizializza contatore                   
         LDA #$FF
         LDX #$00

Dopo aver eseguito i quattro i comandi (LDA, STA, LDA, LDX) che fa?
Non dovrebbe tornare alla linea immediatamente successiva a JSR INIT? Si può omettere l'equivalente x86 RET per il ritorno dal salto non condizionale?

Poi, immediatamente dopo la linea JSR INIT abbiamo

Citazione
LDA #< IRQ
Non ci arrivo proprio... :( Vuol forse dire "Carica nell'accumulatore A il valore restituito dalla funzione (?) IRQ?" In quel caso la label IRQ sarebbe una funzione che restituisce un valore? Anche così non avrebbe senso poichè l'operatore < e successivamente quello > non riuscirei a spiegarli...

E per quanto riguarda la parte teorica ho finito, passiamo a Roberto :)

Citazione
Con l'evoluzione delle tecniche di programmazione però, è stato creato un nuovo metodo di gestire gli sprite, che si chiama Multiplexing.
Un pò come accade nei vecchi display LCD "multiplexati" se ho ben capito. Quelli cioè delle calcolatrici a, ad esempio, dieci cifre che invece di tenere settanta segmenti teoricamente accesi o spenti ne "multiplexavano" una piccola parte (di solito quattro-cinque) mediante un oscillatore al quarzo che "ingannava" l'occhio umano? Se fosse così ho capito il funzionamento

Come al solito grazie ragazzi :D
Ho capito di odiare le firme...

Alberto

  • Utente
  • **
  • Post: 589
  • Gioco Preferito: Grand Prix Circuit
Sprites, In Linguaggio Macchina...
« Risposta #6 il: 25 Luglio 2004, 12:47:05 »
 
Citazione
più di 8 allo stesso tempo sullo schermo non se ne possono mostrare.
Con l'evoluzione delle tecniche di programmazione però, è stato creato un nuovo metodo di gestire gli sprite, che si chiama Multiplexing.
Con il multiplexing si possono gestire un numero molto superiore di sprite adottando un semplice trucchetto che consiste nell' "accendere e spegnere" molto velocemente 8 sprites alla volta.
In questo modo, l'occhio umano viene ingannato facendogli credere che sullo schermo siano presenti più di otto oggetti nello stesso tempo, cosa effettivamente non vera 
Non è un'illusione ottica.
Nel multiplexing gli sprite sullo schermo sono effettivamente più di 8.
Ad esempio,nella routine postata il fascio del raster provoca un'interruzione alle righe 50,99,149,199.
Arrivato a ciascuna di queste righe,viene cambiata l'ordinata degli sprite,in modo che il raster disegni 8 sprite in ciascuna delle 4 porzioni in cui viene diviso il video.

Alberto

  • Utente
  • **
  • Post: 589
  • Gioco Preferito: Grand Prix Circuit
Sprites, In Linguaggio Macchina...
« Risposta #7 il: 25 Luglio 2004, 13:01:27 »
 Innanzitutto,ho apportato alcune piccole modifiche al sorgente,quindi ti/vi prego di copiare/incollare quello attualmente presente. ;)

Citazione
Dopo aver eseguito i quattro i comandi (LDA, STA, LDA, LDX) che fa?

Disegna 8 rettangoli,li colora tutti di giallo e ne setta le coordinate di partenza.

Citazione
Non dovrebbe tornare alla linea immediatamente successiva a JSR INIT? Si può omettere l'equivalente x86 RET per il ritorno dal salto non condizionale?

Esatto,costruisce gli sprite e poi l'esecuzione riprende dall'istruzione successiva alla JSR INIT.

Citazione
Non ci arrivo proprio...  Vuol forse dire "Carica nell'accumulatore A il valore restituito dalla funzione (?) IRQ?" In quel caso la label IRQ sarebbe una funzione che restituisce un valore? Anche così non avrebbe senso poichè l'operatore < e successivamente quello > non riuscirei a spiegarli...

LDA #IRQ "carica nell'accumulatore il byte alto dell'indirizzo di partenza di IRQ".

MarC=ello

  • Utente
  • **
  • Post: 337
  • Gioco Preferito: CBM BASIC 2.0
Sprites, In Linguaggio Macchina...
« Risposta #8 il: 25 Luglio 2004, 13:14:19 »
 Ciao a tutti,

x Alberto: ah, forse ho capito come hai fatto... io usavo un altro metodo... ma sia come faccio io o come fai te credo sia la stessa cosa, per cui dietrofront! ;)

Evito di rispondere riguardo a domande specifiche sul codice, visto che lo ha postato Alberto e potrei non averne compreso alcune parti (ognuno ha il suo stile di programmazione).

Attenzione a non confondere il multiplexing con la tecnica generica delle interruzioni del raster, sono due cose differenti.

Vediamo un attimo come funge il raster.

Lo schermo, nei sistemi PAL (cioè quelli che usiamo noi), viene aggiornato 50 volte al secondo. Questo aggiornamento viene fatto da un fascio di elettroni, che fa in modo che vengano accesi i pixel opportuni su ciascuna linea di scansione (eccitando i fosfori).

********************* 1a linea
********************* 2a linea

queste linee vengono visualizzate dall'alto verso il basso, e poi il processo ricomincia da capo. Il fascio di elettroni percorre ciascuna linea da sinistra a destra.
Giunto all'ultima linea, il fascio riprende la sua scansione dalla prima in alto.

Il raster è un termine che indica diverse cose:

- lo schermo raster: è lo schermo diviso in linee di scansione.
- il raster (abbreviazione di rasterbeam) = pennello elettronico.
- raster (nel senso di raster interrupt) = interruzione del raster.

Un'interruzione del raster viene generata dal VIC-II quando il rasterbeam si trova in una certa linea di scansione. Nel C64 PAL, le linee di scansione vanno da 0 a 312 (quelle visibili da 50 a 250, le non visibili corrispondono al bordo).

Il registro del raster (in realtà sono due perché l'informazione è a 9 bit, ma tralasciamo questo aspetto) indica la posizione corrente del raster. Inoltre, scrivendo su questo stesso registro, viene impostato il valore al quale avverrà l'interruzione del raster.

Per esempio, se voglio dividere lo schermo in due parti, in modo che in mezzo schermo il bordo sia rosso e nell'altro mezzo bianco, devo generare due interruzioni del raster (una a metà dello schermo - impostando di conseguenza il registro alla opportuna linea di scansione) e una in cima allo schermo (linea di scansione 0).

Analogamente, se voglio rappresentare più di 8 sprite sullo schermo, basta che io generi ad esempio 4 interruzioni del raster, dividendo così lo schermo in quattro file:

************** interruzione 1
8 sprite
...
*************** interruzione 2
8 sprite

***************
ecc...

In questo modo, si spostano gli sprite da una fila all'altra quando avviene l'interruzione. L'interruzione avviene quando gli sprite della fila di sopra sono già stati disegnati... e così posso spostare gli sprite nella fila di sotto (cioè la fila corrispondente alla linea di scansione nella quale è avvenuta l'interruzione corrente) senza che chi guarda se ne accorga.

Il multiplexing consiste nell'alternare UNO STESSO sprite in una stessa "fila" (cioè in corrispondenza delle stesse linee di scansione). Ad esempio, nella zona dalla linea di scansione 50 alla 75, per dire, potrei visualizzare non più di 8 sprite... e le interruzioni del raster, intese nel senso di prima, non mi sarebbero utili.

Ma io dispongo di 50 fotogrammi al secondo... e posso rappresentare lo sprite 1 (per dire) nella posizione x = 50 nel fotogramma 1 e nella posizione X = 120 nel fotogramma 2. In questo modo, pena un po' di sfarfallio, pur avendo un solo sprite riesco a farne vedere due... in corrispondenza delle stesse linee di scansione.

Combinando i due effetti si possono visualizzare anche 50 sprite.

Ovviamente, per fare il multiplexing servono le interruzioni del raster, ma stavolta l'obiettivo è quello di alternare due fotogrammi, non di dividere lo schermo in più parti.

Scusate la sciatteria nel trattare le tematiche, ma se riuscirò a completare il "corso semiserio di assembler" tratterò meglio questi argomenti e porterò degli esempi.

Ciao!

 
-=MarC=ellO=-

Roberto

  • Administrator
  • Utente
  • *****
  • Post: 2431
    • https://ready64.org
  • Gioco Preferito: Impossible Mission
Sprites, In Linguaggio Macchina...
« Risposta #9 il: 25 Luglio 2004, 13:20:41 »
 Ops :stordita:  
Per collaborare, segnalare un errore (o qualsiasi altra comunicazione importante) utilizzare la pagina dei contatti:
https://ready64.org/informazioni/contatti.php

Alberto

  • Utente
  • **
  • Post: 589
  • Gioco Preferito: Grand Prix Circuit
Sprites, In Linguaggio Macchina...
« Risposta #10 il: 25 Luglio 2004, 14:32:10 »
 Per chi fosse interessato,un piccolo esercizio:

come avrete notato,la velocità di ripetizione del cursore risulta accelerata (domanda:perchè?).
Modificate il listato in modo da riportare il blink a velocità normale  ;)

Bye

Alberto

  • Utente
  • **
  • Post: 589
  • Gioco Preferito: Grand Prix Circuit
Sprites, In Linguaggio Macchina...
« Risposta #11 il: 25 Luglio 2004, 16:37:08 »
 
Citazione
Ma io dispongo di 50 fotogrammi al secondo... e posso rappresentare lo sprite 1 (per dire) nella posizione x = 50 nel fotogramma 1 e nella posizione X = 120 nel fotogramma 2. In questo modo, pena un po' di sfarfallio, pur avendo un solo sprite riesco a farne vedere due... in corrispondenza delle stesse linee di scansione.

Però,facendo così l'effetto a schermo è abbastanza schifido:50 hz sono una frequenza video troppo bassa per creare l'effetto di più di 8 sprite su una sola riga di raster.
 

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Sprites, In Linguaggio Macchina...
« Risposta #12 il: 25 Luglio 2004, 16:39:43 »
 
Citazione
JSR sarebbe l'equivalente x86 di JMP, giusto? Cioè "salta"
No JMP e' JMP in entrambi i processori. Salto incondizionato e senza ritorno.
JSR e' Jump to Subroutine and Return. Si memorizza nello stack l'indirizzo dell'istruzione successiva alla JSR, salta al nuovo indirizzo e appena si incontra RTS ritorna all'inidirizzo memorizzato sullo stack, continuando di fatto dalla istruzione successiva alla JSR.
Leggiti bene il capitolo 5 della guida di rifermento che trovi sul sito, ogni istruzione 6502 e' spiegata per filo e per segno ;)
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -

djwiper

  • Utente
  • **
  • Post: 197
  • Gioco Preferito: Sim City
Sprites, In Linguaggio Macchina...
« Risposta #13 il: 25 Luglio 2004, 16:47:11 »
 iAN, hai proprio ragione! Piccolo erroe confusionario
Leggerò sicuramente la guida, anze LE guide visto che me ne mancano alcune...

Ritornando al discorso degli sprites credo di averlo capito. Per caso può interessare anche altre macchine, come ad esempio il nintendo (sebbene abbia il chip 6510 come cpu) o il supernintendo? In casi di particolare confusione, alcuni giochi di tali piattaforme rallentano e scompaiono temporaneamente alcuni sprites. Forse è una cosa che non centra proprio nulla?
Ho capito di odiare le firme...

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Sprites, In Linguaggio Macchina...
« Risposta #14 il: 25 Luglio 2004, 16:49:51 »
 
Citazione
Non è un'illusione ottica.
Nel multiplexing gli sprite sullo schermo sono effettivamente più di 8.
mha, io direi piuttosto che, dato che non ci possono essere piu' di 8 sprites HARDWARE, gli sprites sono sempre 8 ma la temporizzazione fa in modo che il raster non riesca a tornare in cima e ridisegnare lo schermo, facendo vedere che lo sprite e' stato spostato. E' solo e comunque un effetto ottico. Fisicamente di sprite ce ne sono sempre e solo 8.

Citazione
Arrivato a ciascuna di queste righe,viene cambiata l'ordinata degli sprite

Appunto, spostato, quindi sopra non c'e' piu'. Che poi noi non lo vediamo perche' facciamo in modo che il raster non riesca a ridisegnare la parte sopra, lasciata vuota, e' ben diverso dal dire che gli sprite sono piu' di 8 contemporaneamente ;)
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -