Numero 2

SCARICA IL NUMERO 2 ORIGINALE

NAVIGA NEL NUMERO 2 ORIGINALE

Amiga Blast Magazine #2

Benvenuti al secondo numero di Amiga Blast.
Forti del successo riscontrato in queste prime settimane, riproponiamo la stessa “formula” anche per il secondo numero, augurandoci che i nostri sforzi vengano apprezzati.

In questo numero troverete due novità: la posta, con le prime lettere scritte da voi (alle quali rispondiamo con piacere) e l’opinione dell’editore, pensieri liberi sul futuro di Amiga.

Buona lettura!

Contribuite anche voi ad Amiga Blast (Vedere Come Contribuire ad Amiga Blast )

Ora navigate nella rivista.

L’Opinione dell’Editore

Dove vogliamo essere domani?

L’Orgoglio Di Essere Tra I Più Grandi (Parte 2)

Corso di ASSEMBLER

Corso di BLITZ

Fondamenti di grafica 3D.

Corso di Amiga E

Tutorial di LightWave

Corso di Grafica 2D

Posta

Gli eroi nella rete.

NOTA BENE

Tutto il materiale in quesa rivista e’ di Pubblico Dominio, potrete quindi scaricarvi: grafica, sorgenti e usarli per i vostri giochi o i vostri programmi!!!
Gli articoli rimarranno però (C)Copyright di Amiga Blast!

Dove Vogliamo Essere Domani ?

La tecnologia si sta evolvendo in fretta e, fortunatamente, con l’avvento di Amiga Technologies, anche Amiga ritornerà molto presto ad essere al passo coi tempi (se non addirittura a superarli, come ha sempre fatto fino a qualche anno fa).
Disquisizioni come quelle che facciamo durante gli articoli “L’Orgoglio Di Essere Tra I Più Grandi” sono valide e vere, ma non bastano. Amiga può vantare un favoloso Sistema Operativo (OS), ma sono poche le persone che, effettivamente, si accorgono di cosa sia un vero ambiente multitasking, di quanto sia facile aggiungere una nuova periferica, senza bisogni di drivers, patch o altro.

Amiga è ancora un passo avanti, e sta a tutti noi continuare a fare in modo che questo vantaggio non diminuisca, ma che anzi, cresca e si affermi ancora maggiormente.

Il discorso che vorremmo fare adesso, non verte tanto sulla parte hardware di Amiga, quanto sullo stile di programmazione del software.

Le caratteristiche che dovrebbero avere tutti i nuovi programmi che verranno sviluppati in futuro dovrebbero essere queste :

Supporto OS3.0+

I nuovi programmi non dovranno più sforzarsi troppo per essere ancora compatibili OS2.0, e dovranno assolutamente scordarsi dell’ormai obsoleto Kickstart 1.3, a meno che questa compatibilità non sia semplicissima da ottenere. L’OS3.0 è granitico e ben scritto. Se pensate che datato 1993 ed è ancora meglio dei vari Windows 95, OS2 ecc. capirete quanto ottimo lavoro ci sia alle spalle. La stessa cosa, purtroppo, non possiamo dirle per OS2.0, che presenta delle lacune molto grosse, comunque aggirabili, ma che appesantiscono (e rallentano) lo sviluppo di software.
Personalmente, sto scrivendo un programma commerciale compatibile OS2.0 e superiori e questo mi è costato molto in termini di prestazioni : ho dovuto sacrificare alcune features di OS3.0 a favore di una “compatibilità” che non credo mi servirà molto. Dalla prossima versione, infatti, richiederò OS3.0+ per funzionare correttamente.

No Enforcer Hits

Questa è una delle cose più difficili da ottenere : un codice granitico. Quando si scrivono programmi di una certa complessità, è già molto difficile che siano senza errori : impegnamoci almeno a verificare che siano senza Enforcer Hits, dal momento che in un ambiente multitasking come Amiga, programmi che generano Enforcer Hits sicuramente non funzioneranno correttamente e potrebbero anche minare l’integrità di tutto il sistema. Usate quindi Enforcer, durante tutte le fasi del processo di scrittura di un nuovo programma, e assicuratevi che, nella versione finale, non compaiano errori.

BOOPSI, Datatypes, Libraries ecc.

Sfruttate al massimo il sistema operativo : non limitatevi per nessuna ragione. Ormai da circa un anno, tutti i programmi dovrebbero, ad esempio, supportare i Datatypes per il caricamento delle immagini e i gadget BOOPSI per la creazione delle interfacce. E non lamentatevi dicendo che i datatypes sono lenti : non lo sono, e ZGIF ne è un esempio emblematico : se pensate che un certo datatype sia lento, riscrivetelo in modo che sia più rapido.
Penso che le interfacce grafiche non abbiano bisogno di MUI per funzionare su tutti gli schermi, MUI non fa altro che sfruttare alcune (poche) caratteristiche di BOOPSI : piuttosto di gui-engines pesanti come MUI, usate ClassAct o scrivete BOOPSI gadgets : tutti gli utenti Amiga beneficerebbero di gadget ben scritti e “pronti all’uso”.

No Limits

Non date dei limiti ai vostri programmi, siate OS compliant, puntate in alto, tutto quello che scrivete deve essere al massimo dello standard. Usate file in formato IFF dove possibile, usate ReadArgs() per parserizzare la command line, supportate i ToolTypes, scrivete le preferenze in ENVARC :, usate chiamate “pulite” per le routines grafiche. Insomma : fate in modo che un programma che scrivete oggi, sia utilizzabile (e funzioni perfettamente) anche fra cinque, dieci anni.

Conclusioni

