Author Topic: SDL2 - Simple DirectMedia Layer in UASM  (Read 913 times)

LiaoMi

  • Member
  • ****
  • Posts: 711
SDL2 - Simple DirectMedia Layer in UASM
« on: March 02, 2020, 10:33:10 PM »
Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D. It is used by video playback software, emulators, and popular games including Valve's award winning catalog and many Humble Bundle games.

SDL officially supports Windows, Mac OS X, Linux, iOS, and Android. Support for other platforms may be found in the source code.

SDL is written in C, works natively with C++, and there are bindings available for several other languages, including C# and Python.

SDL 2.0 is distributed under the zlib license. This license allows you to use SDL freely in any software.

SDL version 2.0.10 (stable - Development Libraries) 25.07.2019 -
SDL2-devel-2.0.10-VC.zip (Visual C++ 32/64-bit) https://www.libsdl.org/release/SDL2-devel-2.0.10-VC.zip
SDL2-devel-2.0.10-mingw.tar.gz (MinGW 32/64-bit) https://www.libsdl.org/release/SDL2-devel-2.0.10-mingw.tar.gz
Mac OS X SDL2-2.0.10.dmg https://www.libsdl.org/release/SDL2-2.0.10.dmg
Linux https://www.archlinux.org/packages/extra/x86_64/sdl2/download/
Source Code https://www.libsdl.org/release/SDL2-2.0.10.zip

SDL2-2.0.10-win32-x86.zip (32-bit Windows) SDL.dll https://www.libsdl.org/release/SDL2-2.0.10-win32-x86.zip
SDL2-2.0.10-win32-x64.zip (64-bit Windows) SDL.dll https://www.libsdl.org/release/SDL2-2.0.10-win32-x64.zip

Implementation of Mandelbrot set using NASM and C with SDL https://github.com/skalermo/ARKO-Mandelbrot-Set/archive/master.zip

Jazon Yamamoto - The Black Art of Multiplatform Game Programming-Cengage Learning PTR (2014) Source code - http://www.delmarlearning.com/companions/content/1305110382/companionfiles/BAMGP.zip
There are many working examples with the source codes of programs, it covers not only the game world, it mainly describes the technology of sdl.

Mandelbrot-set-x86 - This program draws Mandelbrot set computed in x86 assembly language (nasm) in SDL2-powered window - https://github.com/piter324/Mandelbrot-set-x86/archive/master.zip

Fasm with SDL.DLL - https://board.flatassembler.net/topic.php?t=14324
SDL_Animation (Source + Bin) - https://board.flatassembler.net/download.php?id=6714

+

Code: [Select]
format PE GUI 4.0

include 'win32ax.inc'

SDL_INIT_EVERYTHING            = 0x0000FFFF
SDL_SWSURFACE                   = 0

.code
start:
      invoke  SDL_Init,SDL_INIT_EVERYTHING
        invoke  SDL_SetVideoMode,640,480,32,SDL_SWSURFACE
                   mov     [screen],eax
        invoke  SDL_RWFromFile,"hello.bmp","rb"
 invoke  SDL_LoadBMP_RW,eax,1
                        mov     [hello],eax
 invoke  SDL_UpperBlit,[hello],NULL,[screen],NULL
    invoke  SDL_Flip,[screen]
   invoke  SDL_Delay,2000
      invoke  SDL_FreeSurface,[hello]
     invoke  SDL_Quit

.data
       hello   dd 0
        screen  dd 0

section '.idata' import data readable writeable
library        kernel32,       'kernel32.dll',\
         user32,         'user32.dll',\
           msvcrt,         'msvcrt.dll',\
           sdl,            'sdl.dll'
         
            include 'API\KERNEL32.INC'
               include 'API\USER32.INC'
         include 'API\MSVCRT.INC'
         include 'API\SDL.INC'
SDL.INC - https://board.flatassembler.net/download.php?id=6010


Simple FASM game engine with SDL2 (Source + Bin) - https://board.flatassembler.net/download.php?id=7810

LiaoMi

  • Member
  • ****
  • Posts: 711
Re: SDL2 - Simple DirectMedia Layer in UASM
« Reply #1 on: March 02, 2020, 10:35:16 PM »
Basic example SDL2 in win64 - https://board.flatassembler.net/topic.php?t=21289

Example A
Code: [Select]
format PE64 GUI 5.0

entry start

XRES equ 1024
YRES equ 600

include 'win64w.inc'
include 'sdl2.inc'

section '' code readable executable

