initial commit

This commit is contained in:
Alessandro Mauri 2025-05-20 21:43:18 +02:00
commit 6f73f2d443
35 changed files with 4673 additions and 0 deletions

240
test/gpu_triangle.c3 Normal file
View file

@ -0,0 +1,240 @@
import std::io;
import sdl3::sdl;
import std::io::file;
import std::core::mem;
const int WINDOW_WIDTH = 1200;
const int WINDOW_HEIGHT = 800;
const ZString WINDOW_TITLE = "Basic Triangle";
fn GPUShader* load_shader(GPUDevice* device, ZString filename, GPUShaderStage stage, uint sampler_count, uint uniform_buffer_count, uint storage_buffer_count, uint storage_texture_count)
{
//if(!SDL_GetPathInfo(filename, null)) {
// io::eprintf("File (%s) does not exist.\n", filename);
// return null;
//}
if (!file::is_file(filename.str_view())) {
io::eprintf("File %s is not a file\n", filename);
return null;
}
ZString entrypoint;
GPUShaderFormat backend_formats = sdl::get_gpu_shader_formats(device);
GPUShaderFormat format = sdl::GPU_SHADERFORMAT_INVALID;
if (backend_formats & sdl::GPU_SHADERFORMAT_SPIRV) {
format = sdl::GPU_SHADERFORMAT_SPIRV;
entrypoint = "main";
}
usz code_size = file::get_size(filename.str_view())!!;
char[] code = mem::new_array(char, code_size+1);
file::load_buffer(filename.str_view(), code)!!;
GPUShaderCreateInfo shader_info = {
.code = code.ptr,
.code_size = code.len,
.entrypoint = entrypoint,
.format = format,
.stage = stage,
.num_samplers = sampler_count,
.num_uniform_buffers = uniform_buffer_count,
.num_storage_buffers = storage_buffer_count,
.num_storage_textures = storage_texture_count
};
GPUShader* shader = sdl::create_gpu_shader(device, &shader_info);
if (shader == null) {
io::eprintf("ERROR: SDL_CreateGPUShader failed: %s\n", sdl::get_error());
sdl::free(code);
return null;
}
sdl::free(code);
return shader;
}
fn void print_info()
{
int render_drivers = sdl::get_num_render_drivers();
io::printf("Number of render drivers: %d\n", render_drivers)!!;
for (int i = 0; i < render_drivers; i++) {
io::printf("Render driver #%d: %s\n", i, sdl::get_render_driver(i))!!;
}
int video_drivers = sdl::get_num_video_drivers();
io::printf("Number of video drivers: %d\n", video_drivers)!!;
for (int i = 0; i < video_drivers; i++) {
io::printf("Video driver #%d: %s\n", i, sdl::get_video_driver(i))!!;
}
io::printf("Current video driver: %s\n", sdl::get_current_video_driver())!!;
}
fn void handle_event(Event event, bool* quit) {
switch (event.type) {
case sdl::EVENT_QUIT: {
*quit = true;
} break;
case sdl::EVENT_KEY_DOWN: {
switch (event.key.key) {
case sdl::K_Q: {
*quit = true;
} break;
case sdl::K_W: {
} break;
case sdl::K_S: {
} break;
case sdl::K_D: {
} break;
}
} break;
}
}
fn int main() {
sdl::set_hint(sdl::HINT_VIDEO_DRIVER, "wayland");
if (!sdl::init(sdl::INIT_VIDEO)) {
io::eprintf("ERROR: SDL_Init failed: %s\n", sdl::get_error());
return 1;
}
Window* window;
window = sdl::create_window(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, sdl::WINDOW_VULKAN);
if (window == null) {
io::eprintf("ERROR: SDL_CreateWindow failed: %s\n", sdl::get_error());
return 1;
}
sdl::set_window_position(window, sdl::WINDOWPOS_CENTERED, sdl::WINDOWPOS_CENTERED);
GPUDevice* device = sdl::create_gpu_device(sdl::GPU_SHADERFORMAT_SPIRV, true, null);
if (device == null) {
io::eprintf("ERROR: SDL_CreateGPUDevice failed: %s\n", sdl::get_error());
return 1;
}
ZString device_driver = sdl::get_gpu_device_driver(device);
io::printf("OK: Created device with driver %s\n", device_driver)!!;
if (!sdl::claim_window_for_gpu_device(device, window)) {
io::eprintf("ERROR: SDL_ClaimWindowForGPUDevice failed: %s\n", sdl::get_error());
return 1;
}
// Load shaders + create fill/line pipeline
GPUShader* shader_vert = load_shader(device, "shaders/compiled/RawTriangle.vert.spv", GPU_SHADERSTAGE_VERTEX, 0, 0, 0, 0);
if (shader_vert == null) {
io::eprintf("ERROR: LoadShader failed \n");
return 1;
}
GPUShader* shader_frag = load_shader(device, "shaders/compiled/SolidColor.frag.spv", GPU_SHADERSTAGE_FRAGMENT, 0, 0, 0, 0);
if (shader_vert == null) {
io::eprintf("ERROR: LoadShader failed \n");
return 1;
}
GPUGraphicsPipelineCreateInfo pipeline_info = {
.target_info = {
.num_color_targets = 1,
.color_target_descriptions = (GPUColorTargetDescription[]){{
.format = sdl::get_gpu_swapchain_texture_format(device, window)
}},
},
.primitive_type = GPUPrimitiveType.GPU_PRIMITIVETYPE_TRIANGLELIST,
.vertex_shader = shader_vert,
.fragment_shader = shader_frag,
};
GPUGraphicsPipeline* pipeline_fill;
GPUGraphicsPipeline* pipeline_line;
pipeline_info.rasterizer_state.fill_mode = GPU_FILLMODE_FILL;
pipeline_fill = sdl::create_gpu_graphics_pipeline(device, &pipeline_info);
if (pipeline_fill == null) {
io::eprintf("ERROR: SDL_CreateGPUGraphicsPipeline failed: %s\n", sdl::get_error());
return -1;
}
pipeline_info.rasterizer_state.fill_mode = GPU_FILLMODE_LINE;
pipeline_line = sdl::create_gpu_graphics_pipeline(device, &pipeline_info);
if (pipeline_line == null) {
io::eprintf("ERROR: SDL_CreateGPUGraphicsPipeline failed: %s\n", sdl::get_error());
return -1;
}
sdl::release_gpu_shader(device, shader_vert);
sdl::release_gpu_shader(device, shader_frag);
const FColor COLOR_WHITE = (FColor) { 1.0f, 1.0f, 1.0f, 1.0f };
const FColor COLOR_BLACK = (FColor) { 0.0f, 0.0f, 0.0f, 1.0f };
const FColor COLOR_RED = (FColor) { 1.0f, 0.0f, 0.0f, 1.0f };
const FColor COLOR_GREEN = (FColor) { 0.0f, 1.0f, 0.0f, 1.0f };
const FColor COLOR_BLUE = (FColor) { 0.0f, 0.0f, 1.0f, 1.0f };
const FColor COLOR_CYAN = (FColor) { 0.0f, 1.0f, 1.0f, 1.0f };
const FColor COLOR_YELLOW = (FColor) { 1.0f, 1.0f, 0.0f, 1.0f };
const FColor COLOR_PINK = (FColor) { 1.0f, 0.0f, 1.0f, 1.0f };
print_info();
bool quit = false;
while (!quit) {
Event event;
if (sdl::poll_event(&event)) handle_event(event, &quit);
GPUCommandBuffer* cmdbuf = sdl::acquire_gpu_command_buffer(device);
if (cmdbuf == null) {
io::eprintf("ERROR: SDL_AcquireGPUCommandBuffer failed: %s\n", sdl::get_error());
break;
}
GPUTexture* swapchain_texture;
if (!sdl::wait_and_acquire_gpu_swapchain_texture(cmdbuf, window, &swapchain_texture, null, null)) {
io::eprintf("ERROR: SDL_WaitAndAcquireGPUSwapchainTexture failed: %s\n", sdl::get_error());
break;
}
if (swapchain_texture == null) {
io::eprintf("ERROR: swapchain_texture is null\n");
sdl::submit_gpu_command_buffer(cmdbuf);
break;
}
GPUColorTargetInfo color_target_info;
color_target_info.texture = swapchain_texture;
color_target_info.clear_color = COLOR_BLACK;
color_target_info.load_op = GPULoadOp.GPU_LOADOP_CLEAR;
color_target_info.store_op = GPUStoreOp.GPU_STOREOP_STORE;
GPURenderPass* render_pass = sdl::begin_gpu_render_pass(cmdbuf, &color_target_info, 1, null);
sdl::bind_gpu_graphics_pipeline(render_pass, pipeline_fill);
sdl::draw_gpu_primitives(render_pass, 3, 1, 0, 0);
sdl::end_gpu_render_pass(render_pass);
sdl::submit_gpu_command_buffer(cmdbuf);
}
sdl::release_gpu_graphics_pipeline(device, pipeline_fill);
sdl::release_gpu_graphics_pipeline(device, pipeline_line);
sdl::release_window_from_gpu_device(device, window);
sdl::destroy_window(window);
sdl::destroy_gpu_device(device);
sdl::quit();
return 0;
}