In definitiva, cercate di dare tutto quello che potete alla comunità Amiga. Scrivete programmi unici, più flessibili, versatili e funzionali dei corrispettivi per altre piattaforme. Non lamentatevi se adesso il chip set AGA sembra superato : ben presto avremo nuove macchine sempre più potenti e sempre più all’avanguardia. E ci sarà sempre AmigaOS ad occuparsi di tutto. Personalmente, desidero moltissimo che i programmi che sto scrivendo adesso, funzionino anche sulle nuove macchine, che possa usarli un utente fra qualche anno, ed è in quella direzione che mi sto muovendo. E’ in quella direzione che dovremmo muoverci tutti.
Non chiedetevi “dove vuoi andare oggi ?”, perché il presente non è eterno e la tecnologia si sta evolvendo a passi da gigante. La domanda giusta è “Dove Vuoi Essere Domani ?”

L’Orgoglio Di Essere Tra I Più Grandi (Parte 2)

Un Sacco di Memoria

In questo secondo articolo, ci occuperemo di come viene gestita la memoria in Amiga OS e Windows. Prima di iniziare un’analisi approfondita, dobbiamo però esaminare alcune caratteristiche generali della maggior parte dei Sistemi Operativi (OS).

Gestione Delle Risorse

Uno dei compiti principali di tutti i sistemi operativi è la gestione delle risorse di un computer. Con il termine “risorse” non si intendono soltanto le varie unità di storaggio (floppy /hard disk, cd-rom, stampanti, scanner ecc…) ma anche le risorse “interne” come i caratteri (fonts), le varie librerie (libraries), i device audio e video, le finestre, gli schermi ecc…

Ogni risorsa viene vista dall’OS come un oggetto di dati (necessari per descrivere le caratteristiche della risorsa) e metodi di gestione. Per esempio una risorsa di tipo “stampante” conterrà tra i vari dati il numero di righe e di colonne stampabili per ogni pagina, se la stampante è a colori e così via; mentre tra i vari metodi di gestione ci saranno comandi tipo “stampa”, “vai a fine pagina” ecc…

Risorse E OS

Tutte queste risorse vengono gestite dall’OS in modo trasparente. La nostra valutazione verterà sui differenti metodi di implementazione che è stata scelta da Window e Amiga OS. Vediamo subito come Amiga interpreta la gestione delle risorse.

Gestione Delle Risorse In Amiga

In Amiga, Exec si occupa della gestione delle risorse in maniera dinamica. Quando un programma chiede una determinata risorsa all’OS, prima di tutto, Exec verificherà se quella risorsa è già stata richiesta in precedenza e se è quindi in uso: in gergo tecnico, si dice che quella determinata risorsa è “allocata”. Ad esempio, se un programma chiede di aprire una libreria, Exec cercherà quella libreria in memoria. Nel caso la risorsa sia già presente, Exec non la ricaricherà una seconda volta, ma fornirà al programma che la richiedeva un puntatore alla risorsa richiesta. Nel caso invece che quella risorsa non sia già stata alloca da nessuno, Exec la caricherà in memoria e restituirà al programma un puntatore alla risorsa. Come vedete, in entrambi i casi, il programma richiedente si deve solo limitare a richiedere una determinata risorsa, ricevendo come risultato un puntatore. Questo consente ad Exec di occupare la memoria per una determinata risorsa una sola volta e di fornire a tutti i programmi che ne faranno richiesta, un puntatore all’area di memoria contenente la risorsa desiderata.

Gestione Delle Risorse In Windows

In Windows, le cose stanno diversamente. Esistono delle librerie di comandi dette “DLL”, Dynamic Linked Library, che vengono agganciate dinamicamente al programma. Questo somiglierebbe molto alle Shared Library, le “.library” di Amiga, se non per il fatto che due programmi che condividono una stessa DLL devono risiedere nella stessa pagina di memoria, vale a dire che devono stare in 640K, altrimenti Windows ricaricherà la DLL in memoria una seconda volta. Gli utenti di Windows, conoscono bene errori tipo: “Impossibile aprire XXXXX.DLL perchè già in uso da un altro programma”. Senza contare che eventuali “linkaggi” si limitano alle DLL: fonts, devices e qualsiasi altra cosa viene comunque ricaricata per ogni programma.

Immaginate quindi adesso tre programmi che fanno uso del font “Times New Roman” grande 15 punti, che richiedono la GDI.DLL e aprano drivers MCI: il font verrà caricato tre volte, la GDI.DLL e MCI aperti (almeno) due volte. I tre programmi chiederanno complessivamente da un minimo di sette a un massimo di nove risorse al sistema, delle quali almeno quattro potevano essere evitate. Ecco perchè per utilizzare Windows avete bisogno di almeno 8 Mega di memoria. Senza contare che, anche con 8Mb, che il vostro Hard Disk (dove Windows tiene un file di swap che usa come memoria virtuale) sarà continuamente in funzione.

Buon lavoro, quindi, con Windows. E quando la lucetta del vostro hard disk si accenderà per l’ennesima volta, pensate che molti utenti Amiga non sanno neppure cosa sia la memoria virtuale.

FILLED VECTORS (PARTE 1)

AVETE MAI SOGNATO DI SCRIVERE UNA ROUTINE 3D ALL’ALTEZZA DEI MIGLIORI DEMO ? CON UNA SERIE DI ARTICOLI IMPARERETE A FARE QUESTO E ALTRO…
Iniziamo ora con una serie di articoli mensili (2 o 3 al massimo), in linguaggio assembler per amiga, dedicati alla creazione di una routine 3D con le seguenti caratteristiche:

  • DOUBLE BUFFERING
  • ROTATION ON 3 AXIS
  • ZOOM
  • SORTING ( Z-VALUES & PRE-DETERMINED PRIORITY )
  • LINES
  • NORMAL SURFACES
  • TRANSPARENT SURFACES!!!
  • HIDDEN FACES
  • DITHERING
  • CLIPPING
    SOLO IN CASO DI GRANDE RICHIESTA PUBBLICHERO’ ARTICOLI RIGUARDANTI:
  • TEXTURE MAPPING
  • GOURAUD SHADING
  • PHONG SHADING
  • MOVING LIGHT SOURCE ON 3 AXIS
    Inviare E-MAIL specificando la preferenza (anche in programmi completamente diversi , es.: ruotine di compressione e decompressione dati).

