Creare una finestra mediante le funzioni del API di SDL2
La risorsa SDL2 mette a disposizione alcune librerie contenenti varie funzioni che consentono, fra l'altro, anche la creazione di finestre ove visualizzare testo, immagini ed altro.
Per creare e gestire in modo adeguato le finestre, bisognerà servirsi della seguente libreria condivisa: "libSDL2-2.0.so.0.3200.56 ".
Creare una finestra colorata e disegnarvi un quadrato
Mostriamo di seguito un semplice esempio per generare una finestra colorata di giallo, nella quale sarà disegnato un quadrato pieno di colore blu:
Library "libSDL2-2.0:0.3200.56"
Public Struct SDL_Rect
x As Integer
y As Integer
w As Integer
h As Integer
End Struct
Private Const SDL_INIT_VIDEO As Integer = &20
Private Const SDL_WINDOW_SHOWN As Integer = 4
Private Enum SDL_RENDERER_SOFTWARE = 1, SDL_RENDERER_ACCELERATED, SDL_RENDERER_PRESENTVSYNC = 4, SDL_RENDERER_TARGETTEXTURE = 8
' int SDL_Init(Uint32 flags)
' Initialize the SDL library.
Private Extern SDL_Init(flags As Integer) As Integer
' SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int w, int h, Uint32 flags)
' Creates a window with the specified position, dimensions, and flags.
Private Extern SDL_CreateWindow(title As String, xI As Integer, yI As Integer, width As Integer, height As Integer, flags As Integer) As Pointer
' const char* SDL_GetError(void)
' Returns a message with information about the specific error that occurred.
Private Extern SDL_GetError() As String
' SDL_Renderer* SDL_CreateRenderer(SDL_Window* window, int index, Uint32 flags)
' Creates a 2D rendering context for a window.
Private Extern SDL_CreateRenderer(sdl_window As Pointer, index As Integer, flags As Integer) As Pointer
' int SDL_SetRenderDrawColor(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
' Sets the color used for drawing operations (Rect, Line and Clear).
Private Extern SDL_SetRenderDrawColor(renderer As Pointer, rB As Byte, gB As Byte, bB As Byte, aB As Byte) As Integer
' int SDL_RenderClear(SDL_Renderer* renderer)
' Clears the current rendering target with the drawing color.
Private Extern SDL_RenderClear(renderer As Pointer) As Integer
' int SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect* rect)
' Draws a rectangle on the current rendering target.
Private Extern SDL_RenderDrawRect(renderer As Pointer, rect As SDL_Rect) As Integer
' int SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect* rect)
' Fills a rectangle on the current rendering target with the drawing color.
Private Extern SDL_RenderFillRect(renderer As Pointer, rect As SDL_Rect) As Integer
' void SDL_RenderPresent(SDL_Renderer * renderer)
' Update the screen with rendering performed.
Private Extern SDL_RenderPresent(renderer As Pointer)
' void SDL_DestroyWindow(SDL_Window* window)
' Destroy a window.
Private Extern SDL_DestroyWindow(sdl_window As Pointer)
' void SDL_Quit(void)
' Clean up all initialized subsystems.
Private Extern SDL_Quit()
Public Sub Main()
Dim finestra, rend As Pointer
Dim riquadro As New SDL_Rect
Dim s As String
SDL_Init(SDL_INIT_VIDEO)
finestra = SDL_CreateWindow("Titolo finestra", 50, 50, 640, 480, SDL_WINDOW_SHOWN)
If finestra == 0 Then Error.Raise("Impossibile creare la finestra: " & SDL_GetError())
rend = SDL_CreateRenderer(finestra, 0, SDL_RENDERER_ACCELERATED)
If rend == 0 Then Error.Raise("Errore alla funzione 'SDL_CreateRenderer': " & SDL_GetError())
SDL_SetRenderDrawColor(rend, 255, 255, 0, 255)
SDL_RenderClear(rend)
' Si imposta un riquadro 50x50 pixel all'interno della finestra:
With riquadro
.x = 20
.y = 20
.w = 50
.h = 50
End With
' Viene impostato il colore blu per i margini del riquadro:
SDL_SetRenderDrawColor(rend, 0, 0, 255, 255)
' Viene disegnato il riquadro:
SDL_RenderDrawRect(rend, riquadro)
' Il riquadro viene colorato di blu anche al suo interno:
SDL_RenderFillRect(rend, riquadro)
SDL_RenderPresent(rend)
' Per tenere aperta la finestra utilizziamo il seguente ciclo, dal quale si uscirà solo quando si invierà un qualsiasi carattere dalla console o dal Terminale:
Repeat
Input #File.In, s
Until s <> Null
' Va in chiusura:
SDL_DestroyWindow(finestra)
SDL_Quit()
End
Creare una finestra e caricarvi un'immagine
Mostriamo di seguito un semplice esempio per generare una finestra e caricarvi un'immagine. In questo caso la dimensione della finestra avrà le medesime dimensioni dell'immagine.
Poiché si farà uso della funzione "ImageStat()", sarà necessario attivare il Componente gb.image .
Library "libSDL2-2.0:0.3200.56"
Private Const SDL_INIT_VIDEO As Integer = &20
Private Const SDL_WINDOW_SHOWN As Integer = 4
Private Const SDL_WINDOWEVENT_CLOSE As Integer = 14
Private Const SDL_WINDOWEVENT As Integer = &200
Private Const SDL_KEYDOWN As Integer = &300
Private Const SDL_SCANCODE_ESCAPE As Integer = 41
Private Enum SDL_RENDERER_SOFTWARE = 1, SDL_RENDERER_ACCELERATED, SDL_RENDERER_PRESENTVSYNC = 4, SDL_RENDERER_TARGETTEXTURE = 8
' int SDL_Init(Uint32 flags)
' Initialize the SDL library.
Private Extern SDL_Init(flags As Integer) As Integer
' SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int w, int h, Uint32 flags)
' Creates a window with the specified position, dimensions, and flags.
Private Extern SDL_CreateWindow(title As String, xI As Integer, yI As Integer, width As Integer, height As Integer, flags As Integer) As Pointer
' const char* SDL_GetError(void)
' Returns a message with information about the specific error that occurred.
Private Extern SDL_GetError() As String
' SDL_Renderer* SDL_CreateRenderer(SDL_Window* window, int index, Uint32 flags)
' Creates a 2D rendering context for a window.
Private Extern SDL_CreateRenderer(sdl_window As Pointer, index As Integer, flags As Integer) As Pointer
' int SDL_RenderClear(SDL_Renderer* renderer)
' Clears the current rendering target with the drawing color.
Private Extern SDL_RenderClear(renderer As Pointer) As Integer
' int SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect)
' Copy a portion of the texture to the current rendering target.
Private Extern SDL_RenderCopy(renderer As Pointer, texture As Pointer, srcrect As Pointer, dstrect As Pointer) As Integer
' void SDL_RenderPresent(SDL_Renderer * renderer)
' Update the screen with rendering performed.
Private Extern SDL_RenderPresent(renderer As Pointer)
' int SDL_WaitEvent(SDL_Event* event)
' Wait indefinitely for the next available event.
Private Extern SDL_WaitEvent(SDL_event As Pointer) As Integer
' void SDL_DestroyWindow(SDL_Window* window)
' Destroy a window.
Private Extern SDL_DestroyWindow(sdl_window As Pointer)
' void SDL_Quit(void)
' Clean up all initialized subsystems.
Private Extern SDL_Quit()
Library "libSDL2_image-2.0:0.800.8"
' SDL_Texture * IMG_LoadTexture(SDL_Renderer *renderer, const char *file)
' Load an image directly into a render texture.
Private Extern IMG_LoadTexture(renderer As Pointer, _file As String) As Pointer
Public Sub Main()
Dim finestra, rend, tex, ev As Pointer
Dim file_immagine As String
Dim wImm, hImm As Integer
file_immagine = "/percorso/del/file/immagine"
wImm = ImageStat(file_immagine).Width
hImm = ImageStat(file_immagine).Height
SDL_Init(SDL_INIT_VIDEO)
finestra = SDL_CreateWindow("Titolo finestra", 50, 50, wImm, hImm, SDL_WINDOW_SHOWN)
If finestra == 0 Then Error.Raise("Impossibile creare la finestra: " & SDL_GetError())
rend = SDL_CreateRenderer(finestra, -1, SDL_RENDERER_ACCELERATED Or SDL_RENDERER_PRESENTVSYNC)
If rend == 0 Then Error.Raise("Errore alla funzione 'SDL_CreateRenderer': " & SDL_GetError())
' Carica un'immagine nella finestra:
tex = IMG_LoadTexture(rend, file_immagine)
SDL_RenderClear(rend)
SDL_RenderCopy(rend, tex, 0, 0)
SDL_RenderPresent(rend)
ev = Alloc(SizeOf(gb.Byte), 56)
' Resta in attesa che l'utente prema il tasto "Esc" per chiudere la finestra ed il programma:
Do
SDL_WaitEvent(ev)
' Individua il membro 'key' della "Union" 'SDL_Event':
Select Case Int@(ev)
Case SDL_KEYDOWN
' Se il valore del puntatore dereferenziato corrisponde al tasto "Esc", esce dal ciclo.
If Int@(ev + 16) = SDL_SCANCODE_ESCAPE Then Break
Case SDL_WINDOWEVENT
' Se il valore del puntatore dereferenziato corrisponde alla richiesta con il mouse di chiusura della finestra, esce dal ciclo.
If Int@(ev + 12) = SDL_WINDOWEVENT_CLOSE Then Break
End Select
Loop
' Libera la memoria precedentemente occupata e va in chiusura:
Free(ev)
ev = 0
SDL_DestroyWindow(finestra)
SDL_Quit()
End
Creare una finestra colorata e modificare l'aspetto del puntatore del mouse
In quest'altro esempio viene generata una finestra colorata di giallo e viene modificato l'aspetto del puntatore del mouse, che apparirà nel suo nuovo aspetto quando entrerà nella finestra.
Private cursore As String[] = [" 32 32 3 1",
"X c #000000",
". c #FFFFFF",
" c None",
"X ",
"XX ",
"X.X ",
"XXXX ",
"X...X ",
"XXXXXX ",
"X.....X ",
"XXXXXXXX ",
"X.......X ",
"XXXXXXXXXX ",
"X.....XXXXX ",
"XXXXXXX ",
"X.X X..X ",
"XX XXXX ",
"X X..X ",
" XXXX ",
" X..X ",
" XXXX ",
" XX ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
"0,0"]
Private s As String
Library "libSDL2-2.0:0.3200.56"
Private Const SDL_INIT_VIDEO As Integer = &20
Private Const SDL_WINDOWPOS_CENTERED As Integer = &2FFF0000
Private Const SDL_WINDOW_SHOWN As Integer = 4
Private Const SDL_WINDOWEVENT_CLOSE As Integer = 14
Private Const SDL_WINDOWEVENT As Integer = &200
Private Const SDL_KEYDOWN As Integer = &300
Private Const SDL_SCANCODE_ESCAPE As Integer = 41
Private Enum SDL_RENDERER_SOFTWARE = 1, SDL_RENDERER_ACCELERATED, SDL_RENDERER_PRESENTVSYNC = 4, SDL_RENDERER_TARGETTEXTURE = 8
' int SDL_Init(Uint32 flags)
' Initialize the SDL library.
Private Extern SDL_Init(flags As Integer) As Integer
' SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int w, int h, Uint32 flags)
' Creates a window with the specified position, dimensions, and flags.
Private Extern SDL_CreateWindow(title As String, xI As Integer, yI As Integer, width As Integer, height As Integer, flags As Integer) As Pointer
' const char* SDL_GetError(void)
' Returns a message with information about the specific error that occurred.
Private Extern SDL_GetError() As String
' SDL_Renderer* SDL_CreateRenderer(SDL_Window* window, int index, Uint32 flags)
' Creates a 2D rendering context for a window.
Private Extern SDL_CreateRenderer(sdl_window As Pointer, index As Integer, flags As Integer) As Pointer
' int SDL_SetRenderDrawColor(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
' Sets the color used for drawing operations (Rect, Line and Clear).
Private Extern SDL_SetRenderDrawColor(renderer As Pointer, rB As Byte, gB As Byte, bB As Byte, aB As Byte) As Integer
' int SDL_RenderClear(SDL_Renderer* renderer)
' Clears the current rendering target with the drawing color.
Private Extern SDL_RenderClear(renderer As Pointer) As Integer
' void SDL_RenderPresent(SDL_Renderer * renderer)
' Update the screen with rendering performed.
Private Extern SDL_RenderPresent(renderer As Pointer)
' SDL_Cursor* SDL_CreateCursor(const Uint8* data, const Uint8* mask, int w, int h, int hot_x, int hot_y)
' To create a cursor using the specified bitmap data and mask (in MSB format).
Private Extern SDL_CreateCursor(data As Pointer, mask As Pointer, w As Integer, h As Integer, hot_x As Integer, hot_y As Integer) As Pointer
' void SDL_SetCursor(SDL_Cursor* cursor)
' To set the active cursor.
Private Extern SDL_SetCursor(cursor As Pointer)
' int SDL_WaitEvent(SDL_Event* event)
' Wait indefinitely for the next available event.
Private Extern SDL_WaitEvent(SDL_event As Pointer) As Integer
' void SDL_DestroyWindow(SDL_Window* window)
' Destroy a window.
Private Extern SDL_DestroyWindow(sdl_window As Pointer)
' void SDL_Quit(void)
' Clean up all initialized subsystems.
Private Extern SDL_Quit()
Public Sub Main()
Dim finestra, rend, cur, ev As Pointer
SDL_Init(SDL_INIT_VIDEO)
finestra = SDL_CreateWindow("Titolo finestra", 50, 50, 640, 480, SDL_WINDOW_SHOWN)
If finestra == 0 Then Error.Raise("Impossibile creare la finestra: " & SDL_GetError())
rend = SDL_CreateRenderer(finestra, 0, SDL_RENDERER_ACCELERATED)
If rend == 0 Then Error.Raise("Impossibile creare un contesto rendering 2D per la finestra: " & SDL_GetError())
SDL_SetRenderDrawColor(rend, 255, 255, 0, 255)
SDL_RenderClear(rend)
SDL_RenderPresent(rend)
cur = CreaCursore()
SDL_SetCursor(cur)
ev = Alloc(SizeOf(gb.Byte), 56)
' Resta in attesa che l'utente prema il tasto "Esc" per chiudere la finestra ed il programma:
Do
SDL_WaitEvent(ev)
' Individua il membro 'key' della "Union" 'SDL_Event':
Select Case Int@(ev)
Case SDL_KEYDOWN
' Se il valore del puntatore dereferenziato corrisponde al tasto "Esc", esce dal ciclo.
If Int@(ev + 16) = SDL_SCANCODE_ESCAPE Then Break
Case SDL_WINDOWEVENT
' Se il valore del puntatore dereferenziato corrisponde alla richiesta con il mouse di chiusura della finestra, esce dal ciclo.
If Int@(ev + 12) = SDL_WINDOWEVENT_CLOSE Then Break
End Select
Loop
' Libera la memoria precedentemente occupata e va in chiusura:
Free(ev)
SDL_DestroyWindow(finestra)
SDL_Quit()
End
Private Function CreaCursore() As Pointer
Dim i, row, col As Integer
Dim data As New Byte[4 * 32]
Dim mask As New Byte[4 * 32]
i = -1
For row = 0 To 32 - 1
For col = 0 To 32 - 1
If col Mod 8 Then
data[i] = Shl(data[i], 1)
mask[i] = Shl(mask[i], 1)
Else
Inc i
mask[i] = 0
data[i] = mask[i]
Endif
Select Case Mid(cursore[4 + row], col + 1, 1)
Case "X"
data[i] = data[i] Or &01
mask[i] = mask[i] Or &01
Case "."
mask[i] = mask[i] Or &01
End Select
Next
Next
Return SDL_CreateCursor(data.data, mask.data, 32, 32, Left(cursore[4 + row], 1), Right(cursore[4 + row], 1))
End