63
test/lettuce.c3 Normal file
View file

@ -0,0 +1,63 @@
import std::io;
import sdl3::sdl;
fn int main() {
sdl::init(sdl::INIT_VIDEO);
Window* win = sdl::create_window("SDL3 Image", 640, 480, 0);
if (win == null) {
io::eprintfn("SDL_CreateWindow Error: %s", sdl::get_error());
sdl::quit();
return 1;
}
Renderer* ren = sdl::create_renderer(win, null);
if (ren == null) {
io::eprintfn("SDL_CreateRenderer Error: %s", sdl::get_error());
sdl::destroy_window(win);
sdl::quit();
return 1;
}
Surface* bmp = sdl::load_bmp("lettuce.bmp");
if (bmp == null) {
io::eprintfn("SDL_LoadBMP Error: %s", sdl::get_error());
sdl::destroy_renderer(ren);
sdl::destroy_window(win);
sdl::quit();
return 1;
}
Texture* tex = sdl::create_texture_from_surface(ren, bmp);
sdl::destroy_surface(bmp);
if (tex == null) {
io::eprintfn("SDL_CreateTextureFromSurface Error: %s", sdl::get_error());
sdl::destroy_renderer(ren);
sdl::destroy_window(win);
sdl::quit();
return 1;
}
Event e;
bool quit = false;
while (!quit) {
while (sdl::poll_event(&e)) {
if (e.type == sdl::EVENT_QUIT) {
quit = true;
}
}
sdl::render_clear(ren);
sdl::render_texture(ren, tex, null, null);
sdl::render_present(ren);
}
sdl::destroy_texture(tex);
sdl::destroy_renderer(ren);
sdl::destroy_window(win);
sdl::quit();
return 0;
}