start:
        sub     rsp,8

        cinvoke SDL_CreateWindow,_title,\
                          SDL_WINDOWPOS_UNDEFINED,\
                          SDL_WINDOWPOS_UNDEFINED,\
                          [viewport.w], [viewport.h],\
                          SDL_WINDOW_SHOWN
        test    eax,eax
        jz      initialization_error
        mov     [window],eax

        cinvoke SDL_CreateRenderer,eax,-1,SDL_RENDERER_PRESENTVSYNC
        test    eax,eax
        jnz     renderer_ready
        cinvoke SDL_CreateRenderer,[window],-1,0
        test    eax,eax
        jz      initialization_error
    renderer_ready:
        mov     [renderer],eax
        cinvoke SDL_RenderSetLogicalSize,[renderer],[viewport.w],[viewport.h]

        cinvoke SDL_SetRenderDrawColor,[renderer],120,180,0,255
        cinvoke SDL_RenderClear,[renderer]
        cinvoke SDL_RenderPresent,[renderer]

  poll_event:
        cinvoke SDL_PollEvent,event
        test    eax,eax
        jnz     process_event

  process_event:
        cmp     [event.type],SDL_QUIT
        je      quit

  event_processed:
        jmp     poll_event


  initialization_error:
        invoke  MessageBox,HWND_DESKTOP,_intialization_error,_title,MB_ICONERROR+MB_OK
  quit:
        cinvoke SDL_DestroyWindow,[window]
        cinvoke SDL_Quit


section '.data' data readable writeable

  _title db "SDL2 example",0
  _intialization_error db "Initialization failed.",0

  viewport SDL_Rect 0,0,XRES,YRES

  window dd ?
  renderer dd ?

  event SDL_Event

section '.idata' import readable

  library kernel32,'KERNEL32',\
          user32,'USER32',\
          sdl2,'SDL2'
  include 'api\kernel32.inc'
  include 'api\user32.inc'
  include 'sdl2_api.inc'   

Example B
Code: [Select]
format PE64 GUI 5.0

entry start

XRES equ 1024
YRES equ 600

include 'win64w.inc'
include 'sdl2.inc'

section '' code readable executable

start:
        sub     rsp,8

        cinvoke SDL_CreateWindow,_title,\
                          SDL_WINDOWPOS_UNDEFINED,\
                          SDL_WINDOWPOS_UNDEFINED,\
                          [viewport.w], [viewport.h],\
                          SDL_WINDOW_SHOWN
        test    eax,eax
        jz      initialization_error
        mov     [window],eax

        cinvoke SDL_GetWindowSurface,[window]
        mov     rbx,rax

        mov     rdi,[rbx+SDL_Surface.pixels]
        mov     edx,[viewport.h]
    paint:
        mov     al,dl
        and     eax,7Fh
        imul    eax,020102h
        or      eax,0FF000000h
        mov     ecx,[viewport.w]
        push    rdi
        rep     stosd
        pop     rdi
        mov     eax,[rbx+SDL_Surface.pitch]
        add     rdi,rax
        dec     edx
        jnz     paint
        cinvoke SDL_UpdateWindowSurface,[window]

  poll_event:
        cinvoke SDL_PollEvent,event
        test    eax,eax
        jnz     process_event

  process_event:
        cmp     [event.type],SDL_QUIT
        je      quit

  event_processed:
        jmp     poll_event


  initialization_error:
        invoke  MessageBox,HWND_DESKTOP,_intialization_error,_title,MB_ICONERROR+MB_OK
  quit:
        cinvoke SDL_DestroyWindow,[window]
        cinvoke SDL_Quit


section '.data' data readable writeable

  _title db "SDL2 example",0
  _intialization_error db "Initialization failed.",0

  viewport SDL_Rect 0,0,XRES,YRES

  window dd ?

  event SDL_Event

section '.idata' import readable

  library kernel32,'KERNEL32',\
          user32,'USER32',\
          sdl2,'SDL2'
  include 'api\kernel32.inc'
  include 'api\user32.inc'
  include 'sdl2_api.inc'   

LiaoMi

  • Member
  • ****
  • Posts: 711
Re: SDL2 - Simple DirectMedia Layer in UASM
« Reply #2 on: March 02, 2020, 10:37:21 PM »
64 bit Linux SDL Audio example - https://board.flatassembler.net/topic.php?t=15083
Quote
This plays Ode to Joy by Beethoven in sine waves. It was the first 64 bit Linux program I wrote. I think it's quite well commented. Tested on Fedora and Ubuntu. You'll need the program SDL and its development package (which provides sdl-config).
Code: [Select]
format ELF64

public main

extrn 'SDL_Init' as SDL_Init:qword
extrn 'SDL_Quit' as SDL_Quit:qword
extrn 'SDL_OpenAudio' as SDL_OpenAudio:qword
extrn 'SDL_CloseAudio' as SDL_CloseAudio:qword
extrn 'SDL_PauseAudio' as SDL_PauseAudio:qword
extrn 'SDL_Delay' as SDL_Delay:qword