SPIEGAZIONE TERMINI

DOUBLE BUFFERING
Trattasi di un metodo per avere animazioni piu’ fluide, sono necessari due o piu’ blocchi di memoria: mentre un blocco viene visualizzato l’altro serve come buffer per calcolare il fotogramma successivo. A operazione compiuta i due blocchi di memoria vengono invertiti.

ROTATION ON 3 AXIS

la rotazione puo’ essere su uno, due o tre assi, quali X, Y e Z. La ruotine che prenderemo in esempio ruota i punti su tutti tre gli assi, usando una tabella di seno e coseno pre-calcolata per velocizzare tutte le operazioni.

ZOOM

lo zoom serve per aumentare o diminuire le dimensioni dell’oggetto vettoriale, come se questo si avvicinasse o si allontanasse da noi.

SORTING

uno dei problemi maggiori e’ sicuramente quello relativo alla ruotine di sorting. In pratica serve per dare una priorita’ di disegno alle facce che compongono il nostro l’oggetto. Tale priorita’ serve solo in alcuna casi, vediamo quali.

Facciamo un esempio pratico: un cubo tridimensionale sara’ composto da 6 facce (nel nostro esempio in numero di punti e’ trascurabile); in qualunque modo questo sia ruotato o zummato avra’ un numero di facce massime visibili pari a 3. Le restanti 3 facce non sono visibili dall’osservatore (HIDDEN FACES!), quindi e’ perfettamente inutile disegnarle. Mentre le cose sono semplici per queste ultime , tutto si complica per le facce visibili.

In questo esempio le facce visibili non si sovraporranno mai, quindi e’ inutile dar loro una priorita’ di disegno (non e’ rilevante l’ordine con cui queste vengano visualizzate).

Facciamo un secondo esempio: un carro armato con tanto di cingoli!

In questo caso e’ necessario dare una priorita’ di disegno alle facce, onde evitare (in vista laterale) che i cingoli vengano disegnati prima del nucleo principale del carro armato, serebbe impensabile avere entrambi i cingoli sullo stesso lato: avete presente una macchina con tutte le 4 ruote a destra ???

In questo ultimo caso in sorting in base ai valori della Z e’ necessario in modo da bilanciare il disegno, facendo disegnare prima un cingolo, poi il nucleo principale con il cannone e per ultimo l’altro cingolo. In altre parole una volta ruotato e zummato l’oggetto in questione, si prelevano solo le coordinate dalla Z e si effettua la media di ogni faccia, una volta calcolate tutte le medie si effettua un riordino delle facce in base al valore della Z: si disegna partendo dal fondo dell’oggetto e disegnando per ultime le facce piu’ vicino a noi.

LINES

per abbellire il tutto e’ possibile disegnare semplici linee e mescolarle con tutti gli altri metodi di disegni inclusi. NORMAL SURFACES

si tratta di semplici facce piane fillate e sovrapposte a quelle sottostanti. TRANSPARENT SURFACES

le facce trasparenti devono essere calcolate ma non visualizzate (non per nulla sono trasparenti). Deve essere possibile vederci attravarso: in questo caso devono essere visualizzate le facce interne dell’oggetto calcolato (anche se normalmente nascoste). Tornando sul cubo: 3 facce visibili e 3 no; nel caso una delle facce sia trasparente sara’ necessario visualizzare anche le facce nascoste.

HIDDEN FACES

tramite un semplice algoritmo e’ possibile capire se una faccia e’ visibile oppure no (in questo caso non la visualizzeremo neppure per avere una maggiore velocita’ di eseguzione del programma).

DITHERING

questo procedimento serve per aggiungere una maschera grigliata alle facce solide, onde avere colori intermedi e effetti ombreggiatura.

CLIPPING

viene usato quando una faccia esce dalla zona visibile dello screen. Con questa routine e’ possibile disegnare solo i pezzi di facce interne allo screen ed aliminare le parti esterne.

TEXTURE MAPPING

Tecnica per mappare un disegno in bitmap ai poligoni tridimensionali. Molto usati in giochi stile DOOM o simili, il disegno oltre ad essere ruotato sugli assi deve anche essere scalato.

GOURAUD SHADING

Metodo matematico per determinare il colore di una faccia in base ai gradi di ruotazione sia della faccia sia di un punto luminoso. La luce e’ supposta costante all’interno del poligono.

PHONG SHADING

Al contrario del GOURAUD il colore della faccia deve essere calcolato punto per punto, attenuando la sfacettatura delle immagini. Dal punto di vista estetico il PHONG e’ molto migliore del GOURAUD ma richiede molti piu’ calcoli e computer piu’ potenti.

MOVING LIGHT SOURCE ON 3 AXIS

Sia con GOURAUD e PHONG SHADING e’ necessario avere le coordinate (x,y,z) di un punto luminoso in modo da calcolare i vari colori di illuminazione , muovendo questo punto luminoso deve cambiare tutta l’illuminazione dell’oggetto.

SPIEGAZIONE DETTAGLIATA

In questo articolo analizzeremo solo i primi 3 punti, gli altri verranno spiegati nei mesi seguenti.

DOUBLE BUFFERING

Nell’esempio ho utilizzato ben 6 allocazioni di memoria, in modo da far un effetto simile al Motion Blur (premere il tasto destro del mouse).

In pratica su uno di questi (calcolascreen) effettuo il calcolo del fotogramma successivo mentre gli altri li visualizza in sequenza, avremo quindi:

screen1 = ultimo fotogramma calcolato

screen2 = 1 fotogramma prima dell’ultimo calcolato

screen3 = 2 fotogrammi prima dell’ultimo calcolato

