|
|
@@ -1,309 +0,0 @@
|
|
|
-#+ignore
|
|
|
-
|
|
|
-package karl2d
|
|
|
-
|
|
|
-import rl "raylib"
|
|
|
-import "raylib/rlgl"
|
|
|
-import "core:log"
|
|
|
-import "core:strings"
|
|
|
-import "base:runtime"
|
|
|
-import "core:slice"
|
|
|
-
|
|
|
-_init :: proc(width: int, height: int, title: string,
|
|
|
- allocator := context.allocator, loc := #caller_location) -> ^State {
|
|
|
- s = new(State, allocator, loc)
|
|
|
- s.textures = make([dynamic]rl.Texture, allocator, loc)
|
|
|
- s.allocator = allocator
|
|
|
- rl.SetConfigFlags({.WINDOW_RESIZABLE, .VSYNC_HINT})
|
|
|
- rl.InitWindow(i32(width), i32(height), temp_cstring(title))
|
|
|
- return s
|
|
|
-}
|
|
|
-
|
|
|
-_shutdown :: proc() {
|
|
|
- rl.CloseWindow()
|
|
|
-
|
|
|
- if s != nil {
|
|
|
- delete(s.textures)
|
|
|
- a := s.allocator
|
|
|
- free(s, a)
|
|
|
- s = nil
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-_set_internal_state :: proc(new_state: ^State) {
|
|
|
- s = new_state
|
|
|
-}
|
|
|
-
|
|
|
-_clear :: proc(color: Color) {
|
|
|
- rl.ClearBackground(rl.Color(color))
|
|
|
-}
|
|
|
-
|
|
|
-s: ^State
|
|
|
-
|
|
|
-State :: struct {
|
|
|
- textures: [dynamic]rl.Texture,
|
|
|
- allocator: runtime.Allocator,
|
|
|
- implicitly_created: bool,
|
|
|
-}
|
|
|
-
|
|
|
-_load_texture :: proc(filename: string) -> Texture {
|
|
|
- tex := rl.LoadTexture(temp_cstring(filename))
|
|
|
-
|
|
|
- if tex.id == 0 {
|
|
|
- return {}
|
|
|
- }
|
|
|
-
|
|
|
- if len(s.textures) == 0 {
|
|
|
- append(&s.textures, rl.Texture{})
|
|
|
- }
|
|
|
-
|
|
|
- tex_id := Texture_Handle(len(s.textures))
|
|
|
- append(&s.textures, tex)
|
|
|
-
|
|
|
- return {
|
|
|
- id = tex_id,
|
|
|
- width = int(tex.width),
|
|
|
- height = int(tex.height),
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-_destroy_texture :: proc(tex: Texture) {
|
|
|
- if tex.id < 1 || int(tex.id) >= len(s.textures) {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- rl.UnloadTexture(s.textures[tex.id])
|
|
|
- s.textures[tex.id] = {}
|
|
|
-}
|
|
|
-
|
|
|
-_draw_texture :: proc(tex: Texture, pos: Vec2, tint := WHITE) {
|
|
|
- _draw_texture_ex(
|
|
|
- tex,
|
|
|
- {0, 0, f32(tex.width), f32(tex.height)},
|
|
|
- {pos.x, pos.y, f32(tex.width), f32(tex.height)},
|
|
|
- {},
|
|
|
- 0,
|
|
|
- tint,
|
|
|
- )
|
|
|
-}
|
|
|
-
|
|
|
-_draw_texture_rect :: proc(tex: Texture, rect: Rect, pos: Vec2, tint := WHITE) {
|
|
|
- _draw_texture_ex(
|
|
|
- tex,
|
|
|
- rect,
|
|
|
- {pos.x, pos.y, rect.w, rect.h},
|
|
|
- {},
|
|
|
- 0,
|
|
|
- tint,
|
|
|
- )
|
|
|
-}
|
|
|
-
|
|
|
-_draw_texture_ex :: proc(tex: Texture, src: Rect, dst: Rect, origin: Vec2, rot: f32, tint := WHITE) {
|
|
|
- if tex.id == 0 {
|
|
|
- log.error("Invalid texture.")
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- rl.DrawTexturePro(
|
|
|
- s.textures[tex.id],
|
|
|
- transmute(rl.Rectangle)(src),
|
|
|
- transmute(rl.Rectangle)(dst),
|
|
|
- origin,
|
|
|
- rot,
|
|
|
- rl.Color(tint),
|
|
|
- )
|
|
|
-}
|
|
|
-
|
|
|
-_draw_rectangle :: proc(rect: Rect, color: Color) {
|
|
|
- rl.DrawRectangleRec(rl_rect(rect), rl_color(color))
|
|
|
-}
|
|
|
-
|
|
|
-_draw_rectangle_outline :: proc(rect: Rect, thickness: f32, color: Color) {
|
|
|
- rl.DrawRectangleLinesEx(rl_rect(rect), thickness, rl_color(color))
|
|
|
-}
|
|
|
-
|
|
|
-_draw_circle :: proc(center: Vec2, radius: f32, color: Color) {
|
|
|
- rl.DrawCircleV(center, radius, rl_color(color))
|
|
|
-}
|
|
|
-
|
|
|
-_draw_line :: proc(start: Vec2, end: Vec2, thickness: f32, color: Color) {
|
|
|
- rl.DrawLineEx(start, end, thickness, rl_color(color))
|
|
|
-}
|
|
|
-
|
|
|
-_get_screen_width :: proc() -> int {
|
|
|
- return int(rl.GetScreenWidth())
|
|
|
-}
|
|
|
-
|
|
|
-_get_screen_height :: proc() -> int {
|
|
|
- return int(rl.GetScreenHeight())
|
|
|
-}
|
|
|
-
|
|
|
-_key_pressed :: proc(key: Keyboard_Key) -> bool {
|
|
|
- return rl.IsKeyPressed(rl.KeyboardKey(key))
|
|
|
-}
|
|
|
-
|
|
|
-_key_released :: proc(key: Keyboard_Key) -> bool {
|
|
|
- return rl.IsKeyReleased(rl.KeyboardKey(key))
|
|
|
-}
|
|
|
-
|
|
|
-_key_held :: proc(key: Keyboard_Key) -> bool {
|
|
|
- return rl.IsKeyDown(rl.KeyboardKey(key))
|
|
|
-}
|
|
|
-
|
|
|
-_window_should_close :: proc() -> bool {
|
|
|
- return rl.WindowShouldClose()
|
|
|
-}
|
|
|
-
|
|
|
-rl_texture :: proc(tex: Texture) -> rl.Texture {
|
|
|
- if tex.id < 1 || int(tex.id) >= len(s.textures) {
|
|
|
- return {}
|
|
|
- }
|
|
|
-
|
|
|
- return s.textures[tex.id]
|
|
|
-}
|
|
|
-
|
|
|
-rl_rect :: proc(r: Rect) -> rl.Rectangle {
|
|
|
- return transmute(rl.Rectangle)(r)
|
|
|
-}
|
|
|
-
|
|
|
-rl_color :: proc(c: Color) -> rl.Color {
|
|
|
- return (rl.Color)(c)
|
|
|
-}
|
|
|
-
|
|
|
-_draw_text :: proc(text: string, pos: Vec2, font_size: f32, color: Color) {
|
|
|
- rl.DrawTextEx(rl.GetFontDefault(), temp_cstring(text), pos, font_size, 1, rl_color(color))
|
|
|
-}
|
|
|
-
|
|
|
-_mouse_button_pressed :: proc(button: Mouse_Button) -> bool {
|
|
|
- return rl.IsMouseButtonPressed(rl.MouseButton(button))
|
|
|
-}
|
|
|
-
|
|
|
-_mouse_button_released :: proc(button: Mouse_Button) -> bool {
|
|
|
- return rl.IsMouseButtonReleased(rl.MouseButton(button))
|
|
|
-}
|
|
|
-
|
|
|
-_mouse_button_held :: proc(button: Mouse_Button) -> bool {
|
|
|
- return rl.IsMouseButtonDown(rl.MouseButton(button))
|
|
|
-}
|
|
|
-
|
|
|
-_mouse_wheel_delta :: proc() -> f32 {
|
|
|
- return rl.GetMouseWheelMove()
|
|
|
-}
|
|
|
-
|
|
|
-_mouse_position :: proc() -> Vec2 {
|
|
|
- return rl.GetMousePosition()
|
|
|
-}
|
|
|
-
|
|
|
-_enable_scissor :: proc(x, y, w, h: int) {
|
|
|
- rl.BeginScissorMode(i32(x), i32(y), i32(w), i32(h))
|
|
|
-}
|
|
|
-
|
|
|
-_disable_scissor :: proc() {
|
|
|
- rl.EndScissorMode()
|
|
|
-}
|
|
|
-
|
|
|
-_set_window_size :: proc(width: int, height: int) {
|
|
|
- rl.SetWindowSize(i32(width), i32(height))
|
|
|
-}
|
|
|
-
|
|
|
-_set_window_position :: proc(x: int, y: int) {
|
|
|
- rl.SetWindowPosition(i32(x), i32(y))
|
|
|
-}
|
|
|
-
|
|
|
-_screen_to_world :: proc(pos: Vec2, camera: Camera) -> Vec2 {
|
|
|
- return rl.GetScreenToWorld2D(pos, rl_camera(camera))
|
|
|
-}
|
|
|
-
|
|
|
-rl_camera :: proc(camera: Camera) -> rl.Camera2D {
|
|
|
- return {
|
|
|
- offset = camera.origin,
|
|
|
- target = camera.target,
|
|
|
- rotation = camera.rotation,
|
|
|
- zoom = camera.zoom,
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-_set_camera :: proc(camera: Maybe(Camera)) {
|
|
|
- // TODO: Only do something if the camera is actually different.
|
|
|
-
|
|
|
- rlgl.DrawRenderBatchActive()
|
|
|
- rlgl.LoadIdentity()
|
|
|
-
|
|
|
- if c, c_ok := camera.?; c_ok {
|
|
|
- camera_mat := rl.MatrixToFloatV(rl.GetCameraMatrix2D(rl_camera(c)))
|
|
|
- rlgl.MultMatrixf(&camera_mat[0])
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-_set_scissor_rect :: proc(scissor_rect: Maybe(Rect)) {
|
|
|
- // TODO: Only do something if the scissor rect is actually different
|
|
|
-
|
|
|
- rlgl.DrawRenderBatchActive()
|
|
|
-
|
|
|
- if s, s_ok := scissor_rect.?; s_ok {
|
|
|
- rl.BeginScissorMode(i32(s.x), i32(s.y), i32(s.w), i32(s.h))
|
|
|
- } else {
|
|
|
- rlgl.DisableScissorTest()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-_set_shader :: proc(shader: Maybe(Shader)) {
|
|
|
- if s, s_ok := shader.?; s_ok {
|
|
|
- rlgl.SetShader(s.id, raw_data(s.locs))
|
|
|
- } else {
|
|
|
- rlgl.SetShader(rlgl.GetShaderIdDefault(), rlgl.GetShaderLocsDefault())
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-_process_events :: proc() {
|
|
|
- rl.PollInputEvents()
|
|
|
-}
|
|
|
-
|
|
|
-_flush :: proc() {
|
|
|
- rlgl.DrawRenderBatchActive()
|
|
|
-}
|
|
|
-
|
|
|
-_present :: proc(do_flush := true) {
|
|
|
- if do_flush {
|
|
|
- rlgl.DrawRenderBatchActive()
|
|
|
- }
|
|
|
- rl.SwapScreenBuffer()
|
|
|
-}
|
|
|
-
|
|
|
-_load_shader :: proc(vs: string, fs: string) -> Shader {
|
|
|
- s := rl.LoadShader(temp_cstring(vs), temp_cstring(fs))
|
|
|
-
|
|
|
- return {
|
|
|
- id = s.id,
|
|
|
- locs = slice.from_ptr(s.locs, 32),
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-_destroy_shader :: proc(shader: Shader) {
|
|
|
- rl.UnloadShader(rl_shader(shader))
|
|
|
-}
|
|
|
-
|
|
|
-_get_shader_location :: proc(shader: Shader, uniform_name: string) -> int {
|
|
|
- return int(rl.GetShaderLocation(rl_shader(shader), temp_cstring(uniform_name)))
|
|
|
-}
|
|
|
-
|
|
|
-_set_shader_value_f32 :: proc(shader: Shader, loc: int, val: f32) {
|
|
|
- val := val
|
|
|
- rl.SetShaderValue(rl_shader(shader), loc, &val, .FLOAT)
|
|
|
-}
|
|
|
-
|
|
|
-_set_shader_value_vec2 :: proc(shader: Shader, loc: int, val: Vec2) {
|
|
|
- val := val
|
|
|
- rl.SetShaderValue(rl_shader(shader), loc, &val, .VEC2)
|
|
|
-}
|
|
|
-
|
|
|
-rl_shader :: proc(s: Shader) -> rl.Shader {
|
|
|
- return {
|
|
|
- id = s.id,
|
|
|
- locs = raw_data(s.locs),
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-temp_cstring :: proc(str: string) -> cstring {
|
|
|
- return strings.clone_to_cstring(str, context.temp_allocator)
|
|
|
-}
|