work on engine and small demo game

This commit is contained in:
Tuomas Katajisto 2025-08-22 16:41:12 +03:00
parent 495c02e1b1
commit e31a52e049
12 changed files with 237 additions and 11 deletions

View File

@ -1,19 +1,33 @@
#scope_file
cam : Camera;
world : World;
#scope_export
#load "./roule/roule.jai";
bg_tex : Ui_Texture;
#scope_export
game_init :: () {
print("Game init...\n");
cam.position = .{5,5,5};
cam.target = .{3,6,3};
cam.near = 0.1;
cam.far = 5000;
print("Loading bg...\n");
img := create_texture_from_pack("./game/resources/bg.png");
bg_tex.tex = img;
table_init();
}
game_tick :: () {
if input_button_states[#char "W"] & .START {
table_roll();
}
}
game_draw :: () {
draw_sky(*cam, *world.conf);
w,h := get_window_size();
set_shader_for_images(*bg_tex);
immediate_rect(0,0,xx w,xx h);
immediate_flush();
draw_table();
}

BIN
game/resources/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

BIN
game/resources/roule.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

125
game/roule/roule.jai Normal file
View File

@ -0,0 +1,125 @@
// #scope_file
random :: #import "Random";
Color :: enum {
RED;
BLACK;
GREEN;
};
RouleMode :: enum {
WAITING;
ANIMATING;
DONE;
};
Slot :: struct {
color : Color;
number : int;
};
RouleTable :: struct {
animStart : float = -1;
angle : float = 0;
slot : Slot = .{};
mode : RouleMode = .WAITING;
};
tableState : RouleTable;
rouleSlots : []Slot = .[
.{.GREEN, 0},
.{.RED, 32},
.{.BLACK, 15},
.{.RED, 19},
.{.BLACK, 4},
.{.RED, 21},
.{.BLACK, 2},
.{.RED, 25},
.{.BLACK, 17},
.{.RED, 34},
.{.BLACK, 6},
.{.RED, 27},
.{.BLACK, 13},
.{.RED, 36},
.{.BLACK, 11},
.{.RED, 30},
.{.BLACK, 8},
.{.RED, 23},
.{.BLACK, 10},
.{.RED, 5},
.{.BLACK, 24},
.{.RED, 16},
.{.BLACK, 33},
.{.RED, 1},
.{.BLACK, 20},
.{.RED, 14},
.{.BLACK, 31},
.{.RED, 9},
.{.BLACK, 22},
.{.RED, 18},
.{.BLACK, 29},
.{.RED, 7},
.{.BLACK, 28},
.{.RED, 12},
.{.BLACK, 35},
.{.RED, 3},
.{.BLACK, 26},
];
get_roll_result :: () -> (Slot, float) {
slot := random.random_get() % rouleSlots.count.(u64);
return rouleSlots[xx slot], slot.(float) / rouleSlots.count.(float);
}
wheel_tex : Ui_Texture;
base_tex : Ui_Texture;
ball_tex : Ui_Texture;
WHEEL_SIZE :: 3.5;
get_ball :: () -> (ball_size: float, ball_speed: float) {
if tableState.mode == .WAITING {
return 4.7, -20;
} else if tableState.mode == .ANIMATING {
return lerp(4.7, 3, min(1.0, get_time().(float) - tableState.animStart.(float))), -20;
}
}
#scope_export
table_roll :: () {
tableState.animStart = get_time().(float);
tableState.slot, tableState.angle = get_roll_result();
tableState.mode = .ANIMATING;
}
table_init :: () {
img := create_texture_from_pack("./game/resources/roule-spin.png");
wheel_tex.tex = img;
img = create_texture_from_pack("./game/resources/roule.png");
base_tex.tex = img;
img = create_texture_from_pack("./game/resources/roule-ball.png");
ball_tex.tex = img;
}
draw_table :: () {
w,h := get_window_size();
uw := ui_w(10,0);
ball_size, ball_speed := get_ball();
diff := ball_size * uw - WHEEL_SIZE * uw;
set_shader_for_images(*base_tex);
immediate_rect((5-(WHEEL_SIZE/2)) * uw, 50,WHEEL_SIZE*uw,WHEEL_SIZE*uw);
immediate_flush();
set_shader_for_images(*wheel_tex);
immediate_rect((5-(WHEEL_SIZE/2)) * uw, 50,WHEEL_SIZE*uw,WHEEL_SIZE*uw, cast(float) get_time());
immediate_flush();
set_shader_for_images(*ball_tex);
immediate_rect((5-(ball_size/2)) * uw, 50 - diff/2 ,ball_size*uw,ball_size*uw, cast(float) (ball_size * -1 * get_time()));
immediate_flush();
}

View File

@ -196,6 +196,19 @@ draw_tacoma_tab :: (theme: *GR.Overall_Theme, total_r: GR.Rect) {
}
}
draw_trile_picker :: (theme: *GR.Overall_Theme) {
r := GR.get_rect(ui_w(85,85), ui_h(5,0), ui_w(15, 15), ui_h(95, 0));
draw_bg_rectangle(r, theme);
tpt := get_trile_table_ptr();
r.h = ui_h(4,4);
count := 0;
for v : tpt {
GR.button(r, v.name, *theme.button_theme, count);
count += 1;
r.y += r.h;
}
}
#scope_export
tick_level_editor :: () {
@ -272,4 +285,5 @@ draw_level_editor_ui :: (theme: *GR.Overall_Theme) {
case .INFO;
autoedit(r, *world.conf, theme);
}
draw_trile_picker(theme);
}

