Creare una finestra e disegnarvi una scacchiera con le funzioni del API di SDL2

Da Gambas-it.org - Wikipedia.

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.3000.0.

Il seguente codice permetterà di creare una finestra renderizzata e di disegnarvi una scacchiera bianco-nera. Per chiudere la finestra, si dovrà premere il tasto Esc della tastiera.

Library "libSDL2-2.0:0.3000.0"

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 Const SDL_WINDOWPOS_UNDEFINED_MASK As Integer = &1FFF0000
Private Const SDL_KEYDOWN As Integer = &300
Private Const SDL_SCANCODE_ESCAPE As Integer = 41

' 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

' SDL_Surface* SDL_GetWindowSurface(SDL_Window* window)
' Returns the surface associated with the window.
Private Extern SDL_GetWindowSurface(SDL_window As Pointer) As Pointer

' SDL_Renderer* SDL_CreateSoftwareRenderer(SDL_Surface* surface)
' Create a 2D software rendering context for a surface.
Private Extern SDL_CreateSoftwareRenderer(SDL_surface As Pointer) 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_WaitEvent(SDL_Event* event)
' Wait indefinitely for the next available event.
Private Extern SDL_WaitEvent(SDL_event As Pointer) As Integer

' void SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect)
' Get the drawing area for the current target.
Private Extern SDL_RenderGetViewport(SDL_renderer As Pointer, SDL_rect As SDL_Rect)

' 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

' int SDL_UpdateWindowSurface(SDL_Window* window)
' Copy the window surface to the screen.
Private Extern SDL_UpdateWindowSurface(SDL_window 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 i As Integer
 Dim finestra, superficie, rend, ev As Pointer
 
' Inizializa la libreria SDL:
 i = SDL_Init(SDL_INIT_VIDEO)
 If i <> 0 Then Error.Raise("Inizializzazione della libreria SDL2: fallita !")

' Crea una finestra e la predispone per una data superficie:
 finestra = SDL_CreateWindow("Scacchiera", SDL_WINDOWPOS_UNDEFINED_MASK, SDL_WINDOWPOS_UNDEFINED_MASK, 640, 640, SDL_WINDOW_SHOWN)
 If finestra == 0 Then Error.Raise("Creazione della finestra: fallita !")
 
 superficie = SDL_GetWindowSurface(finestra)
 If superficie == 0 Then Error.Raise("Errore !")
 
 rend = SDL_CreateSoftwareRenderer(superficie)
 If rend == 0 Then Error.Raise("Creazione della finestra: fallita !")

' Copre la superficie renderizzata con il colore nero:
 SDL_SetRenderDrawColor(rend, 0, 0, 0, 255)
 SDL_RenderClear(rend)
      
' Disegna l'immagine sulla superficie renderizzata:
 Disegna_Scacchiera(rend)
   
' Aggiorna l'immagine disegnata sulla finestra:
 SDL_UpdateWindowSurface(finestra)
 
 ev = Alloc(SizeOf(gb.Byte), 56)

' Resta in attesa che l'utente prema il tasto "Esc" per chiudere la finestra ed il programma:
 While True
   SDL_WaitEvent(ev)
' Individua il membro 'key' della "Union" 'SDL_Event':
   If Int@(ev) = SDL_KEYDOWN Then
' Individua il membro 'keysym' della "Struttura" 'SDL_KeyboardEvent':
     ev = ev + 16
' Verifica se il valore del puntatore dereferenziato corrisponde al membro 'scancode' della "Struttura" 'SDL_Keysym'.
' Se corrisponde, allora esce dal ciclo:
     If Int@(ev) = SDL_SCANCODE_ESCAPE Then Break
   Endif    
 Wend

' Va in chiusura:
 SDL_DestroyWindow(finestra)
 SDL_Quit()
 Free(ev)
 ev = 0 

End


Private Procedure Disegna_Scacchiera(render As Pointer)
 
 Dim rigo, colonna, x As Integer
 Dim rett, area As New SDL_Rect
 
' Ottiene la dimensione della superficie di disegno:
 SDL_RenderGetViewport(render, area)
   
 For rigo = 0 To 7
   colonna = rigo Mod 2
   x = x + colonna
   For colonna = 0 To 3 + (rigo Mod 2)
     SDL_SetRenderDrawColor(render, 255, 255, 255, 255)
     rett.w = area.w / 8
     rett.h = area.h / 8
     rett.x = x * rett.w
     rett.y = rigo * rett.h
     x = x + 2
     SDL_RenderFillRect(render, rett)
   Next
   x = 0
 Next
    
End


Riferimenti