screen4 = 3 fotogrammi prima dell’ultimo calcolato

screen5 = 4 fotogrammi prima dell’ultimo calcolato

Una volta chiarito l’ordine di visualizzazione del disegno utilizzo il blitter per cancellare il contenuto del bitplane (CalcolaScreen).

SwapScreen:

** Cambiamento puntatori allo screen per il fotogramma successivo

move.l  CalcolaScreen,d0
move.l  Screen1,CalcolaScreen
move.l  Screen2,Screen1
move.l  Screen3,Screen2
move.l  Screen4,Screen3
move.l  Screen5,Screen4
move.l  d0,Screen5

** visualizzazione tramite copper dei puntatori allo screen

lea planeaddress,a0
move.l  Screen5,d0
move.w  d0,6(a0)
swap    d0
move.w  d0,2(a0)
swap    d0
move.l  Screen4,d0
move.w  d0,14(a0)
swap    d0
move.w  d0,10(a0)
swap    d0
move.l  Screen3,d0
move.w  d0,22(a0)
swap    d0
move.w  d0,18(a0)
swap    d0
move.l  Screen2,d0
move.w  d0,30(a0)
swap    d0
move.w  d0,26(a0)
move.l  Screen1,d0
move.w  d0,38(a0)
swap    d0
move.w  d0,34(a0)

** utilizzo del blitter per cancelare CalcolaScreen

lea $dff000,a6
move.w  #$8400,$96(a6)

WaitBlitter:
btst #6,2(a6)
bne.s WaitBlitter
move.w #$0400,$96(a6)
move.l #$01000000,$40(a6)
moveq #-1,d0
move.l d0,$44(a6)
move.l CalcolaScreen,$54(a6)
move.w #0,$66(a6)
move.w #$4014,$58(a6)
rts

ROTATION ON 3 AXIS

Questa routine preleva le coordinate X,Y e Z dalla variabile WPoints e li ruota su tutti gli assi. I gradi di ruotazione sull’asse X li preleva da Xangle, Y da Yangle e Z da Zangle.

La routine SinCos preleva (da SinTab) i valori (precalcolati) del seno e del coseno dell’angolo di ruotazione e li salva in variabili quali Xsin,Xcos,Ysin, Ycos,Zsin e Zcos.


** Ruota attorno tutti gli assi **


Rotate:
move.w #$fff,d4 ; $fff = numero massimo di valori in SINTAB

move.w  Zangle,d0   ; angolo ruotazione Z
and.w   d4,d0       ; and con $fff
move.w  d0,Zangle
jsr SinCos      ; prelevamento Seno e Coseno
move.w  d1,Zsin     ; seno di Z
move.w  d2,Zcos     ; coseno di Z

move.w  Yangle,d0   ; vedi sopra mo con Yangle
and.w   d4,d0
move.w  d0,Yangle
jsr SinCos
move.w  d1,Ysin
move.w  d2,Ycos

move.w  Xangle,d0   ; vedi sopra ma con Xangle
and.w   d4,d0
move.w  d0,Xangle
jsr SinCos
move.w  d1,Xsin
move.w  d2,Xcos

lea Wpoints,a0  ; coordinate X,Y,Z originali
lea IntX,a3     ; salvataggio coordinate X (calcolate)
lea IntY,a4     ; salvataggio coordinate Y (calcolate)
lea IntZ,a5     ; salvataggio coordinate Z (calcolate)
move.w  #npoints-1,d0   ; numero di punti -1 (quindi 1858-1)

Zrotate:
move.w Zsin(pc),d1 ; sin Z
move.w Zcos(pc),d2 ; cos Z
move.w (a0)+,d6 ; X
move.w (a0)+,d7 ; Y
muls d6,d2 ; X * cos Z
muls d7,d1 ; Y * sin Z
sub.l d1,d2 ; (X * cos Z)-(Y * sin Z)
add.l d2,d2 ; ((X * cos Z)-(Y * sin Z)) * 2
swap d2 ; (((X * cos Z)-(Y * sin Z)) * 2) / 32768
move.w d2,d5 ; NEW X !!!
move.w Zsin(pc),d1 ; sin Z
move.w Zcos(pc),d2 ; cos Z
muls d6,d1 ; X * sin Z
muls d7,d2 ; Y * cos Z
add.l d1,d2 ; (Y * cos Z) + (X * sin Z)
add.l d2,d2 ; ((Y * cos Z) + (X * sin Z)) * 2
swap d2 ; (((Y * cos Z) + (X * sin Z)) * 2) / 32768
move.w d2,d6 ; NEW Y
Yrotate:
move.w Ysin(pc),d1
move.w Ycos(pc),d2
move.w (a0)+,d3 ; Z
muls d3,d2
muls d5,d1
sub.l d1,d2
add.l d2,d2
swap d2
move.w d2,d7 ; NEW Z
move.w Ysin(pc),d1
move.w Ycos(pc),d2
muls d3,d1
muls d5,d2
add.l d1,d2
add.l d2,d2
swap d2
move.w d2,(a3)+ ; FINAL X
Xrotate:
move.w Xsin(pc),d1
move.w Xcos(pc),d2
muls d6,d2
muls d7,d1
sub.l d1,d2
add.l d2,d2
swap d2
move.w d2,(a4)+ ; FINAL Y
move.w Xsin(pc),d1
move.w Xcos(pc),d2
muls d6,d1
muls d7,d2
add.l d1,d2
add.l d2,d2
swap d2
move.w d2,(a5)+ ; FINAL Z
dbf d0,Zrotate
rts


** Calcola seno e coseno **


Sincos:
lea SinTab,a1 ; seno e coseno precalcolato
move.w d0,d2
add.w d0,d0
move.w (a1,d0.w),d1 ; New SIN
move.w #$c00,d3 ; 4/3 of 360°
cmp.w d3,d2
blt.s Plus9
sub.w d3,d2
add.w d2,d2
move.w (a1,d2.w),d2 ; New COS
rts
Plus9: add.w #$400,d2 ; 1/4 di 360 gradi
add.w d2,d2
move.w (a1,d2.w),d2 ; New COS
rts

