Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
libreria SDL
di
Giovanni Di Liberto
aka Oligoatria
2006-2007
Introduzione
Cos la libreria SDL: Simple DirectMedia Layer - SDL, una libreria multipiattaforma
per lo sviluppo di applicazioni multimediali. In parole semplici, si tratta di unutile
concentrazione di funzioni riguardanti grafica, suoni, eventi, thread, e altro.
Queste si pongono tra lhardware e lapplicazione, rendendo cos possibile la creazione di
videogiochi, demo, emulatori, etc., molto performanti.
Creata nel 1997 da Sam Lantinga, stata utilizzata per effettuare il port di alcuni
famosi videogiochi dal sistema Windows a Linux. La libreria open-source; in particolare
rilasciata sotto licenza GNU LGPL (GNU LESSER GENERAL PUBLIC LICENSE per
informazioni rimando al link http://www.gnu.org/licenses/lgpl.html), dunque pu essere
utilizzata per lo sviluppo di applicazioni commerciali, anche closed-source, a patto che le
modifiche apportate al codice sorgente del software stesso vengano rese pubbliche e che sia
inserito un linking dinamico alla libreria stessa.
Perch questa guida: Sulla rete sono disponibili cos tanti suggerimenti sullSDL che ho
pensato: copia e incolla, metto un titolo e divento famoso! A parte gli scherzi, sono
convinto che ci sia molta gente interessata alla grafica, in particolar modo se mirata alla
creazione di videogiochi, e credo che lSDL sia un ottimo punto di partenza per chiunque
intenda poi approfondire largomento programmazione grafica, sia 2D che 3D. Ovviamente
non sufficiente limitarsi allutilizzo delle funzioni, ma necessario capirne il
funzionamento per poterle utilizzare al meglio e, se necessario, ampliarle.
Lobiettivo di questa guida fornire i concetti chiave e le relative funzioni SDL
per permettere di proseguire da soli, approfondire e implementare le proprie idee,
ancora carichi di interesse.
Nota fondamentale: Gli esempi relativi a questa guida sono scaricabili dal sito
http://www.pierotofy.it, sezione C++. E sufficiente cercare SDL e nella lista saranno
presenti i file SDL_Example* (1, 2, 3, ). La guida e gli esempi sono disponibili anche nel
sito http://www.oligoatria.it.
Sono daccordo con quasi tutta la descrizione, tranne che per il fatto che troppo
poco vengono fatti pesare i difetti.. oltre che per il fatto che SDL non da meno,
riguardo gli emulatori!
SDL
Rispetto ai pregi di ALLEGRO modificherei solo la semplicit, che non pi
notevole ma non eccessiva. Il supporto 3D decisamente migliore (anche se
Attenzione: per poter utilizzare leseguibile, dora in poi, sar sempre necessaria la
presenza del file SDL.dll nella sua stessa directory.
Per impostare il progetto con un IDE diverso da Visual Studio non cambia
praticamente nulla: ovvio che il men sar diverso, ma le operazioni da eseguire sono le
stesse (dopo averlo fatto la prima volta vi potreste domandare: mmm, ma cosa ho fatto?,
se cos andatevi a studiare il funzionamento di un compilatore e gli argomenti correlati).
La prima dialog
La prima cosa da imparare linizializzazione video. Una delle comodit di questa
libreria la semplicit delle operazioni necessarie alla creazione di una dialog.
Inizializzazione: per utilizzare la libreria necessario inizializzare i sottoinsiemi interessati
(SDL_INIT_VIDEO, SDL_INIT_AUDIO, SDL_INIT_CDROM, SDL_INIT_TIMER)
tramite la funzione SDL_Init(FLAGS). Al termine dellapplicazione necessario chiamare la
funzione SDL_Quit() per terminare questi sottosistemi; un metodo alternativo per la chiusura
la funzione atexit(SDL_Quit), solitamente posta subito dopo linizializzazione, per chi ha
paura di dimenticarsi la chiamata alla funzione di chiusura. In questo caso, per, nel main si
dovr utilizzare lexit().
Subito dopo possiamo inizializzare la finestra. In unapplicazione multipiattaforma
non si pu prendere nessuna decisione a priori; necessario, invece, gestire il software in
relazione alle possibilit hardware della macchina e al sistema operativo. A questo proposito
la libreria SDL mette a disposizione una serie di funzioni per ottenere informazioni
riguardanti i driver video (SDL_GetVideoInfo()) e le potenzialit dellhardware video
(SDL_GetVideoInfo()). Non mi soffermo per su questo; vediamo invece i passi base per la
creazione di una dialog:
SDL_Surface *screen;
screen = SDL_SetVideoMode( x, y, bits, Flags );
if(! screen ) return -1; // gestione del possible errore
SDL_LockSurface(screen);
SDL_Surface questo sar dora in poi il tipo fondamentale, infatti questo che contiene
le informazioni relative a unimmagine. Non si deve per confondere questo tipo con la
dialog, la quale viene collegata ad una variabile di questo tipo; infatti molto spesso si
caricano immagini non visualizzate completamente o del tutto, cosa che avremo modo di
approfondire con gli sprite.
SDL_SetVideoMode( int x, int y, int bits, int Flags ) questa appunto la funzione che
alloca la nuova SDL_Surface e crea una nuova Dialog a essa riferita.
x larghezza della superficie
y altezza della superficie
bits numero bit di colori
Flags SDL_OPENGL | SDL_FULLSCREEN | SDL_DOUBLEBUF | ...
SDL_LockSurface si rende utile quando si inizia lo sviluppo di funzioni pi complesse;
il suo scopo quello di bloccare eventuali operazioni di scrittura non desiderate, che
potrebbero causare errori.
Piccolo fastidio: per ogni blocco di operazioni di disegno (blit) sar necessario
sbloccare e poi riboccare la superficie, con appunto SDL_UnlockSurface(SDL_Surface*) e
SDL_LockSurface(SDL_Surface*)
if (SDL_PushEvent(&test_event) == 0)
{
SDL_PollEvent(&event);
Per andare sul concreto, faccio lesempio degli sprite: in molti tipi di gioco le
immagini di un personaggio vengono unite in un unico file; nella fase di disegno se ne
prender solo una parte alla volta.
Ma questo lo vedremo nel capitolo degli sprite.. andiamo per gradi.
for( ; ; )
{
if (SDL_PushEvent(&test_event) == 0)
{
SDL_PollEvent(&event);
//
(1) Le librerie SDL utilizzano automaticamente un algoritmo per sincronizzare lUpdateRect con laggiornamento
fisico dello schermo. Se nel ciclo di gioco ci fossero pi aggiornamenti visivi della superficie
(SDL_UpdateRect o anche SDL_Flip, nel caso del DOUBLE_BUFFERING) si visualizzerebbero effetti visivi
che renderebbero lapplicazione normalmente inutilizzabile.
Blit parziale: Come per indicare le coordinate dello schermo dove disegnare la BMP, si
utilizza una variabile di tipo SDL_Rect:
SDL_Rect src;
src.x = 0;
src.y = 0;
src.w = 23;
src.h = 10;
Eseguendo poi la funzione SDL_BlitSurface(image, &src, screen, &dst ) si comunica alla
libreria di disegnare in screen dst.x, dst.y, la porzione dellimmagine image contenuta nel
rettangolo di larghezza 23 pixel ed altezza 10.
Cos uno sprite: Per definizione uno sprite unimmagine bidimensionale che pu essere
spostata rispetto ad uno sfondo. Nei primi videogame questo veniva gestito direttamente via
hardware, per ottenere quindi leffetto di trasparenza.
Oggi per sprite intendiamo unimmagine 2D, generalmente formata da n frame; questi
vengono visualizzati uno alla volta in successione, in maniera da essere sovrapposti e da
dare limpressione di una continuit, di un movimento, fluido il pi possibile.
Queste immagini sono caratteristiche di varie tipologie di applicazioni, dai giochi di
ruolo 2D, dove sono utilizzati praticamente per ogni cosa, ad applicazioni con gestione del
testo, dove gli stessi font hanno uno sprite per ogni stile di caratteri, o charset.
Per essere eloquenti al massimo, lo stesso sistema adottato per le gif animate,
sostanzialmente.
Come applicare il concetto: Pensando come sviluppare un codice che realizzi questo
concetto, il pi facile che mi viene alla mente il seguente (vedi SDL_Example4):
// Prima del ciclo di loop
/* Variabili riguardanti la gestione degli sprites */
unsigned int frame_attuale=0;
SDL_Rect src;
src.x = (LARGHEZZA_IMMAGINE)*(frame_attuale);
src.y = 0 ;
src.w = LARGHEZZA_IMMAGINE;
src.h = ALTEZZA_IMMAGINE;
// Nel ciclo di loop, prima di disegnare
/* Cambio frame */
if (++frame_attuale >= NUMERO_FRAMES)
frame_attuale=0;
src.x = (LARGHEZZA_IMMAGINE)*(frame_attuale);
/* Disegno la frame */
SDL_BlitSurface_transparent(image, &src, screen, &dst, 0, 0, 0, 1, 0, 0);
Audio
La libreria SDL gestisce bene anche laspetto riguardante i suoni. Nel dettaglio, la
libreria ci mette a disposizione una serie di funzioni che rendono facile la riproduzione di
file audio: SDL_LoadWav(), SDL_OpenAudio(), SDL_PauseAudio(). SDL chiama
automaticamente una funzione di callback che copia i campioni dalla memoria di sistema al
buffer della scheda audio. Questa funzione devessere creata dallutente e il suo indirizzo,
assieme ai valori della frequenza di campionamento e della risoluzione dei campioni, deve
essere specificato nella struttura SDL_AudioSpec:
typedef struct{
int freq;
Uint16 format;
Uint8 channels;
Uint8 silence;
Uint16 samples;
Uint32 size;
void (*callback)(void *userdata, Uint8 *stream, int len);
void *userdata;
} SDL_AudioSpec;
freq - Frequenza di campionamento
Il numero di campioni copiati nel buffer della scheda audio al secondo. I valori pi comuni
sono 11025, 22050 e 44100. Pi il valore alto, migliore il suono.
format - Formato audio (1)
Specifica la dimensione ed il tipo di ogni campione:
AUDIO_U8 Campioni di tipo Unsigned 8-bit
AUDIO_S8 Signed 8-bit
AUDIO_U16 o AUDIO_U16LSB Unsigned 16-bit little-endian
AUDIO_S16 o AUDIO_S16LSB Signed 16-bit little-endian
AUDIO_U16MSB Unsigned 16-bit big-endian
AUDIO_S16MSB Signed 16-bit big-endian
AUDIO_U16SYS Sia AUDIO_U16LSB che AUDIO_U16MSB dipendenti
dal sistema endianness specifico
AUDIO_S16SYS Sia AUDIO_S16LSB che AUDIO_S16MSB dipendenti
dal sistema endianness specifico.
channels Numero di canali: 1 mono, 2 stereo
silence Valore di silenzio del buffer audio (calcolato automaticamente)
samples Dimensione del buffer audio, in campioni
size Dimensione, in byte, del buffer audio (calcolato automaticamente)
callback(..) Funzone di callback per copiare i campioni nel buffer della
scheda audio
userdata Puntatore ai parametri da passare alla funzione di callback.
SDL permette anche la gestione dellaudio da CD-ROM. Riporto qui di seguito la semplice
funzione ricavata dal sito http://www.libsdl.org:
void PlayTrack(SDL_CD *cdrom, int track)
{
if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) {
SDL_CDPlayTracks(cdrom, track, 0, track+1, 0);
}
while ( SDL_CDStatus(cdrom) == CD_PLAYING ) {
SDL_Delay(1000);
}
}
Si spiega da sola.
(1) Big, Middle e Little Endian sono le tre tipologie alternative alla memorizzazione di dati con dimensione base
superiore al byte. Per endianness si intende generalmente lordine dei byte.
Applicazioni Multi-threaded
A volte capita di dover affrontare problemi che trovano soluzione solo con
operazioni svolte in parallelo; purtroppo la gestione di 2 processi pesa parecchio al sistema,
quindi sono stati creati i thread, definibili come processi leggeri; ogni processo pu avere
pi thread, i quali condividono lo stesso spazio di indirizzamento.
La libreria SDL ci mette a disposizione funzioni per creare thread e per poterli
gestire. Prima di vedere quali sono queste funzioni necessario sapere a cosa necessario
prestare attenzione per evitare effetti indesiderati:
Prima di tutto pensa a tutte le possibili soluzioni alternative allutilizzo di un nuovo
thread;
Se non c altro modo, o se questo il pi efficace, bene evitare lutilizzo di
variabili globali su thread differenti;
Non terminare i threads, utilizza invece un flag e fai in modo che si chiuda
autonomamente; questo sia per evitare errori di esecuzione che il possibile memoryleak;
E preferibile non fare chiamate SDL Video/Event su pi threads.
SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data);
Questa funzione permette la creazione di un nuovo thread, avviando la funzione fn con
parametri data.
void SDL_WaitThread(SDL_Thread *thread, int *status);
Aspetta che un thread finisca; status il valore restituito dalla funzione main del thread
terminato.
void SDL_KillThread(SDL_Thread *thread);
Termina un determinato thread.
SDL permette anche la risoluzione del problema delle variabili condivise tramite
mutex, ovvero il procedimento di sincronizzazione che impedisce laccesso contemporaneo
di pi threads alla stessa risorsa, evitando cos errori parecchio fastidiosi. La conoscenza del
loro utilizzo v oltre lo scopo di questa guida.
Un esempio di operazione da svolgere in multi-threading la gestione della
comunicazione di rete; in questo caso, a meno che non si intenda bloccare il software in
attesa di un determinato pacchetto, o fino alla scadenza di un timeout, risulta fondamentale
lutilizzo di un secondo thread che gestisca in maniera autonoma la connessione.
I Timer
Tutte le operazioni svolte da un computer sono intervallate da un determinato tempo,
denominato clock. Questo devessere necessariamente gestito dal programmatore in questo
genere di applicazioni, ovvero dove si mette mano direttamente al codice del ciclo di loop. Il
non affrontare questo argomento compromette sensibilmente lesecuzione del software, il
quale sfrutterebbe tutta la memoria concessagli, rischiando di mandare in crash il sistema,
oltre che lapplicazione stessa.
La libreria SDL mette a disposizione delle funzioni per la gestione del tempo, una
delle quali SDL_GetTicks(), che restituisce il tempo trascorso dallavvio dellapplicazione
(in ms); anzi, per essere precisi, questo tempo riferito allinizializzazione della libreria.
Laltra funzione fondamentale SDL_Delay(), che attende il tempo, in ms, passatogli come
parametro. Questa funzione particolarmente precisa, se la rapportiamo ad altre disponibili
nelle librerie standard. Unaltra possibilit fornitaci dalla libreria quella di creare timer e
collegarci funzioni; si tratta quindi del classico evento OnTimer disponibile in quasi tutti i
linguaggi visuali.
ATTENZIONE: SDL mette a disposizione funzioni comode e molto utili, ma
compito del programmatore gestire in maniera efficace quello che nelle applicazioni grafiche
sono chiamati FPS (Frame per second). Non si tratta affatto di un argomento banale, anzi, ci
si sbatte la testa pi volte, nello sviluppo di applicazioni grafiche.
Per il mouse:
Uint8 mouse;
mouse = SDL_GetMouseState(mx,my); // mx e my sono puntatori a int
// in essi saranno salvate le coordinate del puntatore del mouse
// possono essere NULL
if ( mouse == SDL_EVENTO )
EVENTI TASTIERA
/* The keyboard syms have been cleverly chosen to map to ASCII */
SDLK_UNKNOWN
= 0,
SDLK_FIRST
= 0,
SDLK_BACKSPACE
= 8,
SDLK_TAB
= 9,
SDLK_CLEAR
= 12,
SDLK_RETURN
= 13,
SDLK_PAUSE
= 19,
SDLK_ESCAPE
= 27,
SDLK_SPACE
= 32,
SDLK_EXCLAIM
= 33,
SDLK_QUOTEDBL
= 34,
SDLK_HASH
= 35,
SDLK_DOLLAR
= 36,
SDLK_AMPERSAND
= 38,
SDLK_QUOTE
= 39,
SDLK_LEFTPAREN
= 40,
SDLK_RIGHTPAREN
= 41,
SDLK_ASTERISK
= 42,
SDLK_PLUS
= 43,
SDLK_COMMA
= 44,
SDLK_MINUS
= 45,
SDLK_PERIOD
= 46,
SDLK_SLASH
= 47,
SDLK_0
= 48,
SDLK_1
= 49,
SDLK_2
= 50,
SDLK_3
= 51,
SDLK_4
= 52,
SDLK_5
= 53,
SDLK_6
= 54,
SDLK_7
= 55,
SDLK_8
= 56,
SDLK_9
= 57,
SDLK_COLON
= 58,
SDLK_SEMICOLON
= 59,
SDLK_LESS
= 60,
SDLK_EQUALS
= 61,
SDLK_GREATER
= 62,
SDLK_QUESTION
= 63,
SDLK_AT
= 64,
/*
Skip uppercase letters
*/
SDLK_LEFTBRACKET = 91,
SDLK_BACKSLASH
= 92,
SDLK_RIGHTBRACKET= 93,
SDLK_CARET
= 94,
SDLK_UNDERSCORE
= 95,
SDLK_BACKQUOTE
= 96,
SDLK_a
= 97,
SDLK_b
= 98,
SDLK_c
= 99,
SDLK_d
= 100,
SDLK_e
= 101,
SDLK_f
= 102,
SDLK_g
= 103,
SDLK_h
= 104,
SDLK_i
= 105,
SDLK_j
= 106,
SDLK_k
= 107,
SDLK_l
= 108,
SDLK_m
= 109,
SDLK_n
= 110,
SDLK_o
= 111,
SDLK_p
= 112,
SDLK_q
= 113,
SDLK_r
= 114,
SDLK_s
= 115,
SDLK_t
= 116,
SDLK_u
= 117,
SDLK_v
= 118,
SDLK_w
= 119,
SDLK_x
= 120,
SDLK_y
= 121,
SDLK_z
= 122,
SDLK_DELETE
= 127,
/* End of ASCII mapped keysyms */
/* International keyboard syms */
SDLK_WORLD_0
= 160,
/* 0xA0 */
SDLK_WORLD_1
= 161,
SDLK_WORLD_2
= 162,
SDLK_WORLD_3
= 163,
SDLK_WORLD_4
= 164,
SDLK_WORLD_5
= 165,
SDLK_WORLD_6
= 166,
SDLK_WORLD_7
= 167,
SDLK_WORLD_8
= 168,
SDLK_WORLD_9
= 169,
SDLK_WORLD_10
= 170,
SDLK_WORLD_11
= 171,
SDLK_WORLD_12
= 172,
SDLK_WORLD_13
= 173,
SDLK_WORLD_14
= 174,
SDLK_WORLD_15
= 175,
SDLK_WORLD_16
= 176,
SDLK_WORLD_17
= 177,
SDLK_WORLD_18
= 178,
SDLK_WORLD_19
= 179,
SDLK_WORLD_20
= 180,
SDLK_WORLD_21
= 181,
SDLK_WORLD_22
= 182,
SDLK_WORLD_23
= 183,
SDLK_WORLD_24
= 184,
SDLK_WORLD_25
= 185,
SDLK_WORLD_26
= 186,
SDLK_WORLD_27
= 187,
SDLK_WORLD_28
= 188,
SDLK_WORLD_29
= 189,
SDLK_WORLD_30
= 190,
SDLK_WORLD_31
= 191,
SDLK_WORLD_32
= 192,
SDLK_WORLD_33
= 193,
SDLK_WORLD_34
= 194,
SDLK_WORLD_35
= 195,
SDLK_WORLD_36
= 196,
SDLK_WORLD_37
= 197,
SDLK_WORLD_38
= 198,
SDLK_WORLD_39
= 199,
SDLK_WORLD_40
= 200,
SDLK_WORLD_41
= 201,
SDLK_WORLD_42
SDLK_WORLD_43
SDLK_WORLD_44
SDLK_WORLD_45
SDLK_WORLD_46
SDLK_WORLD_47
SDLK_WORLD_48
SDLK_WORLD_49
SDLK_WORLD_50
SDLK_WORLD_51
SDLK_WORLD_52
SDLK_WORLD_53
SDLK_WORLD_54
SDLK_WORLD_55
SDLK_WORLD_56
SDLK_WORLD_57
SDLK_WORLD_58
SDLK_WORLD_59
SDLK_WORLD_60
SDLK_WORLD_61
SDLK_WORLD_62
SDLK_WORLD_63
SDLK_WORLD_64
SDLK_WORLD_65
SDLK_WORLD_66
SDLK_WORLD_67
SDLK_WORLD_68
SDLK_WORLD_69
SDLK_WORLD_70
SDLK_WORLD_71
SDLK_WORLD_72
SDLK_WORLD_73
SDLK_WORLD_74
SDLK_WORLD_75
SDLK_WORLD_76
SDLK_WORLD_77
SDLK_WORLD_78
SDLK_WORLD_79
SDLK_WORLD_80
SDLK_WORLD_81
SDLK_WORLD_82
SDLK_WORLD_83
SDLK_WORLD_84
SDLK_WORLD_85
SDLK_WORLD_86
SDLK_WORLD_87
SDLK_WORLD_88
= 202,
= 203,
= 204,
= 205,
= 206,
= 207,
= 208,
= 209,
= 210,
= 211,
= 212,
= 213,
= 214,
= 215,
= 216,
= 217,
= 218,
= 219,
= 220,
= 221,
= 222,
= 223,
= 224,
= 225,
= 226,
= 227,
= 228,
= 229,
= 230,
= 231,
= 232,
= 233,
= 234,
= 235,
= 236,
= 237,
= 238,
= 239,
= 240,
= 241,
= 242,
= 243,
= 244,
= 245,
= 246,
= 247,
= 248,
SDLK_WORLD_89
SDLK_WORLD_90
SDLK_WORLD_91
SDLK_WORLD_92
SDLK_WORLD_93
SDLK_WORLD_94
SDLK_WORLD_95
= 249,
= 250,
= 251,
= 252,
= 253,
= 254,
= 255,
/* Numeric keypad */
SDLK_KP0
= 256,
SDLK_KP1
= 257,
SDLK_KP2
= 258,
SDLK_KP3
= 259,
SDLK_KP4
= 260,
SDLK_KP5
= 261,
SDLK_KP6
= 262,
SDLK_KP7
= 263,
SDLK_KP8
= 264,
SDLK_KP9
= 265,
SDLK_KP_PERIOD
= 266,
SDLK_KP_DIVIDE
= 267,
SDLK_KP_MULTIPLY = 268,
SDLK_KP_MINUS
= 269,
SDLK_KP_PLUS
= 270,
SDLK_KP_ENTER
= 271,
SDLK_KP_EQUALS
= 272,
/* Arrows + Home/End pad */
SDLK_UP
= 273,
SDLK_DOWN
= 274,
SDLK_RIGHT
= 275,
SDLK_LEFT
= 276,
SDLK_INSERT
= 277,
SDLK_HOME
= 278,
SDLK_END
= 279,
SDLK_PAGEUP
= 280,
SDLK_PAGEDOWN
= 281,
/* Function keys */
SDLK_F1
SDLK_F2
SDLK_F3
SDLK_F4
SDLK_F5
SDLK_F6
SDLK_F7
SDLK_F8
= 282,
= 283,
= 284,
= 285,
= 286,
= 287,
= 288,
= 289,
/* 0xFF */
SDLK_F9
SDLK_F10
SDLK_F11
SDLK_F12
SDLK_F13
SDLK_F14
SDLK_F15
= 290,
= 291,
= 292,
= 293,
= 294,
= 295,
= 296,
EVENTI MOUSE
#define SDL_BUTTON(X)
(SDL_PRESSED << ((X)-1))
#define SDL_BUTTON_LEFT
1
#define SDL_BUTTON_MIDDLE
2
#define SDL_BUTTON_RIGHT 3
#define SDL_BUTTON_WHEELUP 4
#define SDL_BUTTON_WHEELDOWN
5
#define SDL_BUTTON_LMASK
SDL_BUTTON(SDL_BUTTON_LEFT)
#define SDL_BUTTON_MMASK
SDL_BUTTON(SDL_BUTTON_MIDDLE)
#define SDL_BUTTON_RMASK
SDL_BUTTON(SDL_BUTTON_RIGHT)
int i,j,decimale=0,aggiunta;
int xs, ys, xd, yd, ystmp, ydtmp;
int condizione_x, condizione_y;
Uint32 color, trpcolor;
trpcolor=getpixel(src, 0, 0);
if ( (srcrect==NULL) && (dstrect==NULL) )
{
xs=0;
ystmp=0;
xd=0;
ydtmp=0+decentramento_y;
condizione_x=src->w;
condizione_y=src->h;
if (flip==1) // flip orizzontale
xd+=src->w;
}
else
if (srcrect==NULL)
{
xs=0;
ystmp=0;
xd=dstrect->x;
ydtmp=dstrect->y+decentramento_y;
condizione_x=src->w;
condizione_y=src->h;
if (flip==1) // flip orizzontale
xd+=src->w;
}
else
if (dstrect==NULL)
{
xs=srcrect->x;
ystmp=srcrect->y;
xd=0;
ydtmp=0+decentramento_y;
condizione_x=(srcrect->w + srcrect->x);
condizione_y=(srcrect->h + srcrect->y);
if (flip==1) // flip orizzontale
xd+=srcrect->w;
}
else
{
xs=srcrect->x;
ystmp=srcrect->y;
xd=dstrect->x;
ydtmp=dstrect->y+decentramento_y;
condizione_x=(srcrect->w + srcrect->x);
condizione_y=(srcrect->h + srcrect->y);
if (flip==1) // flip orizzontale
xd+=srcrect->w;
}
else xd+=scala;
}
return 0;
}
Bibliografia
Using SDL with Microsoft Visual C++ 5,6 and 7 di Sam Lantinga, modificato da
Lion Kimbro and revisionato da James Turk;
SDL Library Documentation - http://docs.huihoo.com/sdl/1.2/guidevideo.html;
http://www.gameprog.it;
http://www.libsdl.org, sito ufficiale della libreria;
http://www.gnu.org/licenses/lgpl.html, citato relativamente alla licenza della libreria
SDL.