extrn 'exit' as exit:qword

AUDIOS16LSB equ 0x8010
SDL_INIT_AUDIO equ 0x00000010

struc SDL_AudioSpec
{
        .freq dd ?
        .format dw ?
        .channels db ?
        .silence db ?
        .samples dw ?
        dw ?
        .size dd ?
        .callback dq ?
        .userdata dq ?
}

SAMPLE_RATE equ 44100 ; samples per second
TEMPO equ 160 ; beats per minute
CROTCHETS_PER_SECOND equ (4 * (TEMPO / 60)) ; quarter beats per second
CROTCHET_DURATION equ (1000 / CROTCHETS_PER_SECOND) ; length of a quarter beat in ms
SAMPLES_PER_CROTCHET equ (SAMPLE_RATE / CROTCHETS_PER_SECOND) ; samples per quarter beat

; macro for declaration of note data
macro NOTE f,d
{
        local .frequency, .duration
        .frequency dq f ; floating point frequency in Hz
        .duration dq d ; duration in quarter notes
}

section '.data' writable

audio_desired SDL_AudioSpec

NEGATIVE_ONE dq -1.0
MAX_SIGNED_SHORT dq 32767.0 ; max signed value that can be stored in a 2 byte integer
TWO_TIMES_PI dq 6.2831
ANGLE dq 0.0 ; current input to sine function
STEP_SIZE dq 0.0 ; rate at which to step through sine function
AMPLITUDE dq 1.0 ; current volume
SAMPLES_THIS_NOTE dq 0 ; samples REMAINING for the current note
CROTCHETS_THIS_NOTE dq 0 ; current note length in quarter beats
TEMP dq 0
SAMPLE dw 0 ; storage for integer audio sample
align 8
MUSIC_PLAYING dq 1 ; controls when the program ends
MUSIC_REST dq 0 ; is the current note a rest?

NOTE_POINTER dq MUSIC ; pointer to current note

; frequencies for the notes

G2 equ 195.998
C3 equ 261.626
D3 equ 293.664
E3 equ 329.628
F3 equ 349.228
G3 equ 391.996

; music melody

MUSIC:

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE E3, 4
NOTE 0,2
NOTE D3, 2
NOTE D3, 6
NOTE 0, 2

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 4
NOTE 0,2
NOTE C3, 2
NOTE C3, 6
NOTE 0, 2

NOTE D3, 6
NOTE 0, 2
NOTE E3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 4
NOTE E3, 2
NOTE F3, 2
NOTE E3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 4
NOTE E3, 2
NOTE F3, 2
NOTE E3, 2
NOTE 0, 2
NOTE D3, 2
NOTE 0, 2
NOTE C3, 2
NOTE 0, 2
NOTE D3, 2
NOTE 0, 2
NOTE G2, 6
NOTE 0, 2

NOTE E3,2
NOTE 0,2
NOTE E3,2
NOTE 0,2
NOTE F3,2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE G3, 2
NOTE 0,2
NOTE F3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE C3, 2
NOTE 0,2
NOTE D3, 2
NOTE 0,2
NOTE E3, 2
NOTE 0,2
NOTE D3, 4
NOTE 0,2
NOTE C3, 2
NOTE C3, 6
NOTE 0, 2

dq -1.0 ; note data ends

section '.text' executable

main:

push rbp
mov rbp, rsp

mov rax, 0
mov rdi, SDL_INIT_AUDIO
call SDL_Init

mov [audio_desired.freq], SAMPLE_RATE
mov [audio_desired.format], AUDIOS16LSB
mov [audio_desired.channels], 1
mov [audio_desired.silence], 0
mov [audio_desired.samples], 4096
mov [audio_desired.size], 8192
mov [audio_desired.callback], audio_callback
mov [audio_desired.userdata], 0

mov rax, 0
mov rdi, audio_desired
mov rsi, 0
call SDL_OpenAudio

; unpause audio
mov rax, 0
mov rdi, 0
call SDL_PauseAudio

call next_note

; loop till we hit the last note
.main_loop:

; small delay to avoid maxing out CPU
mov rax, 0
mov rdi, CROTCHET_DURATION
call SDL_Delay

mov rax, [MUSIC_PLAYING]
cmp rax, 0
jz .exit_main_loop

jmp .main_loop
.exit_main_loop:

mov rax, 0
call SDL_CloseAudio

mov rax, 0
call SDL_Quit

mov rax, 0
mov rdi, 0
call exit

; SDL calls this function when it requires audio data

audio_callback:

push rbx rbp r12 r13 r14 r15
sub rsp, 8

; get the number of bytes of audio samples
; divide by two because each sample comprises 2 bytes
; store in rbx

mov rax, rdx
mov rbx, 2
mov rdx, 0
idiv rbx
mov rbx, rax