ZOOM

La ruotine di Zoom serve per aumentare o diminuire le demensioni degli oggetti in modo da aggiungere l’effetto avvicinamento o allontanamento.

A questo proposito sono necessarie 3 coordinate per ogni punto (X,Y,Z) e da queste ne verranno ricavate solo 2 (X,Y).

Una semplificazione dei calcoli 3D che gestiscono lo zoom potrebbero essere:

X final = ( X * zoom ) / ( 1000 + Z )
Y final = ( Y * zoom ) / ( 1000 + Z )

dove:
X , Y , Z = sono le coordinate di un punto

zoom = valore di zoom intermedio tra 0 e 1000

1000 = valore massimo dello zoom

Zoom:
lea IntX,a1 ; coordinata X
lea IntY,a2 ; coordinata Y
lea IntZ,a3 ; coordinata Z

move.l  CalcolaScreen,a4    ; screen address
lea Tabella,a5      ; valore Y moltiplicati per 40

moveq   #0,d0
move.w  #npoints-1,d0
move.w  Dist(pc),d3     ; valore zoom
move.w  #1000,d4        ; volore massimo zoom

WaitBlit:
btst #6,$dff002
bne.s WaitBlit
CalcAll:
move.w (a1)+,d6 ; X
muls d3,d6 ; X * zoom
move.w (a3)+,d2 ; Z
move.w d2,d7 ; d7 = d2 = Z
add.w d4,d2 ; 1000 + Z
divs.w d2,d6 ; NEW X
add.w Xorg(pc),d6 ; X = X + orgX

move.w  (a2)+,d1        ; Y
neg.w   d1          ; d1 = neg d1
muls    d3,d1           ; Y * zoom
add.w   d4,d7           ; 1000 + Z
divs.w  d7,d1           ; NEW Y
add.w   YOrg(pc),d1     ; Y = Y + orgY

; X = d6
; Y = d1
move.w d6,d5 ; d6 = d5 = X
lsr.w #3,d5 ; d5 = d5 / 8
add.w d1,d1 ; d1 = d1 * 2
add.w (a5,d1.w),d5 ; d5 = d5 * 40 (byte for row)
not.b d6 ; d6 = not d6

bset    d6,(a4,d5.w)        ; set pixel

dbf d0,CalcAll
rts

Nell’archivio sono incluse due demo:
3D-points : esempio e sorgente di questo articolo

3D-demo : demo della routine 3D (presto avrete il sorgente)…

Le routine somo molto vecchie (1990) e testate solo su Amiga 500 e 2000 , pertanto non ottimizate per microprocessori piu’ veloci.

La mia ultima routine 3D (68020+) riesce a gestire il satellite (180 punti e 170 facce) a 25 Frames/second in modo 256 colori, ma essendo stata creata per un gioco (quindi commerciale), non ne pubblichero’ il sorgente.

SORRY….

Corso Di Blitz

Fondamenti di Grafica 3D

Le parti principali del programma di cui vale la pena discutere sono la routine di proiezione e quella di rotazione.
Iniziamo con la parte relativa alla proiezione: l’idea base è di un mio amico (Giorgio Fornara). Il diagramma allegato all’articolo aiuterà nella comprensione (dategli un’occhiata). L’idea è molto semplice (ma ingegnosa): quando si disegna un oggetto tridimensionale su un foglio di carta si è già fatta la proiezione che stiamo cercando, perché il foglio è 2-dimensionale!

Inizio con la descrizione del diagramma: i tre assi blu sono quelli del nostro spazio tridimensionale, i due assi neri sono quelli dello schermo 2-dimensionale (per essere precisi bisognerebbe cambiare segno all’asse Y in quanto tale asse sullo schermo punta verso il basso). Le linee rosse formano il nostro oggetto (per chiarezza non ho disegnato le linee nascoste) e le linee verdi sono le coordinate 2-dimensionali del punto P che stiamo cercando. Nel programma i due angoli alpha e beta sono entrambi uguali a 30 gradi, ma non devono necessariamente essere tali.

D’ora in poi indicherò le coordinate dello schermo con le lettere maiuscole X e Y, e le coordinate dello spazio tridimensionale con lettere minuscole x, y e z; allora la coordinata Y di P verrà scritta P_Y, e la coordinata y di P sarà rappresentata da P_y, e così via… Adesso il lavoro è facile: P_Y è semplicemente uguale a P_z meno il segmento dato da P_x * Sin(beta) (quello delimitato dalle linee blu tratteggiate) meno l’altro piccolo segmento dato da P_y * Sin(alpha). Analogamente per l’altra coordinata: P_X è uguale a P_x * Cos(beta) meno P_y * Cos(alpha). Quindi abbiamo le seguenti relazioni:

P_X = P_x * Cos(beta) – P_y * Cos(alpha)

P_Y = P_z – P_x * Sin(beta) – P_y * Sin(alpha)

Per ottenere le formule usate nel programma occorre sottrarre queste quantità dalle coordinate del centro dello schermo.

A proposito, il disegno degli spigoli nascosti con linee tratteggiate è dovuto ad un (subdolo) trucco. Fra l’altro, il trucco funziona solo se si ha un solo vertice nascosto alla volta: si calcola quale vertice ha il valore più negativo per la somma delle sue tre coordinate P_x + P_y + P_z e si disegna tratteggiata ogni linea che si diparte da tale vertice. Sto ancora pensando a come generalizzare tale idea per permette configurazioni in cui più vertici sono nascosti contemporaneamente (se avete suggerimenti io non ho E-Mail, ma potete scrivere a Fabio Soft presso fsoft@intercom.it)

