...
This commit is contained in:
76
main.sx
76
main.sx
@@ -1,40 +1,24 @@
|
||||
#import "modules/std.sx";
|
||||
#import "build.sx";
|
||||
#import "modules/compiler.sx";
|
||||
#import "modules/sdl3.sx";
|
||||
#import "modules/opengl.sx";
|
||||
#import "modules/math";
|
||||
#import "modules/stb.sx";
|
||||
#import "modules/stb_truetype.sx";
|
||||
#import "modules/wasm.sx";
|
||||
#import "ui";
|
||||
|
||||
configure_build :: () {
|
||||
opts := build_options();
|
||||
inline if OS == {
|
||||
case .wasm: {
|
||||
opts.set_output_path(if POINTER_SIZE == 4 then "sx-out/wasm32/index.html" else "sx-out/wasm32/index.html");
|
||||
opts.add_link_flag("-sUSE_SDL=3");
|
||||
opts.add_link_flag("-sMAX_WEBGL_VERSION=2");
|
||||
opts.add_link_flag("-sFULL_ES3=1");
|
||||
opts.add_link_flag("--preload-file assets");
|
||||
opts.add_link_flag("-sALLOW_MEMORY_GROWTH=1");
|
||||
}
|
||||
case .macos: {
|
||||
opts.set_output_path("sx-out/macos/game");
|
||||
}
|
||||
}
|
||||
}
|
||||
#run configure_build();
|
||||
|
||||
libc :: #library "c";
|
||||
emscripten_set_main_loop :: (func: *void, fps: s32, sim_infinite: s32) #foreign libc;
|
||||
|
||||
WIDTH :f32: 800;
|
||||
HEIGHT :f32: 600;
|
||||
|
||||
// --- Frame state (globals for emscripten callback) ---
|
||||
g_window : *void = ---;
|
||||
g_pipeline : *UIPipeline = ---;
|
||||
g_running : bool = true;
|
||||
g_width : s32 = 800; // logical window size
|
||||
g_height : s32 = 600;
|
||||
g_pixel_w : s32 = 800; // physical pixel size
|
||||
g_pixel_h : s32 = 600;
|
||||
|
||||
load_texture :: (path: [:0]u8) -> u32 {
|
||||
w : s32 = 0;
|
||||
@@ -141,13 +125,13 @@ run_ui_tests :: (pipeline: *UIPipeline) {
|
||||
// Render after tests and save snapshot to see scrolled state
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
pipeline.tick();
|
||||
save_snapshot("goldens/test_after_drag.png", xx WIDTH, xx HEIGHT);
|
||||
save_snapshot("goldens/test_after_drag.png", g_pixel_w, g_pixel_h);
|
||||
}
|
||||
|
||||
// One frame of the main loop — called repeatedly by emscripten or desktop while-loop
|
||||
frame :: () {
|
||||
sdl_event : SDL_Event = .none;
|
||||
while SDL_PollEvent(sdl_event) {
|
||||
while SDL_PollEvent(@sdl_event) {
|
||||
print("SDL event: {}\n", sdl_event.tag);
|
||||
|
||||
if sdl_event == {
|
||||
@@ -155,17 +139,24 @@ frame :: () {
|
||||
case .key_up: (e) {
|
||||
if e.key == { case .escape: { g_running = false; } }
|
||||
}
|
||||
case .window_resized: (data) {
|
||||
g_width = data.data1;
|
||||
g_height = data.data2;
|
||||
SDL_GetWindowSizeInPixels(g_window, @g_pixel_w, @g_pixel_h);
|
||||
g_pipeline.resize(xx g_width, xx g_height);
|
||||
}
|
||||
}
|
||||
|
||||
ui_event := translate_sdl_event(@sdl_event);
|
||||
if ui_event != .none {
|
||||
print(" ui event dispatched\n");
|
||||
g_pipeline.*.dispatch_event(@ui_event);
|
||||
g_pipeline.dispatch_event(@ui_event);
|
||||
} else {
|
||||
print(" -> .none\n");
|
||||
}
|
||||
}
|
||||
|
||||
glViewport(0, 0, g_pixel_w, g_pixel_h);
|
||||
glClearColor(0.12, 0.12, 0.15, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
@@ -189,17 +180,42 @@ main :: () -> void {
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
|
||||
window := SDL_CreateWindow("SX UI Demo", xx WIDTH, xx HEIGHT, SDL_WINDOW_OPENGL);
|
||||
// Auto-size: on desktop use 75% of usable display, on WASM SDL picks up canvas size
|
||||
init_w : s32 = 800;
|
||||
init_h : s32 = 600;
|
||||
inline if OS == .wasm {
|
||||
init_w = emscripten_run_script_int("window.innerWidth");
|
||||
init_h = emscripten_run_script_int("window.innerHeight");
|
||||
} else {
|
||||
display_id := SDL_GetPrimaryDisplay();
|
||||
bounds : SDL_Rect = ---;
|
||||
if SDL_GetDisplayUsableBounds(display_id, @bounds) {
|
||||
init_w = bounds.w * 3 / 4;
|
||||
init_h = bounds.h * 3 / 4;
|
||||
}
|
||||
}
|
||||
|
||||
window := SDL_CreateWindow("SX UI Demo", init_w, init_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY);
|
||||
gl_ctx := SDL_GL_CreateContext(window);
|
||||
SDL_GL_MakeCurrent(window, gl_ctx);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
load_gl(xx SDL_GL_GetProcAddress);
|
||||
|
||||
// Query actual window size (may differ from requested, especially on WASM)
|
||||
SDL_GetWindowSize(window, @g_width, @g_height);
|
||||
SDL_GetWindowSizeInPixels(window, @g_pixel_w, @g_pixel_h);
|
||||
width_f : f32 = xx g_width;
|
||||
height_f : f32 = xx g_height;
|
||||
dpi_scale : f32 = if width_f > 0.0 then xx g_pixel_w / width_f else 1.0;
|
||||
|
||||
// Set viewport to physical pixel dimensions
|
||||
glViewport(0, 0, g_pixel_w, g_pixel_h);
|
||||
|
||||
// --- Build UI ---
|
||||
pipeline : UIPipeline = ---;
|
||||
pipeline.init(WIDTH, HEIGHT);
|
||||
pipeline.init_font("assets/fonts/default.ttf", 32.0);
|
||||
pipeline.init(width_f, height_f);
|
||||
pipeline.init_font("assets/fonts/default.ttf", 32.0, dpi_scale);
|
||||
|
||||
scroll_content := VStack.{ spacing = 10.0, alignment = .center } {
|
||||
self.add(
|
||||
@@ -220,7 +236,7 @@ main :: () -> void {
|
||||
});
|
||||
self.add(
|
||||
RectView.{ color = COLOR_DARK_GRAY, preferred_height = 60.0 }
|
||||
|> padding(EdgeInsets.symmetric(16.0, 8.0))
|
||||
|> padding(.symmetric(16.0, 8.0))
|
||||
|> background(COLOR_BLUE, 8.0)
|
||||
);
|
||||
self.add(RectView.{ color = COLOR_ORANGE, preferred_height = 120.0, corner_radius = 12.0 });
|
||||
@@ -243,6 +259,8 @@ main :: () -> void {
|
||||
}
|
||||
}
|
||||
|
||||
save_snapshot("goldens/last_frame.png", g_pixel_w, g_pixel_h);
|
||||
|
||||
SDL_GL_DestroyContext(gl_ctx);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
|
||||
Reference in New Issue
Block a user