mov rdi, rsi ; put audio buffer pointer in rdi

; loop to write the audio samples into the buffer

mov rcx, 0 ; initialise counter

.loop:

; if there are no samples remaining to be written for the current note, progress to the next note
cmp [SAMPLES_THIS_NOTE], 0
jnz .skip_next_note

push rdi rcx
call next_note
pop rcx rdi

.skip_next_note:

cmp rcx, rbx ; exit the loop if we've reached the end of the audio buffer
jge .exit_loop

cmp [MUSIC_REST], 1 ; if the current note is a rest, skip writing the samples
je .rest

; calculate amplitude (volume)
; amplitude = samples_still_unwritten / (crotchets_this_note * samples_per_crotchet)
mov rax, [CROTCHETS_THIS_NOTE]
imul rax, SAMPLES_PER_CROTCHET
mov [TEMP], rax
fild [TEMP]
mov rsi, [SAMPLES_THIS_NOTE]
mov [TEMP], rsi
fild [TEMP]
fdivrp st1, st
fstp qword [AMPLITUDE]
fwait

; obtain our sine value and store it in memory as a 2 byte word
; sample = sin(angle) * amplitude * max_signed_short
fld qword [AMPLITUDE]
fld qword [MAX_SIGNED_SHORT]
fld qword [ANGLE]
fsin
fmulp st1, st
fmulp st1, st
fistp word [SAMPLE]

; transfer the sample into the audio buffer
mov si, [SAMPLE]
mov word [rdi + rcx * 2], si

; increase angle by step size

fld qword [STEP_SIZE]
fld qword [ANGLE]
faddp st1, st

; compare the angle to (2.0 * Pi)

fcom qword [TWO_TIMES_PI]
fstsw ax
fwait
sahf
jb .skip ; if the angle is less than (2.0 * Pi), skip the next instruction

fsub qword [TWO_TIMES_PI] ; reduce the angle by (2.0 * Pi) to bring it back within the range 0.0 to 2.0 * Pi

.skip:
fstp qword [ANGLE] ; write the new angle

.rest:

dec [SAMPLES_THIS_NOTE] ; decrease sample counter

inc rcx ; increase offset into audio buffer

jmp .loop
.exit_loop:

add rsp, 8
pop r15 r14 r13 r12 rbp rbx
ret

next_note:

push rbx

; restore amplitude (volume) to 1.0

fld1
fstp qword [AMPLITUDE]

; load the new note's frequency (measured in Hz) and duration (measured in quarter-notes)
; also store the length of the note in quarter-notes, and the length of the note in samples

mov rsi, [NOTE_POINTER]
mov rsi, [rsi + 8]
mov [CROTCHETS_THIS_NOTE], rsi
imul rsi, SAMPLES_PER_CROTCHET
mov [SAMPLES_THIS_NOTE], rsi
mov rbx, [NOTE_POINTER]
mov rbx, [rbx]

cmp rbx, [NEGATIVE_ONE]; negative one marks the end of the music
jne .skip

mov [MUSIC_PLAYING], 0 ; tell the main thread the program has finished

pop rbx
ret

.skip:

cmp rbx, 0.0 ; if frequency is 0.0, the note is a rest so next few calculations are not needed
jz .rest

mov [MUSIC_REST], 0 ; not a rest

; calculate the rate at which we need to step through the sine function's domain
; step_size = (2.0 * Pi) / (sample_rate / frequency)
mov [TEMP], rbx
fld [TEMP]
mov [TEMP], SAMPLE_RATE
fild [TEMP]
fdivrp st1, st
fld [TWO_TIMES_PI]
fdivrp st1, st
fstp [STEP_SIZE]
fwait

jmp .skip_rest
.rest:
mov [MUSIC_REST], 1 ; note is a rest
.skip_rest:

; progress to the next note

mov rbx, [NOTE_POINTER]
add rbx, 16
mov [NOTE_POINTER], rbx

mov [ANGLE], 0.0 ; reset angle for new frequency

pop rbx
ret
   

LiaoMi

  • Member
  • ****
  • Posts: 711
Re: SDL2 - Simple DirectMedia Layer in UASM
« Reply #3 on: March 02, 2020, 10:38:22 PM »

Mouse Pixel Test - https://board.flatassembler.net/topic.php?t=12775
SDL.inc
Code: [Select]
; SDL.INC

SDL_INIT_TIMER =       0x00000001
SDL_INIT_AUDIO =       0x00000010
SDL_INIT_VIDEO =       0x00000020
SDL_INIT_CDROM =       0x00000100
SDL_INIT_JOYSTICK =    0x00000200
SDL_INIT_NOPARACHUTE = 0x00100000      ; Don't catch fatal signals
SDL_INIT_EVENTTHREAD = 0x01000000      ; Not supported on all OS's
SDL_INIT_EVERYTHING =  0x0000FFFF