Veniamo ora alla routine che effettua le rotazioni. Le formule usate qui sono solo il prodotto della matrice di rotazione attorno all’asse z per la matrice di rotazione attorno all’asse x. In particolare: la rotazione attorno all’asse z è rappresentata in algebra lineare dalla matrice

| Cos(theta) Sin(theta) 0 |
| |
| -Sin(theta) Cos(theta) 0 |
| |
| 0 0 1 |

dove theta è l’angolo che rappresenta l’entità della rotazione; la rotazione attorno all’asse x è rappresentata dalla matrice

| 1 0 0 |
| |
| 0 Cos(phi) Sin(phi) |
| |
| 0 -Sin(phi) Cos(phi) |

dove phi è l’angolo che rappresenta l’entità della rotazione. Ora si effettua il prodotto (righe per colonne, al solito) delle due matrici e si ottiene:

| Cos(theta) Sin(theta)Cos(phi) Sin(theta)Sin(Phi) |
| |

R = | -Sin(theta) Cos(theta)Cos(phi) Cos(theta)Sin(phi) |
| |
| 0 -Sin(phi) Cos(phi) |

Se indico le nuove coordinate (quelle ruotate) con (x’, y’, z’) e quelle vecchie con (x, y, z) abbiamo

| x’ | | x |
| | | |
| y’ | = R | y |
| | | |
| z’ | | z |

cioè

x’ = xCos(theta) + ySin(theta)Cos(phi) + zSin(theta)Sin(Phi)

y’ = – xSin(theta) + yCos(theta)Cos(phi) + zCos(theta)Sin(phi)

z’ = – ySin(phi) + zCos(phi)

e queste sono le formule che appaiono nel programma.

Io ho scelto di ruotare il mio cubo attorno agli assi x e z, ma si possono effettuare rotazioni attorno a qualunque asse si voglia, a patto di moltiplicare le matrici giuste e, poi, di collegare gli angoli al movimento del mouse.

Il resto del programma è dedicato ad aprire la finestra, leggere l’input, scrivere l’output: potete trovare i commenti a proposito di queste operazioni direttamente nel programma.

Clickate qui per il sorgente.

E per Esperti

Basi di OOP e sue implementazioni in AmigaE (Parte 1)

Overview

La Programmazione Orientata agli Oggetti (OOP) rappresenta la naturale evoluzione di altre tecniche di programmazione, come la programmazione strutturata e quella procedurale. Le varie metodologie di programmazione evolutesi in questi anni, hanno sempre cercato di incapsulare dati non essenziali al programmatore in strutture invisibili in modo da ridurre al minimo la possibilità di errore. Facendo un esempio, una procedura o una funzione chiamata Test() potrebbe richiedere in input alcuni parametri, e dovrebbe essere compito della procedura stessa di assicurare un corretto funzionamento anche in situazioni critiche (ad es. parametri non validi, mancanza di memoria ecc..)
Caratteristica della programmazione procedurale è la relativa semplicità del debug: se i risulati ottenuti dalla procedura Test() non sono corretti, il problema risiede solo nella procedura Test() stessa. Quindi un programmatore è in grado di correggere facilmente eventuali errori. A patto che non scriva un intero programma in una sola volta e poi tenti di debuggarlo…

La OOP rappresenta la naturale evoluzione della programmazione procedurale. Anche se quello che sto per dire non è del tutto corretto, un oggetto potrebbe essere visto come una struttura di dati (le struct del C, gli OBJECTs di E, i NEWTYPE del BLITZ) associata ad una serie di funzioni mirate alla manipolazione dei dati contenuti nella struttura stessa. La mia definizione di cosa sia un oggetto è sicuramente troppo semplicistica ma, in definitiva, la programmazione a oggetti si limita a questo. I vantaggi però non sono così semplicistici…

Dal punto di vista del programmatore, un oggetto può essere visto come un vero e proprio programma a sè stante, con le sue variabili globali e locali (le prime incluse nella definizione dell’oggetto, le altre nelle varie funzioni/procedure di manipolazione dei dati dell’oggetto stesso), le sue funzioni e le sue routine di inizializzazione e distruzione (la main() del C e di E). Scrivendo un oggetto, il programmatore si comporta esattamente come se stesse scrivendo un programma. Tutti i dati verranno manipolati all’interno dell’oggetto stesso, e sta al programmatore decidere cosa rendere visibile e cosa invece tenere chiuso all’interno dell’oggetto.

Fondamenti Di OOP

Un oggetto, come abbiamo già detto, è formato da una parte strutturale di dati (le variabili) ed un’altra di funzioni legate all’oggetto stesso, che permettono la manipolazione dei dati. Sia le variabili all’interno dell’oggetto che le funzioni stesse, possono essere rese visibili o invisibili dall’implementatore dell’oggetto ai futuri utilizzatori dell’oggetto stesso: in definitiva, è chi crea l’oggetto che decide se determinate caratteristiche dell’oggetto devono essere sfruttabili da altri, oppure rimanere interne all’oggetto stesso.

Questa caratteristicha della OOP, permette di creare delle vere e proprie “scatole nere” (gli oggetti), che svolgono determinate funzioni correttamente e che possono (e devono) essere utilizzate da altri programmatori senza preoccuparsi molto di come siano effettivamente state create.

Personalmente, ho scritto molti oggetti che mi permettono operazioni particolari sui dati o su particolari caratteristiche del Sistema Operativo di Amiga… e di alcuni non so più con precisione cosa facciano. Più o meno è così che dovrebbe essere per tutti: un oggetto deve essere chiuso in sè stesso ed assicurare funzionalità.

continua nel prossimo numero…

Tutorial Di Lightwave (Parte 2)

Nel secondo numero di Lightwave, abbiamo deciso di insegnarvi a creare delle scene stile Guerre Stellari. Vedrete che non sarà molto difficile, grazie a Lightwave.