View File

@ -1,6 +1,6 @@
#scope_file
MAX_FILE_SIZE :: 200_000;
MAX_FILE_SIZE :: 2_000_000_000;
buf : [MAX_FILE_SIZE]u8;
g_asset_pack : Load_Package;
@ -12,6 +12,7 @@ packcb :: (res: *sfetch_response_t) #c_call {
mem : []u8;
mem.count = res.data.size.(s64);
mem.data = res.data.ptr;
print("Mem count %\n", mem.count);
success := init_from_memory(*g_asset_pack, mem, "main_asset_pack");
print("Succesfully loaded main asset pack!\n");

View File

@ -4,12 +4,13 @@ create_pack :: () {
util :: #import "File_Utilities";
files_to_pack := util.file_list("./resources", true);
files_to_pack_game := util.file_list("./game/resources", true);
package: Create_Package;
defer deinit(*package);
init(*package);
print("Packing % files -> ./packs/assets.pack\n", files_to_pack.count);
for files_to_pack {
file, ok := read_entire_file(it);
@ -22,6 +23,21 @@ create_pack :: () {
filedata.data = file.data;
add(*package, it, filedata);
}
for files_to_pack_game {
file, ok := read_entire_file(it);
if !ok {
print("Failed in loading file to pack: %\n", it);
continue;
}
filedata : []u8;
filedata.count = file.count;
filedata.data = file.data;
add(*package, it, filedata);
}
print("Packing % engine files -> ./packs/assets.pack\n", files_to_pack.count);
print("Packing % game files -> ./packs/assets.pack\n", files_to_pack_game.count);
write(*package, "./packs/assets.pack");
}

View File

@ -5,9 +5,10 @@
trile_gfx_table : Table(string, Trile_GFX);
trile_table : Table(string, Trile);
#scope_export
Trile_GFX :: struct {
trixel_colors : sg_image;
vertex_buffer : sg_buffer;
@ -17,6 +18,10 @@ Trile_GFX :: struct {
vertex_count : s64;
};
get_trile_table_ptr :: () -> *Table(string, Trile) {
return *trile_table;
}
// @Note: Creates the gfx things if they are not yet created.
// Could be a bad idea to do this implicitly. Think about it
// once it's more clear how this whole trile storage thing

View File

@ -236,6 +236,57 @@ immediate_triangle :: (p0: Vector3, p1: Vector3, p2: Vector3, c0 := Vector4.{1,1
arb_tri_add(tri);
}
immediate_rect :: (x: float, y: float, w: float, h: float, rotation: float = 0) {
if rotation == 0 {
immediate_quad(.{xx x, xx y}, .{xx x + w, xx y}, .{xx x + w, xx y + h}, .{xx x, xx y + h});
return;
}
// 1. Find the center of the rectangle, which will be our pivot point.
center_x := x + w / 2.0;
center_y := y + h / 2.0;
// 2. Pre-calculate the sine and cosine of the rotation angle.
// The angle is assumed to be in radians.
s := sin(rotation);
c := cos(rotation);
// 3. Define the corners relative to the origin (0,0) before rotation.
half_w := w / 2.0;
half_h := h / 2.0;
// Relative positions of the four corners
p1_rel_x := -half_w; p1_rel_y := -half_h; // Top-left
p2_rel_x := half_w; p2_rel_y := -half_h; // Top-right
p3_rel_x := half_w; p3_rel_y := half_h; // Bottom-right
p4_rel_x := -half_w; p4_rel_y := half_h; // Bottom-left
// 4. Apply the 2D rotation formula to each corner and add the center offset.
// The formula is:
// x' = x * cos(θ) - y * sin(θ)
// y' = x * sin(θ) + y * cos(θ)
p1x := center_x + p1_rel_x * c - p1_rel_y * s;
p1y := center_y + p1_rel_x * s + p1_rel_y * c;
p2x := center_x + p2_rel_x * c - p2_rel_y * s;
p2y := center_y + p2_rel_x * s + p2_rel_y * c;
p3x := center_x + p3_rel_x * c - p3_rel_y * s;
p3y := center_y + p3_rel_x * s + p3_rel_y * c;
p4x := center_x + p4_rel_x * c - p4_rel_y * s;
p4y := center_y + p4_rel_x * s + p4_rel_y * c;
// 5. Draw the quad using the final, rotated corner coordinates.
immediate_quad(
.{xx p1x, xx p1y},
.{xx p2x, xx p2y},
.{xx p3x, xx p3y},
.{xx p4x, xx p4y}
);
}
immediate_quad :: (p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2, color := Vector4.{1,1,1,1}, uv0 := Vector2.{0,0}, uv1 := Vector2.{1,0}, uv2 := Vector2.{1,1}, uv3 := Vector2.{0, 1}) {
to_3d_vec :: (v: Vector2) -> Vector3 {
return .{v.x, v.y, 0.0};