SDL_SWSURFACE =  0x00000000    ;  /**< Surface is in system memory */
SDL_HWSURFACE =  0x00000001     ; /**< Surface is in video memory */
SDL_ASYNCBLIT =  0x00000004  ; /**< Use asynchronous blits if possible */

SDL_ANYFORMAT =  0x10000000      ; /**< Allow any video depth/pixel-format */
SDL_HWPALETTE =  0x20000000  ; /**< Surface has exclusive palette */
SDL_DOUBLEBUF =  0x40000000       ; /**< Set up double-buffered video mode */
SDL_FULLSCREEN = 0x80000000   ; /**< Surface is a full screen display */
SDL_OPENGL =    0x00000002     ; /**< Create an OpenGL rendering context */
SDL_OPENGLBLIT = 0x0000000A  ; /**< Create an OpenGL rendering context and use it for blitting */
SDL_RESIZABLE =  0x00000010          ;/**< This video mode may be resized */
SDL_NOFRAME =      0x00000020             ; No window caption or edge frame */

SDLK_0                      = 48
SDLK_1                  = 49
SDLK_2                  = 50
SDLK_3                  = 51

;------------------------------------------------------------------------------
;
; SDL_EVENTs STUFF
;
;------------------------------------------------------------------------------
SDL_RELEASED = 0
SDL_PRESSED =  1

;
SDL_NOEVENT = 0              ; Unused (do not remove)
SDL_ACTIVEEVENT = 1         ; Application loses/gains visibility
SDL_KEYDOWN = 2                 ; Keys pressed
SDL_KEYUP = 3                 ; Keys released
SDL_MOUSEMOTION = 4          ; Mouse moved
SDL_MOUSEBUTTONDOWN = 5        ; Mouse button pressed
SDL_MOUSEBUTTONUP = 6         ; Mouse button released
SDL_JOYAXISMOTION = 7                ; Joystick axis motion
SDL_JOYBALLMOTION = 8         ; Joystick trackball motion
SDL_JOYHATMOTION = 9             ; Joystick hat position change
SDL_JOYBUTTONDOWN = 10                ; Joystick button pressed
SDL_JOYBUTTONUP = 11               ; Joystick button released
SDL_QUIT = 12                     ; User-requested quit
SDL_SYSWMEVENT = 13            ; System specific event
SDL_EVENT_RESERVEDA = 14     ; Reserved for future use..
SDL_EVENT_RESERVEDB = 15 ; Reserved for future use..
SDL_VIDEORESIZE = 16             ; User resized video mode
SDL_VIDEOEXPOSE = 17               ; Screen needs to be redrawn
SDL_EVENT_RESERVED2 = 18        ; Reserved for future use..
SDL_EVENT_RESERVED3 = 19 ; Reserved for future use..
SDL_EVENT_RESERVED4 = 20 ; Reserved for future use..
SDL_EVENT_RESERVED5 = 21 ; Reserved for future use..
SDL_EVENT_RESERVED6 = 22 ; Reserved for future use..
SDL_EVENT_RESERVED7 = 23 ; Reserved for future use..

; Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use
SDL_USEREVENT = 24

; This last event is only for bounding internal arrays
; It is the number of bits in the event mask datatype -- Uint32
SDL_NUMEVENTS = 32

SDL_ACTIVEEVENTMASK      = 1 shl SDL_ACTIVEEVENT
SDL_KEYDOWNMASK      = 1 shl SDL_KEYDOWN
SDL_KEYUPMASK            = 1 shl SDL_KEYUP
SDL_KEYEVENTMASK   = (1 shl SDL_KEYDOWN) or \
                   (1 shl SDL_KEYUP)
SDL_MOUSEMOTIONMASK      = 1 shl SDL_MOUSEMOTION
SDL_MOUSEBUTTONDOWNMASK = 1 shl SDL_MOUSEBUTTONDOWN
SDL_MOUSEBUTTONUPMASK = 1 shl SDL_MOUSEBUTTONUP
SDL_MOUSEEVENTMASK = (1 shl SDL_MOUSEMOTION) or \
                       (1 shl SDL_MOUSEBUTTONDOWN) or \
                   (1 shl SDL_MOUSEBUTTONUP)
SDL_JOYAXISMOTIONMASK    = 1 shl SDL_JOYAXISMOTION
SDL_JOYBALLMOTIONMASK      = 1 shl SDL_JOYBALLMOTION
SDL_JOYHATMOTIONMASK       = 1 shl SDL_JOYHATMOTION
SDL_JOYBUTTONDOWNMASK       = 1 shl SDL_JOYBUTTONDOWN
SDL_JOYBUTTONUPMASK        = 1 shl SDL_JOYBUTTONUP
SDL_JOYEVENTMASK     = (1 shl SDL_JOYAXISMOTION) or \
                     (1 shl SDL_JOYBALLMOTION) or \
                     (1 shl SDL_JOYHATMOTION) or \
                      (1 shl SDL_JOYBUTTONDOWN) or \
                     (1 shl SDL_JOYBUTTONUP)