Materiale occorrente:

  • Lightwave 3.5 o +
  • Oggetti di Astronavi (quelli del tutorial vanno benissimo)
    Per prima cosa dobbiamo caricare il seguente oggetto:
  • SpaceFighter (o un qualsiasi altra astronave desideriate). Inseriamo con MOVE Numeric Input i seguenti valori: X: -24
    Y: 0
    Z: 24
    e Ruotiamo l’ oggetto inserendo con ROTATE Numeric Input i seguenti valori: H: 128.80
    P: -0.60
    B: 0
    Creaiamo la KEY con CREATE KEY.

Copiamo la KEY premendo sempre CREATE KEY e inserendo il numero 30.

Andiamo al numero 30 con NEXT

Inseriamo con MOVE Numeric Input i seguenti valori:

X: 0
Y: 0
Z: 5

Creaiamo la KEY con CREATE KEY.

Copiamo la KEY premendo sempre CREATE KEY e inserendo il numero 60.

Andiamo al numero 60 con NEXT

Inseriamo con MOVE Numeric Input i seguenti valori:

X: 20.30
Y:  0
Z: -3.20

Ruotiamo la CAMERA inserendo i seguenti valori di ROTATE:

H: 46.80
P:  2.20
B:  0

Creaiamo la KEY con CREATE KEY.

Copiamo la KEY premendo sempre CREATE KEY e inserendo il numero 80.

Andiamo al numero 80 con NEXT

Inseriamo con MOVE Numeric Input i seguenti valori:

X:  62
Y:   0
Z: -36

Ruotiamo la CAMERA inserendo i seguenti valori di ROTATE:

H: 90.20
P:  3.6
B:  0

Abbellite la SCENA con più oggetti quali: Pianeti, Stelle e altre astronavi.

Per un impatto maggiore consigliamo alcuni trucchi:

Lens Flare attivato sull’ astronave.
Motion Blur per l’ animazione.
Shadow e completo Ray-Tracing attivato.

Come abbiamo pututo notare è la camera virtuale a dare il senso di movimento e ad abbellire la scena, con LIGHTWAVE è semplicissimo creare sensi di movimento piacevoli, basta ad esempio far seguire alla camera virtuale tragitti sempre diversi e sarà il programma a calcolarne il movimento senza neanche il minimo sforzo.

Corso Di Grafica 2D – SECONDA LEZIONE –

Nel secondo numero di AMIGABLAST useremo i concetti appresi nel numeor precedente della rivista, unendoli ad altri “trucchi” per creare Giochi di Piattaforme, come SuperFrog, Super Mario Bros ecc.
Occorrenti:

Programma di Grafica Bidimensionale
( BRILLANCE, DPAINT, CLOANTO PAINT ECC. )
Conoscere i comandi principali
( TRASPARENZA, SMOOTH, CREAZIONE DI UN BRUSH ecc. )
Come nel numero precedente dobbiamo organizzare intelligentemente la Palette da noi utilizzata. Dopo essere entrati nel menu della PALETTE ( per programmi come Brillance, Dpaint la lettera P ), dobbiamo inserire i seguenti colori:

Col. N: 0 – RGB: 0,0,0

Col. N: 5 – RGB: 33,66,123

Col. N: 10 – RGB: 255,255,255

Col. N: 11 – RGB: 49,24,0

Col. N: 17 – RGB: 189,148,107

Col. N: 18 – RGB: 255,0,0

Col. N: 21 – RGB: 255,255,0

Con un’ opzione di SPREAD dobbiamo trovare le sfumature che vanno dal 5 colore al 1, dal 10 al 5, dal 10 al 17 e dal 18 al 21.
Ora dobbiamo disegnare, con l’ opzione di BOX pieni, un quadrato di 16×16 pixel che servira’ come Maschera per la nostra grafica. Copiamo come BRUSH molte volte la nostra maschera, disegnamoci dei puntini di diverse sfumature da noi create precedentemente (vedi riga A nella schermata di esempio). Dopo aver compiuto questa operazione usiamo un’ opzione simile allo SMOOTH e applichiamola sul quadrato con i puntini. Come si puo’ vedere dal disegno dimostrativo, il quadrato e stato “SPIXELLATO” dandogli una piacevole sfumatura di colore. Ritocchiamo il nostro BOX “Mattonella” evidenziando:

-Lato superiore e laterale destro, con il colore bianco applicato alla
trasparenza.
-Lato inferiore e laterale sinistro, con il colore nero applicato alla
trasparenza.
Da notare l’ effetto luce in alto a destra.

Conserviamo per il momento la nostra “Mattonella” per creare la parte alta (una sorta di soffitto) per la nostra zona di gioco. Come la mattonella da noi creata usiamo il procedimento sopra indicato cioe’ le seguenti opzioni: TRASPARENZA SMOOTH e BOX pieni. Da notare l’ effetto ombra che riesce a risaltare i volumi (vedi riga B nella schermata di esempio). Per crearlo basta attivare la Trasparenza e applicare i colori dal piu’ scuro al piu’ chiaro sul blocco SMOOTHato.

Ora dobbiamo disegnare dove dovra’ appoggiare il nostra personaggio (vedi riga A nella schermata di esempio), con una procedura simile a quella utilizzata precedentemente (vedi la creazione della mattonella). Anche qui gioca un ruolo fonamentale la Luce.

-Lato superiore e lato destro, linea di 2 pixel di colore bianco attivando la
trasparenza.
-Lato inferiore e lato sinistro, linea di 2 pixel di colore nero attivando la
trasparenza.

