use "lib:SDL2"
use "lib:SDL2main"
use "time"
use "debug"
use @SDL_Init[I32](flags: U32)
use @SDL_CreateWindow[Pointer[_SDLWindow val] ref](title: Pointer[U8] tag, x: I32, y: I32, w: I32, h: I32, flags: U32)
use @SDL_CreateRenderer[Pointer[_SDLRenderer val] ref](window: Pointer[_SDLWindow val] box, index: I32, flags: U32)
use @SDL_DestroyRenderer[None](renderer: Pointer[_SDLRenderer val] box)
use @SDL_DestroyWindow[None](window: Pointer[_SDLWindow val] box)
use @SDL_RenderClear[I32](renderer: Pointer[_SDLRenderer val] box)
use @SDL_RenderPresent[None](renderer: Pointer[_SDLRenderer val] box)
use @SDL_SetRenderDrawColor[I32](renderer: Pointer[_SDLRenderer val] box, r: U8, g: U8, b: U8, a: U8)
use @SDL_RenderFillRect[I32](renderer: Pointer[_SDLRenderer val] box, rect: MaybePointer[_SDLRect ref] box)
use @SDL_PollEvent[I32](event : Pointer[U8] tag)
struct ref _SDLRect
var x: I32 = 0
var y: I32 = 0
var w: I32 = 0
var h: I32 = 0
new create(x1: I32, y1: I32, w1: I32, h1: I32) =>
x = x1
y = y1
w = w1
h = h1
struct SDLEvent
var array : Array[U8]
new create() =>
array = Array[U8].init(0, 56)
// see https://github.com/Rust-SDL2/rust-sdl2/blob/6e9a00a0d254c6b6e3cc0024494f84c1cc577534/sdl2-sys/src/event.rs
primitive SdlQuitEvent
fun apply() : U32 => 256
primitive SDLEventTranslator
fun type_of_event(event : SDLEvent) : U32 =>
try
var byte0 : U8 = event.array(0)?
var byte1 : U8 = event.array(1)?
var byte2 : U8 = event.array(2)?
var byte3 : U8 = event.array(3)?
// Debug.out(byte0.string())
// Debug.out(byte1.string())
// Debug.out(byte2.string())
// Debug.out(byte3.string())
// TODO use byte shiffting instead of that ugly multiplications
byte0.u32() + (byte1.u32() * 256) + (byte2.u32() * 256 * 256) + (byte3.u32() * 256 * 256 * 256)
else
0
end
primitive _SDLWindow
primitive _SDLRenderer
primitive SDL2
fun init_video(): U32 =>
0x00000020
fun window_shown(): U32 =>
0x00000004
fun renderer_accelerated(): U32 =>
0x00000002
fun renderer_presentvsync(): U32 =>
0x00000004
class val GameTime
let second : I64
let nano_second : I64
new iso create(s : I64, ns : I64) =>
second = s
nano_second = ns
fun delta(s : I64, ns : I64) : GameTime val^ =>
if (ns < nano_second) then
let r = GameTime(s - 1 - second, (ns - nano_second) + 1_000_000_000)
r
else
let r = GameTime(s - second, ns - nano_second)
r
end
actor Main
let _env : Env
var _event : SDLEvent
var window: Pointer[_SDLWindow val] ref
var renderer: Pointer[_SDLRenderer val] ref
var is_done : Bool = false
var game_time : GameTime
var frame_index : U64 = 0
new create(env : Env) =>
_env = env
@SDL_Init(SDL2.init_video())
window = @SDL_CreateWindow("Hello World!".cstring(), 100, 100, 640, 480, SDL2.window_shown())
renderer = @SDL_CreateRenderer(window, -1, SDL2.renderer_accelerated() or SDL2.renderer_presentvsync())
_event = SDLEvent
(let s : I64, let ns : I64)= Time.now()
game_time = GameTime(s, ns)
tick()
be tick() =>
(let s : I64, let ns : I64) = Time.now()
let delta = game_time.delta(s, ns)
if (delta.second > 1) or (delta.nano_second > 6_000_000) then
game_time = GameTime(s, ns)
loop(delta)
frame_index = frame_index + 1
end
if not is_done then
tick()
end
fun ref loop(delta : GameTime) =>
@SDL_RenderClear(renderer)
@SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255)
@SDL_RenderFillRect(renderer, MaybePointer[_SDLRect].none())
@SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255)
let cosine = (((game_time.second.f64() * 1_000_000_000 ) + game_time.nano_second.f64()) / F64(1_000_000_000)).cos()
let x : F64 = F64(100) + (F64(100) * cosine)
let rect = _SDLRect(x.i32(), 100, 200, 200)
@SDL_RenderFillRect(renderer, MaybePointer[_SDLRect](rect))
@SDL_RenderPresent(renderer)
var result : I32 = @SDL_PollEvent(_event.array.cpointer())
while result != 0 do
//_env.out.print("result is " + result.string())
var event_type = SDLEventTranslator.type_of_event(_event)
//_env.out.print("event type is " + event_type.string())
if event_type == SdlQuitEvent() then
//_env.out.print("is done")
quit()
end
result = @SDL_PollEvent(_event.array.cpointer())
end
fun ref quit() : None =>
Debug.out("is done")
@SDL_DestroyRenderer(renderer)
@SDL_DestroyWindow(window)
is_done = true