SDL_VIDEORESIZEMASK        = 1 shl SDL_VIDEORESIZE
SDL_VIDEOEXPOSEMASK  = 1 shl SDL_VIDEOEXPOSE
SDL_QUITMASK         = 1 shl SDL_QUIT
SDL_SYSWMEVENTMASK  = 1 shl SDL_SYSWMEVENT

SDL_ALLEVENTS = 0xFFFFFFFF

;------------------------------------------------------------------------------
;
; STRUCTURES
;
;------------------------------------------------------------------------------

struct SDL_Rect
  x dw ?
  y dw ?
  w dw ?
  h dw ?
ends

;
struct SDL_Surface
  flags dd ?                        ; Read-only
  format dd ?                    ; Read-only
  w dd ?                         ; Read-only
  h dd ?                         ; Read-only
  pitch dw ?                     ; Read-only
  db 0,0
  pixels dd ?                        ; Read-write
  offset dd ?                   ; Private

  ; Hardware-specific surface info
  hwdata dd ?

  ; clipping information
  clip_rect SDL_Rect            ; Read-only
  unused1 dd ?                   ; for binary compatibility

  ; Allow recursive locks
  locked dd ?                    ; Private

  ; info for fast blit mapping to other surfaces */
  map dd ?                      ; Private

  ; format version, bumped at every change to invalidate blit maps
  format_version dd ?            ; Private

  ; Reference count -- used when freeing surface
  refcount dd ?            ; Read-mostly
ends

;
struct SDL_version
  major db ?
  minor db ?
  patch db ?
ends

;
struct SDL_keysym
  scancode db ?
  db 0,0,0
  sym dd ?
  mod dd ?
  unicode dw ?
  db 0,0
ends

; Application visibility event structure
struct SDL_ActiveEvent
  type db ?        ; SDL_ACTIVEEVENT
  gain db ?        ; Whether given states were gained or lost (1/0)
  state db ?        ; A mask of the focus states
ends

; Keyboard event structure
struct SDL_KeyboardEvent
  type db ?       ; SDL_KEYDOWN or SDL_KEYUP
  which db ?      ; The keyboard device index
  state db ?     ; SDL_PRESSED or SDL_RELEASED
  db 0
  keysym SDL_keysym
ends

; Mouse motion event structure
struct SDL_MouseMotionEvent
  type db ?      ; SDL_MOUSEMOTION
  which db ?       ; The mouse device index
  state db ?        ; The current button state
  db 0
  x dw ?        ; The X coordinates of the mouse
  y dw ?    ; The Y coordinates of the mouse
  xrel dw ? ; The relative motion in the X direction
  yrel dw ? ; The relative motion in the Y direction
ends

; Mouse button event structure
struct SDL_MouseButtonEvent
  type db ?    ; SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP
  which db ?      ; The mouse device index
  button db ?       ; The mouse button index
  state db ?        ; SDL_PRESSED or SDL_RELEASED
  x dw ?       ; The X coordinates of the mouse at press time
  y dw ?      ; The Y coordinates of the mouse at press time
ends

; Joystick axis motion event structure
struct SDL_JoyAxisEvent
  type db ?  ; SDL_JOYAXISMOTION
  which db ?     ; The joystick device index
  axis db ?      ; The joystick axis index
  db 0
  value dw ?     ; The axis value (range: -32768 to 32767)
ends

; Joystick trackball motion event structure
struct SDL_JoyBallEvent
  type db ?      ; SDL_JOYBALLMOTION
  which db ?     ; The joystick device index
  ball db ?      ; The joystick trackball index
  db 0
  xrel dw ? ; The relative motion in the X direction
  yrel dw ? ; The relative motion in the Y direction
ends

; Joystick hat position change event structure
struct SDL_JoyHatEvent
  type db ? ; SDL_JOYHATMOTION
  which db ?      ; The joystick device index
  hat db ?       ; The joystick hat index
  value db ?        ; The hat position value:
               ;   SDL_HAT_LEFTUP   SDL_HAT_UP       SDL_HAT_RIGHTUP
               ;   SDL_HAT_LEFT     SDL_HAT_CENTERED SDL_HAT_RIGHT
         ;   SDL_HAT_LEFTDOWN SDL_HAT_DOWN     SDL_HAT_RIGHTDOWN
             ; Note that zero means the POV is centered.

ends