Ora un punto fondamentale, la creazione del blocco principale: Copiamo la mattonella e blittiamola (vedi riga D nella schermata di esempio) attiviamo la traparenza e utiliziamola per creare le sfumature, quindi creiamo un po’ di blocchi uno dopo l’ altro. Con la Trasparenza attivata, riblittiamo dove avevamo blittato precedentemente i blocchi, con lo stesso brush. Noterete che i blocchi verranno Mixati dando un effetto molto migliore del brush originale.
Creaiamo adesso il blocco per lo sfondo, da spiegare c’e’ veramente poco, se non di analizzare bene il primo blocco (vedi riga E nella schermata di esempio) Una volta creato una Texture omogenea, cioe’ che non si veda la fine di un blocco, e colorata, SMOOTHamola con l’ apposita opzione.

Abbiamo terminato la seconda lezione di GRAFICA BIDIMENSIONALE. Ora caricate la schermata chiamata 2D_TOTAL.GIF per vedere come si possono utilizzare i blocchi creati. Sarebbe meglio aumentare i blocchi con qualche chicca (vedi righe F,G,H,I nella schermata di esempio)

NOTA BENE: nel numero successivo uniremo la GRAFICA TRIDIMENSIONALE A QUELLA BIDIMENSIONALE per creare giochi dalla grafica come Donkey Kong Country o l’ ultimissimo Super Mario RPG.

L’ANGOLO DELLA POSTA

Ecco alcune delle lettere che sono giunte qui ad Amiga Blast.
Se volete spedire i vostri commenti, fatelo scrivendo a: fsoft@intercom.it

From: Alessandro_Consoli@amp.flashnet.it (Alessandro Consoli)
Ciao,
Ho scoperto per caso la vostra rivista e devo dire che ne sono rimasto
positivamente colpito.
Come 1o numero gli articoli sono molto interessanti. Andate avanti cosi! 🙂
Solo un piccolo suggerimento: dovreste rendere possibile il donwload della
rivista in .guide o .html tutta insieme, senza scorrerla nel web..i motivi
sono vari..1 la Telecom dissangua..2 non tutti possiedono (come me, almeno
per ora) un accesso ad Internet completo (vedi niente SLIP/PPP)…

Alla prox..ciao
Beh, Alessandro, come puoi vedere, adesso è possibile scaricare la
rivista! Dal momento che però gli articoli non arrivano tutti “subito”,
l’archivio non sarà disponibile assieme alla rivista, ma sempre con
qualche giorno di ritardo. Spero che questo non sia un problema!

Ciao,
    Fabio Rotondo

From: di3andpe@ida.his.se (Anders Persson)
Ciao!
Ho un piccolo commento riguardo all’articolo sul multitasking:
(“L’Orgoglio di essere tra i più grandi (Parte 1)”, n.d.r.)

Penso che dovreste menzionare il fatto che un “loop busy-wait” non rallenta
il computer per niente, se utilizzate un cpu-scheduler come “Executive”.
Al task in busy-loop viene allora data una priorità così bassa, che tutti
gli altri task ricevono la loro CPU-time prima.

vedete anche:
http://www.megabaud.fi/~petrin/Executive.html
Saluti:

Anders Persson

Beh… personalmente non conoscevo Executive. Di solito, se un task entra in
busy-loop, io lo uccido con Amiga Real Time Monitor… 😉

In ogni caso, grazie per la precisazione!

Ciao,

    Fabio Rotondo

From: tarjeik@stud.unit.no (Tarjei Knapstad)
E’ molto difficile leggere gli articoli sulle pagine di Amiga Blast
perchè il testo si mischia con lo sfondo. Dovreste provare a trovare un
background un po’ più omogeneo…
Beh, Tarjei, sei stato l’unico a segnalarci questo problema…
non leggerai mica Amiga Blast con NetScape, vero?
Comunque, cercheremo di trovare una soluzione!

A presto!
Fabio Rotondo

From: Porter_Woodward@internet.kronos.com (Porter Woodward)
Heylà!,
congratulazioni per aver portato un magazine di programmazione su Amiga veramente tosto
sulla rete! Mi piace quello che avete fatto – vale sicuramente più della pena di aspettare
che esca qualche arretrata rivista con dischetto….

                        Grazie,
                        Porter Woodward

Ciao Porter,

grazie per i tuoi complimenti: sono stati apprezzatissimi. Torna a trovarci

quando vuoi… e porta degli amici! 😉

Ciao,
    Fabio Rotondo

From: melizo@nais.com (Louis Volpe)
Siete stati aggiunti al motore di ricerca amiCrawler.

URL: http:www.intercom.it/~fsoft/ablast.html
Keywords: magazine online
Name: Amiga Blast Magazine Home Page
Description: This is the Amiga Blast Home Page, the first WEB Italian magazine dedicated to Amiga. From this page you can access to both Italian and English version of the mag.
Password:

Grazie,
David Tiberio

WOW!!!! ;)

Ho guardato la vostra rivista, e mi è sembrata molto tosta!
Naturalmente, ho apprezzato la sezione su E 🙂
Anche l’articolino sul texturemapping era bello… ci ho
giocherellato un po’.
Allora, qual’è lo scopo? Che cosa state pianificando?

Wouter

Hey, il GRANDE Wouter, il creatore di AmigaE, che mi dice che il mio magazine è tosto! 😉
Potrei scoppiare ;))
Cosa intendi con scopo? Vogliamo solo dare alla comunità Amiga un bel magazine!!!

Ciao,
Fabio Rotondo

Gli Eroi nella rete.

Gundam
La più bella pagina dedicata al famosissimo mobile-suit la potete trovare a: http://gundam.anime.net/

Ricca di testi e immagini. Personalmente ci ho perso molti giorni…

Goldrake
Sfortunatamente, non c’è molto materiale riguardante questoi mito dei cartoni animati giapponesi. Tutto quello che ho trovato di valido è qui:

http://lapphp0.in2p3.ft/~lafaye/goldorak.html

L’Uomo Ragno
Ecco una delle pagine più belle dedicate all’arrampicamuri.

http://minuteman.com/spiderman/index.html

Il Corvo
Brandon Lee non è morto.

Guardate a: http://199.182.102.186:81/crow/the_crow.html