162
test/test_enum.c3 Normal file
View file

@ -0,0 +1,162 @@
enum OtherEnum : int
{
ABC,
DEF,
GHI
}
enum EventType : (inline int val)
{
SDL_EVENT_FIRST = 0,
SDL_EVENT_QUIT = 0x100,
SDL_EVENT_TERMINATING,
SDL_EVENT_LOW_MEMORY,
SDL_EVENT_WILL_ENTER_BACKGROUND,
SDL_EVENT_DID_ENTER_BACKGROUND,
SDL_EVENT_WILL_ENTER_FOREGROUND,
SDL_EVENT_DID_ENTER_FOREGROUND,
SDL_EVENT_LOCALE_CHANGED,
SDL_EVENT_SYSTEM_THEME_CHANGED,
SDL_EVENT_DISPLAY_ORIENTATION = 0x151,
SDL_EVENT_DISPLAY_ADDED,
SDL_EVENT_DISPLAY_REMOVED,
SDL_EVENT_DISPLAY_MOVED,
SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED,
SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED,
SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED,
SDL_EVENT_DISPLAY_FIRST = SDL_EVENT_DISPLAY_ORIENTATION,
SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED,
SDL_EVENT_WINDOW_SHOWN = 0x202,
SDL_EVENT_WINDOW_HIDDEN,
SDL_EVENT_WINDOW_EXPOSED,
SDL_EVENT_WINDOW_MOVED,
SDL_EVENT_WINDOW_RESIZED,
SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED,
SDL_EVENT_WINDOW_METAL_VIEW_RESIZED,
SDL_EVENT_WINDOW_MINIMIZED,
SDL_EVENT_WINDOW_MAXIMIZED,
SDL_EVENT_WINDOW_RESTORED,
SDL_EVENT_WINDOW_MOUSE_ENTER,
SDL_EVENT_WINDOW_MOUSE_LEAVE,
SDL_EVENT_WINDOW_FOCUS_GAINED,
SDL_EVENT_WINDOW_FOCUS_LOST,
SDL_EVENT_WINDOW_CLOSE_REQUESTED,
SDL_EVENT_WINDOW_HIT_TEST,
SDL_EVENT_WINDOW_ICCPROF_CHANGED,
SDL_EVENT_WINDOW_DISPLAY_CHANGED,
SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED,
SDL_EVENT_WINDOW_SAFE_AREA_CHANGED,
SDL_EVENT_WINDOW_OCCLUDED,
SDL_EVENT_WINDOW_ENTER_FULLSCREEN,
SDL_EVENT_WINDOW_LEAVE_FULLSCREEN,
SDL_EVENT_WINDOW_DESTROYED,
SDL_EVENT_WINDOW_HDR_STATE_CHANGED,
SDL_EVENT_WINDOW_FIRST = SDL_EVENT_WINDOW_SHOWN,
SDL_EVENT_WINDOW_LAST = SDL_EVENT_WINDOW_HDR_STATE_CHANGED,
SDL_EVENT_KEY_DOWN = 0x300,
SDL_EVENT_KEY_UP,
SDL_EVENT_TEXT_EDITING,
SDL_EVENT_TEXT_INPUT,
SDL_EVENT_KEYMAP_CHANGED,
SDL_EVENT_KEYBOARD_ADDED,
SDL_EVENT_KEYBOARD_REMOVED,
SDL_EVENT_TEXT_EDITING_CANDIDATES,
SDL_EVENT_MOUSE_MOTION = 0x400,
SDL_EVENT_MOUSE_BUTTON_DOWN,
SDL_EVENT_MOUSE_BUTTON_UP,
SDL_EVENT_MOUSE_WHEEL,
SDL_EVENT_MOUSE_ADDED,
SDL_EVENT_MOUSE_REMOVED,
SDL_EVENT_JOYSTICK_AXIS_MOTION = 0x600,
SDL_EVENT_JOYSTICK_BALL_MOTION,
SDL_EVENT_JOYSTICK_HAT_MOTION,
SDL_EVENT_JOYSTICK_BUTTON_DOWN,
SDL_EVENT_JOYSTICK_BUTTON_UP,
SDL_EVENT_JOYSTICK_ADDED,
SDL_EVENT_JOYSTICK_REMOVED,
SDL_EVENT_JOYSTICK_BATTERY_UPDATED,
SDL_EVENT_JOYSTICK_UPDATE_COMPLETE,
SDL_EVENT_GAMEPAD_AXIS_MOTION = 0x650,
SDL_EVENT_GAMEPAD_BUTTON_DOWN,
SDL_EVENT_GAMEPAD_BUTTON_UP,
SDL_EVENT_GAMEPAD_ADDED,
SDL_EVENT_GAMEPAD_REMOVED,
SDL_EVENT_GAMEPAD_REMAPPED,
SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN,
SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION,
SDL_EVENT_GAMEPAD_TOUCHPAD_UP,
SDL_EVENT_GAMEPAD_SENSOR_UPDATE,
SDL_EVENT_GAMEPAD_UPDATE_COMPLETE,
SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED,
SDL_EVENT_FINGER_DOWN = 0x700,
SDL_EVENT_FINGER_UP,
SDL_EVENT_FINGER_MOTION,
SDL_EVENT_FINGER_CANCELED,
SDL_EVENT_CLIPBOARD_UPDATE = 0x900,
SDL_EVENT_DROP_FILE = 0x1000,
SDL_EVENT_DROP_TEXT,
SDL_EVENT_DROP_BEGIN,
SDL_EVENT_DROP_COMPLETE,
SDL_EVENT_DROP_POSITION,
SDL_EVENT_AUDIO_DEVICE_ADDED = 0x1100,
SDL_EVENT_AUDIO_DEVICE_REMOVED,
SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED,
SDL_EVENT_SENSOR_UPDATE = 0x1200,
SDL_EVENT_PEN_PROXIMITY_IN = 0x1300,
SDL_EVENT_PEN_PROXIMITY_OUT,
SDL_EVENT_PEN_DOWN,
SDL_EVENT_PEN_UP,
SDL_EVENT_PEN_BUTTON_DOWN,
SDL_EVENT_PEN_BUTTON_UP,
SDL_EVENT_PEN_MOTION,
SDL_EVENT_PEN_AXIS,
SDL_EVENT_CAMERA_DEVICE_ADDED = 0x1400,
SDL_EVENT_CAMERA_DEVICE_REMOVED,
SDL_EVENT_CAMERA_DEVICE_APPROVED,
SDL_EVENT_CAMERA_DEVICE_DENIED,
SDL_EVENT_RENDER_TARGETS_RESET = 0x2000,
SDL_EVENT_RENDER_DEVICE_RESET,
SDL_EVENT_RENDER_DEVICE_LOST,
SDL_EVENT_PRIVATE0 = 0x4000,
SDL_EVENT_PRIVATE1,
SDL_EVENT_PRIVATE2,
SDL_EVENT_PRIVATE3,
SDL_EVENT_POLL_SENTINEL = 0x7F00,
SDL_EVENT_USER = 0x8000,
SDL_EVENT_LAST = 0xFFFF,
SDL_EVENT_ENUM_PADDING = 0x7FFFFFFF
}
import std::io;
fn int main()
{
EventType ev = SDL_EVENT_WINDOW_RESIZED;
io::printfn("%d == %d", SDL_EVENT_WINDOW_RESIZED, ev);
return 0;
}