; Joystick button event structure
struct SDL_JoyButtonEvent
  type db ?    ; SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP
  which db ?  ; The joystick device index
  button db ?    ; The joystick button index
  state db ?     ; SDL_PRESSED or SDL_RELEASED
ends

; The "window resized" event
; When you get this event, you are responsible for setting a new video
; mode with the new width and height.
struct SDL_ResizeEvent
  type db ? ; SDL_VIDEORESIZE
  db 0,0,0
  w dd ?     ; New width
  h dd ? ; New height
ends

; The "screen redraw" event
struct SDL_ExposeEvent
  type db ?      ; SDL_VIDEOEXPOSE
ends

; The "quit requested" event
struct SDL_QuitEvent
  type db ?  ; SDL_QUIT
ends

; A user-defined event type
struct SDL_UserEvent
  type db ?    ; SDL_USEREVENT through SDL_NUMEVENTS-1
  db 0,0,0
  code dd ?    ; User defined event code
  data1 dd ?       ; User defined data pointer
  data2 dd ?     ; User defined data pointer
ends

; If you want to use this event, you should include SDL_syswm.h
struct SDL_SysWMEvent
  type db ?
  db 0,0,0
  msg dd ?
ends

; General event structure
struct SDL_Event
  union
    type db ?
    active SDL_ActiveEvent
    key SDL_KeyboardEvent
    motion SDL_MouseMotionEvent
    button SDL_MouseButtonEvent
    jaxis SDL_JoyAxisEvent
    jball SDL_JoyBallEvent
    jhat SDL_JoyHatEvent
    jbutton SDL_JoyButtonEvent
    resize SDL_ResizeEvent
    expose SDL_ExposeEvent
    quit SDL_QuitEvent
    user SDL_UserEvent
    syswm SDL_SysWMEvent
  ends
ends
   

Mouse Pixel Test Example
Code: [Select]
;------------------------------------------------------------------------------
;
; FORMAT
;
;------------------------------------------------------------------------------

format PE GUI 4.0

;------------------------------------------------------------------------------
;
; ENTRYPOINT
;
;------------------------------------------------------------------------------

entry start

;------------------------------------------------------------------------------
;
; INCLUDES
;
;------------------------------------------------------------------------------

include 'win32a.inc'
include 'sdl.inc'

;------------------------------------------------------------------------------
;
; CONSTANTS
;
;------------------------------------------------------------------------------

SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
SCREEN_BPP = 8
SOLID_COLOR = 255

;------------------------------------------------------------------------------
;
; RDATA SECTION
;
;------------------------------------------------------------------------------

section '.rdata' data readable

  szProgramName db 'Mouse Pixel Test',0
  szDirectDrawLibrary db 'DDRAW.DLL',0
  szMouseMotion db 'mouse @ %d,%d',0
  szKeyPressed db 'keypressed is %s',0

;------------------------------------------------------------------------------
;
; UDATA SECTION
;
;------------------------------------------------------------------------------

section  '.udata' data readable writeable

  screen       dd ?
  pitch         dw ?
  pixels        dd ?
  event         SDL_Event
  buffer   rb 16

;------------------------------------------------------------------------------
;
; CODE SECTION
;
;------------------------------------------------------------------------------

section '.code' code readable executable

  start:
   invoke LoadLibrary,szDirectDrawLibrary
      or eax,eax
  jz @f
       invoke FreeLibrary,eax

  @@:
     cinvoke SDL_Init,SDL_INIT_NOPARACHUTE
        or eax,eax
  jnz exit
    invoke GetModuleHandle,NULL
 cinvoke SDL_SetModuleHandle,eax
      cinvoke SDL_Init,SDL_INIT_VIDEO
      or eax,eax
  jnz exit
    cinvoke SDL_WM_SetCaption,szProgramName,NULL
 cinvoke SDL_SetVideoMode,SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0
     or eax,eax
  jz finish
   mov [screen],eax
    mov ecx,[eax+SDL_Surface.pixels]
    movzx edx,[eax+SDL_Surface.pitch]
   mov [pitch],dx
      add edx,ecx
 mov [pixels],edx

  flip:
 cinvoke SDL_Flip,[screen]
    or eax,eax
  jnz finish

  idle:
       cinvoke SDL_PollEvent,event
  or eax,eax
  jz flip
     cmp [event.type],SDL_KEYDOWN
        je keydown
  cmp [event.type],SDL_MOUSEMOTION
    je mouse_motion
     cmp [event.type],SDL_MOUSEBUTTONDOWN
        je mouse_button_down
        cmp [event.type],SDL_QUIT
   je finish
   jmp idle

  keydown:
      movzx eax,word [event.key.keysym.sym]
      cinvoke SDL_GetKeyName,eax
   cinvoke sprintf,buffer,szKeyPressed,eax
     cinvoke SDL_WM_SetCaption,buffer,NULL
        jmp idle

  mouse_motion:
 movzx eax,word [event.motion.x]
     movzx ecx,word [event.motion.y]
     cinvoke sprintf,buffer,szMouseMotion,eax,ecx
        cinvoke SDL_WM_SetCaption,buffer,NULL
        jmp idle

  mouse_button_down:
    movzx eax,word [event.button.y]
     movzx edx,word [pitch]
      imul eax,edx
        movzx edx,word [event.button.x]
     add eax,edx
 mov edx,[pixels]
    mov byte[edx+eax],255
       jmp idle

  finish:
       cinvoke SDL_Quit,0

  exit:
        invoke ExitProcess,0

