initial commit with demo in main.c
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
.clangd
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
CC := gcc
|
||||||
|
LIBS := `pkg-config --libs sdl3`
|
||||||
|
INC := `pkg-config --cflags sdl3` -I./include
|
||||||
|
SRC := src/main.c \
|
||||||
|
src/engine/engine.c \
|
||||||
|
src/engine/engine_init.c \
|
||||||
|
src/engine/render.c
|
||||||
|
OUT := build/main
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(CC) -o $(OUT) $(SRC) $(INC) $(LIBS)
|
||||||
|
|
||||||
|
run:
|
||||||
|
$(OUT)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm $(OUT)
|
||||||
|
|
||||||
|
.PHONY: build run
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"folders":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,529 @@
|
|||||||
|
{
|
||||||
|
"auto_complete":
|
||||||
|
{
|
||||||
|
"selected_items":
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"SDL_EVENT",
|
||||||
|
"SDL_EVENT_KEY_DOWN"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"engine_sdl_",
|
||||||
|
"engine_sdl_destroy"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"clie",
|
||||||
|
"client_update_framebuffer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"en",
|
||||||
|
"engine_update_framebuffer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"engine",
|
||||||
|
"engine_poll_events"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"int",
|
||||||
|
"internal_state"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"inter",
|
||||||
|
"engine_internal_state_t"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"engine_",
|
||||||
|
"engine_update_framebuffer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"RCO",
|
||||||
|
"RCODE_SUCCESS"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"game_s",
|
||||||
|
"game_state_t"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"sdl_state",
|
||||||
|
"engine_sdl_state_t"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"SDL_Des",
|
||||||
|
"SDL_DestroyWindow"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"R",
|
||||||
|
"RCODE_SUCCESS"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"W",
|
||||||
|
"window_name"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"window",
|
||||||
|
"window_name"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"WINDOW",
|
||||||
|
"WINDOW_NAME_LENGTH"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"RC",
|
||||||
|
"RCODE_FAILURE"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"eng",
|
||||||
|
"engine_sdl_state_t"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"SLD",
|
||||||
|
"SDL_Init"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"target",
|
||||||
|
"target_frame"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"buffers":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"file": ".clangd",
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"buffer_size": 77,
|
||||||
|
"encoding": "UTF-8",
|
||||||
|
"line_ending": "Unix"
|
||||||
|
},
|
||||||
|
"undo_stack":
|
||||||
|
[
|
||||||
|
[
|
||||||
|
8,
|
||||||
|
1,
|
||||||
|
"insert",
|
||||||
|
{
|
||||||
|
"characters": "dangerzone"
|
||||||
|
},
|
||||||
|
"CgAAAC0AAAAAAAAALgAAAAAAAAAQAAAAY19zZGxfcGxheWdyb3VuZC4AAAAAAAAALwAAAAAAAAAAAAAALwAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAAAAAADEAAAAAAAAAAAAAADEAAAAAAAAAMgAAAAAAAAAAAAAAMgAAAAAAAAAzAAAAAAAAAAAAAAAzAAAAAAAAADQAAAAAAAAAAAAAADQAAAAAAAAANQAAAAAAAAAAAAAANQAAAAAAAAA2AAAAAAAAAAAAAAA2AAAAAAAAADcAAAAAAAAAAAAAAA",
|
||||||
|
"AQAAAAAAAAABAAAALQAAAAAAAAA9AAAAAAAAAAAAAAAAAPC/"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
11,
|
||||||
|
14,
|
||||||
|
"left_delete",
|
||||||
|
null,
|
||||||
|
"DgAAACsAAAAAAAAAKwAAAAAAAAABAAAAZSoAAAAAAAAAKgAAAAAAAAABAAAAZCkAAAAAAAAAKQAAAAAAAAABAAAAbygAAAAAAAAAKAAAAAAAAAABAAAAQycAAAAAAAAAJwAAAAAAAAABAAAALyYAAAAAAAAAJgAAAAAAAAABAAAAcCUAAAAAAAAAJQAAAAAAAAABAAAAbSQAAAAAAAAAJAAAAAAAAAABAAAAaSMAAAAAAAAAIwAAAAAAAAABAAAALyIAAAAAAAAAIgAAAAAAAAABAAAAZSEAAAAAAAAAIQAAAAAAAAABAAAAbSAAAAAAAAAAIAAAAAAAAAABAAAAbx8AAAAAAAAAHwAAAAAAAAABAAAAaB4AAAAAAAAAHgAAAAAAAAABAAAALw",
|
||||||
|
"AQAAAAAAAAABAAAALAAAAAAAAAAsAAAAAAAAAAAAAAAAAPC/"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
12,
|
||||||
|
1,
|
||||||
|
"insert",
|
||||||
|
{
|
||||||
|
"characters": "$HOME/Code"
|
||||||
|
},
|
||||||
|
"CgAAAB4AAAAAAAAAHwAAAAAAAAAAAAAAHwAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAACEAAAAAAAAAAAAAACEAAAAAAAAAIgAAAAAAAAAAAAAAIgAAAAAAAAAjAAAAAAAAAAAAAAAjAAAAAAAAACQAAAAAAAAAAAAAACQAAAAAAAAAJQAAAAAAAAAAAAAAJQAAAAAAAAAmAAAAAAAAAAAAAAAmAAAAAAAAACcAAAAAAAAAAAAAACcAAAAAAAAAKAAAAAAAAAAAAAAA",
|
||||||
|
"AQAAAAAAAAABAAAAHgAAAAAAAAAeAAAAAAAAAAAAAAAAAPC/"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"build_system": "",
|
||||||
|
"build_system_choices":
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"Packages/Makefile/Make.sublime-build",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Packages/Makefile/Make.sublime-build",
|
||||||
|
"Clean"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Packages/Makefile/Make.sublime-build",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"Packages/User/Custom Make.sublime-build",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Packages/User/Custom Make.sublime-build",
|
||||||
|
"Run"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Packages/User/Custom Make.sublime-build",
|
||||||
|
"Clean"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Packages/User/Custom Make.sublime-build",
|
||||||
|
"Clean"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"build_varint": "",
|
||||||
|
"command_palette":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"last_filter": "",
|
||||||
|
"selected_items":
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"log",
|
||||||
|
"LSP: Toggle Log Panel"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"log panel",
|
||||||
|
"LSP: Toggle Log Panel"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"toggle lo",
|
||||||
|
"LSP: Toggle Log Panel"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"globally",
|
||||||
|
"LSP: Enable Language Server Globally"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"lsp enable",
|
||||||
|
"LSP: Enable Language Server Globally"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"list packages",
|
||||||
|
"Package Control: List Packages"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"satisfy",
|
||||||
|
"Package Control: Satisfy Libraries"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"instal",
|
||||||
|
"Package Control: Install Package"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"branch",
|
||||||
|
"git: branch"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"status",
|
||||||
|
"git: status"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"commit",
|
||||||
|
"git: commit"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"git: status",
|
||||||
|
"git: status"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"install",
|
||||||
|
"Package Control: Install Package"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"remove",
|
||||||
|
"Package Control: Remove Package"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"git gui",
|
||||||
|
"Git: Gui"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"git",
|
||||||
|
"Git: Gitk"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Package Control: install",
|
||||||
|
"Package Control: Install Package"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Package Control: insta",
|
||||||
|
"Package Control: Install Package"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Package Control: remove",
|
||||||
|
"Package Control: Remove Package"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"zeal:",
|
||||||
|
"Zeal: Search"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"zeal",
|
||||||
|
"Zeal: Search"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Package Control: ",
|
||||||
|
"Package Control: Remove Package"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"clangd",
|
||||||
|
"Preferences: LSP-clangd Settings"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"install package",
|
||||||
|
"Package Control: Install Package"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"package",
|
||||||
|
"Install Package Control"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"width": 0.0
|
||||||
|
},
|
||||||
|
"console":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"history":
|
||||||
|
[
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"distraction_free":
|
||||||
|
{
|
||||||
|
"menu_visible": true,
|
||||||
|
"show_minimap": false,
|
||||||
|
"show_open_files": false,
|
||||||
|
"show_tabs": false,
|
||||||
|
"side_bar_visible": false,
|
||||||
|
"status_bar_visible": false
|
||||||
|
},
|
||||||
|
"expanded_folders":
|
||||||
|
[
|
||||||
|
"/home/imp/Code/dangerzone",
|
||||||
|
"/home/imp/Code/dangerzone/include",
|
||||||
|
"/home/imp/Code/dangerzone/src"
|
||||||
|
],
|
||||||
|
"file_history":
|
||||||
|
[
|
||||||
|
"/home/imp/Code/c_sdl_playground/include/error.h",
|
||||||
|
"/home/imp/Code/c_sdl_playground/src/engine/render.c",
|
||||||
|
"/home/imp/Code/c_sdl_playground/src/engine/engine_init.c",
|
||||||
|
"/home/imp/Code/c_sdl_playground/Makefile",
|
||||||
|
"/home/imp/Code/c_sdl_playground/include/engine.h",
|
||||||
|
"/home/imp/Code/c_sdl_playground/src/engine/engine.c",
|
||||||
|
"/home/imp/Code/c_sdl_playground/src/main.c",
|
||||||
|
"/home/imp/Code/c_sdl_playground/include/render.h",
|
||||||
|
"/home/imp/Code/c_sdl_playground/.clangd",
|
||||||
|
"/home/imp/Code/c_sdl_playground/src/error.c",
|
||||||
|
"/home/imp/Code/c_sdl_playground/compile_options.txt",
|
||||||
|
"/home/imp/.config/sublime-text/Packages/User/zeal_unfiltered.py",
|
||||||
|
"/home/imp/Dokumenty/sdlwiki/SDL3/SDL_Window.html",
|
||||||
|
"/home/imp/.config/sublime-text/Packages/User/open-offline-doc.py",
|
||||||
|
"/home/imp/.config/sublime-text/Packages/User/open-url.py",
|
||||||
|
"/home/imp/.local/share/Zeal/Zeal/docsets/import_docset.py",
|
||||||
|
"/home/imp/.local/share/Zeal/Zeal/docsets/SDL3.docset/Contents/Info.plist",
|
||||||
|
"/home/imp/.local/share/Zeal/Zeal/docsets/SDL.docset/Contents/Resources/docSet.dsidx",
|
||||||
|
"/home/imp/.config/sublime-text/Packages/User/LSP-clangd.sublime-settings",
|
||||||
|
"/home/imp/.config/sublime-text/Packages/LSP-clangd/LSP-clangd.sublime-settings",
|
||||||
|
"/home/imp/Code/c_sdl_playground/src/compile_options.txt",
|
||||||
|
"/home/imp/sdl-builder/SDL/build/build.sh",
|
||||||
|
"/home/imp/sdl-builder/Dockerfile",
|
||||||
|
"/home/imp/sdl-builder/build-sdl.sh",
|
||||||
|
"/home/imp/.config/sublime-text/Packages/User/Custom Make.sublime-build",
|
||||||
|
"/home/imp/Code/c_sdl_playground/build/main",
|
||||||
|
"/home/imp/.config/sublime-text/Packages/User/Make.sublime-build",
|
||||||
|
"/home/imp/.config/sublime-text/Packages/User/make.sublime-build",
|
||||||
|
"/home/imp/xzlevor/s1/d_2048.py"
|
||||||
|
],
|
||||||
|
"find":
|
||||||
|
{
|
||||||
|
"height": 45.0
|
||||||
|
},
|
||||||
|
"find_in_files":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"where_history":
|
||||||
|
[
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"find_state":
|
||||||
|
{
|
||||||
|
"case_sensitive": false,
|
||||||
|
"find_history":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"highlight": true,
|
||||||
|
"in_selection": false,
|
||||||
|
"preserve_case": false,
|
||||||
|
"regex": false,
|
||||||
|
"replace_history":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"reverse": false,
|
||||||
|
"scrollbar_highlights": true,
|
||||||
|
"show_context": true,
|
||||||
|
"use_buffer2": true,
|
||||||
|
"use_gitignore": true,
|
||||||
|
"whole_word": false,
|
||||||
|
"wrap": true
|
||||||
|
},
|
||||||
|
"groups":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"sheets":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"file": ".clangd",
|
||||||
|
"selected": true,
|
||||||
|
"semi_transient": false,
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"buffer_size": 77,
|
||||||
|
"regions":
|
||||||
|
{
|
||||||
|
},
|
||||||
|
"selection":
|
||||||
|
[
|
||||||
|
[
|
||||||
|
41,
|
||||||
|
41
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"lsp_uri": "file:///home/imp/Code/dangerzone/.clangd",
|
||||||
|
"syntax": "Packages/Text/Plain text.tmLanguage",
|
||||||
|
"tab_size": 2,
|
||||||
|
"translate_tabs_to_spaces": true
|
||||||
|
},
|
||||||
|
"translation.x": 0.0,
|
||||||
|
"translation.y": 0.0,
|
||||||
|
"zoom_level": 1.0
|
||||||
|
},
|
||||||
|
"stack_index": 0,
|
||||||
|
"stack_multiselect": false,
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"incremental_find":
|
||||||
|
{
|
||||||
|
"height": 0.0
|
||||||
|
},
|
||||||
|
"input":
|
||||||
|
{
|
||||||
|
"height": 47.0
|
||||||
|
},
|
||||||
|
"layout":
|
||||||
|
{
|
||||||
|
"cells":
|
||||||
|
[
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"cols":
|
||||||
|
[
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"rows":
|
||||||
|
[
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"menu_visible": true,
|
||||||
|
"output.LSP Log Panel":
|
||||||
|
{
|
||||||
|
"height": 335.0,
|
||||||
|
"history":
|
||||||
|
[
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"output.diagnostics":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"history":
|
||||||
|
[
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"output.exec":
|
||||||
|
{
|
||||||
|
"height": 151.0,
|
||||||
|
"history":
|
||||||
|
[
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"output.find_results":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"history":
|
||||||
|
[
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"output.git":
|
||||||
|
{
|
||||||
|
"height": 178.0,
|
||||||
|
"history":
|
||||||
|
[
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"output.mdpopups":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"history":
|
||||||
|
[
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pinned_build_system": "Packages/User/Custom Make.sublime-build",
|
||||||
|
"project": "dangerzone.sublime-project",
|
||||||
|
"replace":
|
||||||
|
{
|
||||||
|
"height": 0.0
|
||||||
|
},
|
||||||
|
"save_all_on_build": true,
|
||||||
|
"select_file":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"last_filter": "",
|
||||||
|
"selected_items":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"width": 0.0
|
||||||
|
},
|
||||||
|
"select_project":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"last_filter": "",
|
||||||
|
"selected_items":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"width": 0.0
|
||||||
|
},
|
||||||
|
"select_symbol":
|
||||||
|
{
|
||||||
|
"height": 0.0,
|
||||||
|
"last_filter": "",
|
||||||
|
"selected_items":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"width": 0.0
|
||||||
|
},
|
||||||
|
"selected_group": 0,
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"lsp_show_inlay_hints": false
|
||||||
|
},
|
||||||
|
"show_minimap": true,
|
||||||
|
"show_open_files": false,
|
||||||
|
"show_tabs": true,
|
||||||
|
"side_bar_visible": true,
|
||||||
|
"side_bar_width": 267.0,
|
||||||
|
"status_bar_visible": true,
|
||||||
|
"template_settings":
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH 1280
|
||||||
|
#define WINDOW_HEIGHT 720
|
||||||
|
#define DEFAULT_WINDOW_NAME "SDL Playground"
|
||||||
|
#define WINDOW_NAME_LENGTH 128
|
||||||
|
#define TARGET_FRAME 1.0 / 60.0
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char window_name[WINDOW_NAME_LENGTH];
|
||||||
|
uint16_t width, height;
|
||||||
|
SDL_Window *window;
|
||||||
|
SDL_Renderer *renderer;
|
||||||
|
SDL_Texture *texture;
|
||||||
|
} engine_sdl_state_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* this function runs inside of the SDL_PollEvent loop
|
||||||
|
* useful for user input, quitting the program and so on
|
||||||
|
*/
|
||||||
|
void (*engine_poll_events)(void);
|
||||||
|
/**
|
||||||
|
* meant as the "area" for manupulating the framebuffer;
|
||||||
|
* after this is executed, the contents of
|
||||||
|
* game_state->framebuffer get drawn
|
||||||
|
*/
|
||||||
|
void (*engine_update_framebuffer)(void);
|
||||||
|
engine_sdl_state_t *sdl_state;
|
||||||
|
} engine_internal_state_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t framebuffer[WINDOW_WIDTH * WINDOW_HEIGHT];
|
||||||
|
SDL_Event event;
|
||||||
|
bool is_running;
|
||||||
|
uint16_t width, height;
|
||||||
|
} game_state_t;
|
||||||
|
|
||||||
|
extern engine_internal_state_t *internal_state;
|
||||||
|
extern game_state_t *game_state;
|
||||||
|
|
||||||
|
engine_sdl_state_t*
|
||||||
|
engine_sdl_init();
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_sdl_destroy(
|
||||||
|
engine_sdl_state_t *state
|
||||||
|
);
|
||||||
|
|
||||||
|
bool
|
||||||
|
engine_init(
|
||||||
|
void (*engine_poll_events)(void),
|
||||||
|
void (*engine_update_framebuffer)(void)
|
||||||
|
);
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_start();
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_stop();
|
||||||
|
|
||||||
|
void
|
||||||
|
put_pixel(
|
||||||
|
unsigned int x,
|
||||||
|
unsigned int y,
|
||||||
|
uint32_t color
|
||||||
|
);
|
||||||
|
|
||||||
|
void
|
||||||
|
clear_framebuffer(
|
||||||
|
uint32_t color
|
||||||
|
);
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define eprintf(fmt, ...) \
|
||||||
|
fprintf(stderr, "[ERROR] " fmt "\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define RCODE_FAILURE false
|
||||||
|
#define RCODE_SUCCESS true
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
engine_internal_state_t *internal_state = NULL;
|
||||||
|
game_state_t *game_state = NULL;
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_start() {
|
||||||
|
// main game loop
|
||||||
|
while(game_state->is_running) {
|
||||||
|
uint64_t start = SDL_GetPerformanceCounter();
|
||||||
|
|
||||||
|
// poll events
|
||||||
|
while (SDL_PollEvent(&game_state->event)) {
|
||||||
|
internal_state->engine_poll_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
// call the user-defined framebuffer manipulation function
|
||||||
|
internal_state->engine_update_framebuffer();
|
||||||
|
|
||||||
|
// update the texture with the modified framebuffer
|
||||||
|
SDL_UpdateTexture(
|
||||||
|
internal_state->sdl_state->texture,
|
||||||
|
NULL, game_state->framebuffer,
|
||||||
|
internal_state->sdl_state->width * sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
SDL_RenderClear(
|
||||||
|
internal_state->sdl_state->renderer
|
||||||
|
);
|
||||||
|
|
||||||
|
SDL_RenderTexture(
|
||||||
|
internal_state->sdl_state->renderer,
|
||||||
|
internal_state->sdl_state->texture,
|
||||||
|
NULL, NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
SDL_RenderPresent(
|
||||||
|
internal_state->sdl_state->renderer
|
||||||
|
);
|
||||||
|
|
||||||
|
uint64_t end = SDL_GetPerformanceCounter();
|
||||||
|
|
||||||
|
double elapsed =
|
||||||
|
(double)(end - start) /
|
||||||
|
(double)SDL_GetPerformanceFrequency();
|
||||||
|
|
||||||
|
// cap the framerate at '1.0/TARGET_FRAME' fps
|
||||||
|
if (elapsed < TARGET_FRAME) {
|
||||||
|
SDL_Delay((TARGET_FRAME - elapsed) * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_stop() {
|
||||||
|
engine_sdl_destroy(internal_state->sdl_state);
|
||||||
|
free(internal_state);
|
||||||
|
free(game_state);
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
#include "engine.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include <SDL3/SDL_render.h>
|
||||||
|
#include <SDL3/SDL_video.h>
|
||||||
|
|
||||||
|
bool
|
||||||
|
engine_sdl_init_state(engine_sdl_state_t **state) {
|
||||||
|
*state = (engine_sdl_state_t *)
|
||||||
|
malloc(sizeof(engine_sdl_state_t));
|
||||||
|
|
||||||
|
if (*state == NULL) {
|
||||||
|
eprintf("failed to initialize engine_sdl_state");
|
||||||
|
return RCODE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*state)->width = WINDOW_WIDTH;
|
||||||
|
(*state)->height = WINDOW_HEIGHT;
|
||||||
|
strncpy(
|
||||||
|
(*state)->window_name, DEFAULT_WINDOW_NAME,
|
||||||
|
WINDOW_NAME_LENGTH
|
||||||
|
);
|
||||||
|
|
||||||
|
return RCODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
engine_sdl_init_root()
|
||||||
|
{
|
||||||
|
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
|
eprintf("SDL_Init failed! %s\n", SDL_GetError());
|
||||||
|
return RCODE_FAILURE;
|
||||||
|
} else {
|
||||||
|
return RCODE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
engine_sdl_init_window(
|
||||||
|
engine_sdl_state_t* state
|
||||||
|
) {
|
||||||
|
state->window = SDL_CreateWindow(
|
||||||
|
state->window_name,
|
||||||
|
state->width, state->height, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (state->window == NULL) {
|
||||||
|
eprintf("SDL_CreateWindow failed! %s\n", SDL_GetError());
|
||||||
|
SDL_Quit();
|
||||||
|
return RCODE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RCODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
engine_sdl_init_renderer(
|
||||||
|
engine_sdl_state_t *state
|
||||||
|
) {
|
||||||
|
state->renderer = SDL_CreateRenderer(state->window, NULL);
|
||||||
|
if (state->renderer == NULL) {
|
||||||
|
eprintf("SDL_CreateRenderer failed! %s\n", SDL_GetError());
|
||||||
|
SDL_DestroyWindow(state->window);
|
||||||
|
SDL_Quit();
|
||||||
|
return RCODE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RCODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
engine_sdl_init_texture(
|
||||||
|
engine_sdl_state_t *state
|
||||||
|
) {
|
||||||
|
state->texture = SDL_CreateTexture(
|
||||||
|
state->renderer, SDL_PIXELFORMAT_XRGB8888,
|
||||||
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
state->width, state->height
|
||||||
|
);
|
||||||
|
if (state->texture == NULL) {
|
||||||
|
eprintf("SDL_CreateTexture failed! %s\n", SDL_GetError());
|
||||||
|
SDL_DestroyWindow(state->window);
|
||||||
|
SDL_DestroyRenderer(state->renderer);
|
||||||
|
SDL_Quit();
|
||||||
|
return RCODE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RCODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine_sdl_state_t*
|
||||||
|
engine_sdl_init()
|
||||||
|
{
|
||||||
|
engine_sdl_state_t *state;
|
||||||
|
|
||||||
|
if (!engine_sdl_init_state(&state) ||
|
||||||
|
!engine_sdl_init_root() ||
|
||||||
|
!engine_sdl_init_window(state) ||
|
||||||
|
!engine_sdl_init_renderer(state) ||
|
||||||
|
!engine_sdl_init_texture(state)
|
||||||
|
) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* only call intentinally, not when engine_sdl_init fails
|
||||||
|
* -> it cleans up after itself already
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
engine_sdl_destroy(
|
||||||
|
engine_sdl_state_t *state
|
||||||
|
) {
|
||||||
|
SDL_DestroyTexture(state->texture);
|
||||||
|
SDL_DestroyRenderer(state->renderer);
|
||||||
|
SDL_DestroyWindow(state->window);
|
||||||
|
SDL_Quit();
|
||||||
|
free(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
engine_init(
|
||||||
|
void (*engine_poll_events)(void),
|
||||||
|
void (*engine_update_framebuffer)(void)
|
||||||
|
) {
|
||||||
|
internal_state = (engine_internal_state_t *)
|
||||||
|
malloc(sizeof(engine_internal_state_t));
|
||||||
|
|
||||||
|
game_state = (game_state_t *)
|
||||||
|
malloc(sizeof(game_state_t));
|
||||||
|
|
||||||
|
internal_state->engine_poll_events
|
||||||
|
= engine_poll_events;
|
||||||
|
|
||||||
|
internal_state->engine_update_framebuffer
|
||||||
|
= engine_update_framebuffer;
|
||||||
|
|
||||||
|
internal_state->sdl_state = engine_sdl_init();
|
||||||
|
|
||||||
|
game_state->is_running = true;
|
||||||
|
game_state->width = internal_state->sdl_state->width;
|
||||||
|
game_state->height = internal_state->sdl_state->height;
|
||||||
|
|
||||||
|
return (game_state == NULL || internal_state == NULL)
|
||||||
|
? RCODE_FAILURE : RCODE_SUCCESS;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#include "engine.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
// alter a pixel at an imaginary x & y coordinates
|
||||||
|
void
|
||||||
|
put_pixel(
|
||||||
|
unsigned int x,
|
||||||
|
unsigned int y,
|
||||||
|
uint32_t color
|
||||||
|
) {
|
||||||
|
uint16_t w = game_state->width;
|
||||||
|
uint16_t h = game_state->height;
|
||||||
|
|
||||||
|
if (x < 0 || x >= w || y < 0 || y >= h) {
|
||||||
|
eprintf(
|
||||||
|
"CRITICAL: attempted buffer overflow in put_pixel\n"
|
||||||
|
"at x = %d, y = %d", x, y
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
game_state->framebuffer[game_state->width * y + x]
|
||||||
|
= color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill the entire framebuffer with a given color
|
||||||
|
void
|
||||||
|
clear_framebuffer(
|
||||||
|
uint32_t color
|
||||||
|
) {
|
||||||
|
uint16_t w = game_state->width;
|
||||||
|
uint16_t h = game_state->height;
|
||||||
|
|
||||||
|
for (int i = 0; i < w * h; i++) {
|
||||||
|
game_state->framebuffer[i] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
bool left = true;
|
||||||
|
|
||||||
|
// polling events every frame
|
||||||
|
void
|
||||||
|
client_poll_event() {
|
||||||
|
SDL_Event ev = game_state->event;
|
||||||
|
|
||||||
|
if (ev.type == SDL_EVENT_QUIT) {
|
||||||
|
game_state->is_running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.type == SDL_EVENT_KEY_DOWN) {
|
||||||
|
switch (ev.key.key) {
|
||||||
|
case SDLK_Q:
|
||||||
|
game_state->is_running = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// performed every frame
|
||||||
|
void
|
||||||
|
client_update_framebuffer() {
|
||||||
|
// draw a green square
|
||||||
|
// clear_framebuffer(0x000000);
|
||||||
|
// for (int i = 0; i < 20; i++) {
|
||||||
|
// for (int j = 0; j < 20; j++) {
|
||||||
|
// put_pixel(i, j, 0x00FF00);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// draw alternating green squares
|
||||||
|
if (left) {
|
||||||
|
clear_framebuffer(0x000000);
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
for (int j = 0; j < 20; j++) {
|
||||||
|
put_pixel(i, j, 0x00FF00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
left = false;
|
||||||
|
} else {
|
||||||
|
clear_framebuffer(0x000000);
|
||||||
|
for (int i = 20; i < 40; i++) {
|
||||||
|
for (int j = 20; j < 40; j++) {
|
||||||
|
put_pixel(i, j, 0x00FFFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
left = true;
|
||||||
|
}
|
||||||
|
SDL_Delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// initialize the engine
|
||||||
|
if (engine_init(
|
||||||
|
client_poll_event,
|
||||||
|
client_update_framebuffer
|
||||||
|
)) {
|
||||||
|
engine_start();
|
||||||
|
engine_stop();
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user