;------------------------------------------------------------------------------
;
; IDATA SECTION
;
;------------------------------------------------------------------------------

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
    msvcrt,'MSVCRT.dll',\
    sdl,'SDL.DLL'

  import kernel32,\
        GetModuleHandle,'GetModuleHandleA',\
     LoadLibrary,'LoadLibraryA',\
     FreeLibrary,'FreeLibrary',\
      ExitProcess,'ExitProcess'

  import msvcrt,\
       sprintf,'sprintf'

  import sdl,\
  SDL_Init,'SDL_Init',\
    SDL_SetModuleHandle, 'SDL_SetModuleHandle',\
     SDL_SetVideoMode,'SDL_SetVideoMode',\
    SDL_Flip,'SDL_Flip',\
    SDL_PollEvent,'SDL_PollEvent',\
  SDL_Quit,'SDL_Quit',\
    SDL_WM_SetCaption,'SDL_WM_SetCaption',\
  SDL_GetKeyName,'SDL_GetKeyName'

SDL_HelloWorld_Fasm - https://web.archive.org/web/20150815122715/http://homepage.ntlworld.com/jeeastwood/SDL.7z

Linux FASM SDL program and source code to display a JPG to the screen https://board.flatassembler.net/download.php?id=2615
Quote
fasm image.asm
gcc -o image -s image.o -nostartfiles -nostdlib -lSDL -lc -lSDL_image
ls -la image

Plot graphic lib using SDL2 - https://github.com/bertrandmartel/plot-sdl/archive/master.zip


To use this library in UASM we need to convert the include folder in the archive - SDL2-devel-2.0.10-VC.zip (Visual C++ 32/64-bit) https://www.libsdl.org/release/SDL2-devel-2.0.10-VC.zip, there are few files in the folder, but I could not do it from the first approach, because the translator does not have the required variables  :nie:

mabdelouahab

  • Member
  • ***
  • Posts: 484
Re: SDL2 - Simple DirectMedia Layer in UASM
« Reply #4 on: March 03, 2020, 07:44:20 AM »
uasm -elf64 sdl2.asm
gcc -o sdl2asm sdl2.o  -lglib-2.0 -fno-pie -no-pie `sdl2-config --cflags --libs`

Code: [Select]
    main PROC SYSTEMV   _argc:DWORD, _argv:QWORD
local dev :SDL_AudioDeviceID
local want :SDL_AudioSpec
local have :SDL_AudioSpec

invoke SDL_Init,SDL_INIT_AUDIO

mov recordedSamples,rv(g_malloc,NUM_BYTE)
mov recordedSamplesI,rax

      mov fid,rv(_open,str$(RAW_FILE_NAME),O_WRONLY or O_CREAT or O_TRUNC , S_IRWXU or S_IRWXG or S_IRWXO)
.if fid==0
invoke printf,str$(<13,10,"Could not open file. ">)      
.endif

invoke memset,recordedSamplesI ,0 ,NUM_BYTE
invoke memset,addr want ,0 ,sizeof want

    mov want.freq , SAMPLE_RATE ;44100
    mov want.format , AUDIO_S32LSB
    mov want.channels , NUM_CHANNELS
    mov want.samples , FRAMES_PER_BUFFER
    lea rax,cb_record
    mov want.callback , rax     
   
    invoke SDL_OpenAudioDevice,rv(SDL_GetAudioDeviceName,0, 1), 1, addr want,addr have, 0
mov dev ,eax

    .if dev == 0
    invoke printf,str$(<13,10,"Failed to open audio: %s">),rv(SDL_GetError)
    ret
        .endif
       
      invoke SDL_PauseAudioDevice,dev, 0

invoke SDL_Delay,1000 * NUM_SECONDS
invoke SDL_CloseAudioDevice,dev

.if fid
            invoke _close,fid     
.endif

xor rax,rax
ret
     main ENDP
     
     cb_record PROC  userdata:gpointer,  stream:gpointer, __len
      .if fid
            invoke _write,fid,stream,__len
.endif
      RET
     cb_record ENDP