Skip to content

Commit

Permalink
Particles extension, Matrix3 & buncha fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
asbott committed Aug 28, 2024
1 parent e651487 commit 23c1462
Show file tree
Hide file tree
Showing 18 changed files with 1,128 additions and 157 deletions.
2 changes: 1 addition & 1 deletion build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ if not exist build (

pushd build

clang -g -fuse-ld=lld -o cgame.exe ../build.c -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -lkernel32 -lgdi32 -luser32 -lruntimeobject -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -lole32 -lshcore -lavrt -lksuser -ldbghelp -femit-all-decls
clang -g -fuse-ld=lld -o cgame.exe ../build.c -O0 -std=c11 -D_CRT_SECURE_NO_WARNINGS -Wextra -Wno-incompatible-library-redeclaration -Wno-sign-compare -Wno-unused-parameter -Wno-builtin-requires-header -lkernel32 -lgdi32 -luser32 -lruntimeobject -lwinmm -ld3d11 -ldxguid -ld3dcompiler -lshlwapi -lole32 -lshcore -lavrt -lksuser -ldbghelp -femit-all-decls

popd
13 changes: 10 additions & 3 deletions build.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
///
// Build config stuff

// To enable extensions:
// #define OOGABOOGA_ENABLE_EXTENSIONS 1
// #define OOGABOOGA_EXTENSION_PARTICLES 1

#define INITIAL_PROGRAM_MEMORY_SIZE MB(5)

// You might want to increase this if you get a log warning saying the temporary storage was overflown.
Expand All @@ -22,7 +26,7 @@ typedef struct Context_Extra {
#define CONTEXT_EXTRA Context_Extra

// This defaults to "entry", but we can set it to anything (except "main" or other existing proc names"
#define ENTRY_PROC entry
#define ENTRY_PROC entry

// Ooga booga needs to be included AFTER configuration and BEFORE the program code
#include "oogabooga/oogabooga.c"
Expand All @@ -33,7 +37,7 @@ typedef struct Context_Extra {
//

// This is a minimal starting point for new projects. Copy & rename to get started
// #include "oogabooga/examples/minimal_game_loop.c"
#include "oogabooga/examples/minimal_game_loop.c"

// #include "oogabooga/examples/text_rendering.c"
// #include "oogabooga/examples/custom_logger.c"
Expand All @@ -43,7 +47,10 @@ typedef struct Context_Extra {
// #include "oogabooga/examples/custom_shader.c"
// #include "oogabooga/examples/growing_array_example.c"
// #include "oogabooga/examples/input_example.c"
#include "oogabooga/examples/sprite_animation.c"
// #include "oogabooga/examples/sprite_animation.c"

// These examples require some extensions to be enabled. See top respective files for more info.
// #include "oogabooga/examples/particles_example.c" // Requires OOGABOOGA_EXTENSION_PARTICLES

// #include "oogabooga/examples/sanity_tests.c"

Expand Down
5 changes: 3 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ CFLAGS="-g -O0 -std=c11 --static -D_CRT_SECURE_NO_WARNINGS
-Wextra -Wno-sign-compare -Wno-unused-parameter
-lkernel32 -lgdi32 -luser32 -lruntimeobject
-lwinmm -ld3d11 -ldxguid -ld3dcompiler
-lshlwapi -lole32 -lavrt -lksuser -ldbghelp"
-lshlwapi -lole32 -lavrt -lksuser -ldbghelp
-lshcore"
SRC=../build.c
EXENAME=game.exe

mkdir build
mkdir -p build
cd build
$CC $SRC -o $EXENAME $CFLAGS
cd ..
39 changes: 39 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
## v0.01.006

- Build configuration
- Introduced an "extensions" system to be able to compile some extensions that might help with your game.
- To enable extensions, do #define OOGABOOGA_ENABLE_EXTENSIONS 1, then #define OOGABOOGA_EXTENSION_XXXXX 1
Also call ext_update(delta_time) and ext_draw() each frame.

- Implemented a Particles extension for particle emissions
- struct Emission_Config
- Emission_Handle emit_particles(config, position)


- Misc
- Added void *growing_array_add_multiple_empty(void **array, u64 count)
- Added void growing_array_add_multiple(void **array, void *items, u64 count)
- Added Matrix3 with:
- Matrix4 m3_to_m4(Matrix3 mat3)
- Matrix3 m3_scalar(float32 scalar)
- Matrix3 m3_identity()
- Matrix3 m3_make_translation(Vector2 translation)
- Matrix3 m3_make_rotation(float32 radians)
- Matrix3 m3_make_scale(Vector2 scale)
- Matrix3 m3_mul(Matrix3 a, Matrix3 b)
- Matrix3 m3_translate(Matrix3 m, Vector2 translation)
- Matrix3 m3_rotate(Matrix3 m, float32 radians)
- Matrix3 m3_scale(Matrix3 m, Vector2 scale)
- Matrix3 m3_inverse(Matrix3 m)
- Vector3 m3_transform(Matrix3 m, Vector3 v)
- Fixed Arena so it actually works
- Fixed sys keys not being handled as expected (such as LALT)
- Added some arena procedures:
- void *arena_push(Arena *arena, u64 size)
- #define arena_push_struct(parena, type)
- Allocator make_arena_allocator_from_arena(Arena *arena)
- Cleaned up some example stuff
- Fixed build.sh
- Made seed_for_random thread_local
- Added utility function float32 sine_oscillate_n_waves_normalized(float32 v, float32 n)

## v0.01.005 - Arenas, Monitor query, fullscreen

- Window
Expand Down
15 changes: 7 additions & 8 deletions oogabooga/examples/growing_array_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ int entry(int argc, char **argv) {
os_update(); // We set scaled window size, os_update updates the pixel window size values for us

for (int i = 0; i < num_circles; i++) {
Circle c;
c.radius = get_random_float32_in_range(radius_min, radius_max);
c.pos.x = get_random_float32_in_range(-(f32)window.width/2.0+c.radius, (f32)window.width/2.0-c.radius);
c.pos.y = get_random_float32_in_range(-(f32)window.height/2.0+c.radius, (f32)window.height/2.0-c.radius);
growing_array_add((void**)&circles, &c);
assert(circles[i].radius == c.radius);
assert(circles[i].pos.x == c.pos.x);
assert(circles[i].pos.y == c.pos.y);
float32 r = get_random_float32_in_range(radius_min, radius_max);
Vector2 p = v2(
get_random_float32_in_range(-(f32)window.width/2.0+r, (f32)window.width/2.0-r),
get_random_float32_in_range(-(f32)window.height/2.0+r, (f32)window.height/2.0-r)
);
// &(Circle){p, r} will only compile in true C, not in a C++ compiler
growing_array_add((void**)&circles, &(Circle){p, r});
}

float64 last_time = os_get_elapsed_seconds();
Expand Down
18 changes: 1 addition & 17 deletions oogabooga/examples/minimal_game_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,8 @@
int entry(int argc, char **argv) {

// This is how we (optionally) configure the window.
// You can set this at any point in the runtime and it will
// be applied in os_update().
// If you don't care, you can ignore all of this as it all
// has reasonable default values.
// To see all the settable window properties, ctrl+f "struct Os_Window" in os_interface.c
window.title = STR("Minimal Game Example");
window.scaled_width = 1280; // We need to set the scaled size if we want to handle system scaling (DPI)
window.scaled_height = 720;
window.x = 200;
window.y = 90;
window.clear_color = hex_to_rgba(0x6495EDff);
window.allow_resize = true;
window.fullscreen = false;

float64 last_time = os_get_elapsed_seconds();
while (!window.should_close) {
Expand All @@ -30,12 +20,6 @@ int entry(int argc, char **argv) {

draw_rect(v2(sin(now), -.8), v2(.5, .25), COLOR_RED);

float aspect = (f32)window.width/(f32)window.height;
float mx = (input_frame.mouse_x/(f32)window.width * 2.0 - 1.0)*aspect;
float my = input_frame.mouse_y/(f32)window.height * 2.0 - 1.0;

draw_line(v2(-.75, -.75), v2(mx, my), 0.005, COLOR_WHITE);

if (is_key_just_pressed('F')) {
window.fullscreen = !window.fullscreen;
}
Expand Down
177 changes: 177 additions & 0 deletions oogabooga/examples/particles_example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@


#if !OOGABOOGA_ENABLE_EXTENSIONS
#error particles_example.c requires OOGABOOGA_ENABLE_EXTENSIONS to be enabled
#endif
#if !OOGABOOGA_EXTENSION_PARTICLES
#error particles_example.c requires OOGABOOGA_EXTENSION_PARTICLES to be enabled
#endif

Emission_Config emission_rain;
Emission_Config emission_poof;
void setup_emission_configs();

int entry(int argc, char **argv) {

// This is how we (optionally) configure the window.
// To see all the settable window properties, ctrl+f "struct Os_Window" in os_interface.c
window.title = STR("Particles example");

setup_emission_configs();

Gfx_Font *font = load_font_from_disk(STR("C:/windows/fonts/arial.ttf"), get_heap_allocator());
assert(font, "Failed loading arial.ttf");

// Keep a stack of the looped emissions so we can pop them
Emission_Handle *emission_stack = 0;
growing_array_init((void**)&emission_stack, sizeof(Emission_Handle), get_heap_allocator());

float64 last_time = os_get_elapsed_seconds();
while (!window.should_close) {
reset_temporary_storage();

float64 now = os_get_elapsed_seconds();
float64 delta_time = now-last_time;

last_time = now;

draw_frame.projection = m4_make_orthographic_projection(window.pixel_width * -0.5, window.pixel_width * 0.5, window.pixel_height * -0.5, window.pixel_height * 0.5, -1, 10);

float mx = input_frame.mouse_x - window.width/2;
float my = input_frame.mouse_y - window.height/2;

// Left click: Emit a rain thingy and add to stack of rain emissions
if (is_key_just_pressed(MOUSE_BUTTON_LEFT)) {
Emission_Handle h = emit_particles(emission_rain, v2(mx, my));
growing_array_add((void**)&emission_stack, &h);
}

u64 num_emissions = growing_array_get_valid_count(emission_stack);
// Pop emissions on right click
if (is_key_just_pressed(MOUSE_BUTTON_RIGHT) && num_emissions > 0) {
Emission_Handle h = emission_stack[num_emissions-1];

emission_release(h);
growing_array_pop((void**)&emission_stack);
}

// Emit poof with spacebar, but just use one instance which is reset with a new seed
// (Most of the time you might just want to emit a new emission each time though, this
// is just showing that a resetting emission is possible)
if (is_key_just_pressed(KEY_SPACEBAR)) {

local_persist Emission_Handle inst = ZERO(Emission_Handle);
local_persist bool inst_set = false;

if (!inst_set) {
inst = emit_particles(emission_poof, v2(mx, my));
inst_set = true;
} else {
emission_poof.seed = get_random();
emission_set_config(inst, emission_poof);
emission_reset(inst);
emission_set_position(inst, v2(mx, my));
}
}



ext_update(delta_time);
ext_draw();

draw_text(font, tprint("FPS: %.2f", 1.0/delta_time), 32, v2(-window.width/2+30, window.height/2-60), v2(1, 1), COLOR_WHITE);

os_update();
gfx_update();
}

return 0;
}


void setup_emission_configs() {

Gfx_Image *img = load_image_from_disk(STR("oogabooga/examples/berry_bush.png"), get_heap_allocator());
assert(img, "Failed loading berry_bush.png");

//
// Rain

emission_rain.kind_pool[0] = PARTICLE_KIND_RECTANGLE;
emission_rain.kind_pool[1] = PARTICLE_KIND_CIRCLE;
emission_rain.kind_pool[2] = PARTICLE_KIND_IMAGE;
emission_rain.number_of_kinds = 3;

emission_rain.image_pool[0] = img;
emission_rain.number_of_images = 1;

emission_rain.loop = true; // Loop means first particle starts over after last particle is emitted
// If we want to loop without pauses, then number_of_particles needs to be at least
// life_time*emissions_per_second
emission_rain.number_of_particles = 600;
emission_rain.emissions_per_second = 100;

emission_rain.life_time.flat_f32 = 0.6;

// Color and size must be set for particles to be visible at all

emission_rain.color.mode = EMISSION_PROPERTY_MODE_INTERPOLATE;
emission_rain.color.interp_kind = EMISSION_INTERPOLATION_SMOOTH;
emission_rain.color.min_v4 = v4(0.85, 0.5, 0.5, 1.0);
emission_rain.color.max_v4 = v4(0.85, 0.5, 0.5, 0.0); // Fade out

emission_rain.size.flat_v2 = v2(16, 16);

// start_position is relative to the position which you emit at
emission_rain.start_position.mode = EMISSION_PROPERTY_MODE_RANDOM;
emission_rain.start_position.min_v2 = v2(-16, -16);
emission_rain.start_position.max_v2 = v2(16, 16);


emission_rain.velocity.mode = EMISSION_PROPERTY_MODE_RANDOM;
emission_rain.velocity.min_v2 = v2(-1000, -1000);
emission_rain.velocity.max_v2 = v2( 1000, 1000);

emission_rain.acceleration.flat_v2 = v2(0, -2500);

//
// Poof
emission_poof.kind_pool[0] = PARTICLE_KIND_RECTANGLE;
emission_poof.number_of_kinds = 1;

emission_poof.number_of_particles = 10;
emission_poof.emissions_per_second = 100;
emission_poof.loop = false;

// If we don't loop, the emission will get released when done.
// Alternatilvely, we set persist to true so we can keep it around to reset
// and potentially release manually with emission_release()
emission_poof.persist = true;

emission_poof.life_time.flat_f32 = 1.6;

emission_poof.velocity.mode = EMISSION_PROPERTY_MODE_RANDOM;
emission_poof.velocity.min_v2 = v2(-300, -300);
emission_poof.velocity.max_v2 = v2( 300, 300);

emission_poof.rotational_acceleration.mode = EMISSION_PROPERTY_MODE_RANDOM;
emission_poof.rotational_acceleration.min_f32 = -TAU32;
emission_poof.rotational_acceleration.max_f32 = TAU32;

// Fade out
emission_poof.color.mode = EMISSION_PROPERTY_MODE_INTERPOLATE;
emission_poof.color.min_v4 = COLOR_WHITE;
emission_poof.color.max_v4 = v4_zero;

// Shrink until death
emission_poof.size.mode = EMISSION_PROPERTY_MODE_INTERPOLATE;
emission_poof.size.interp_kind = EMISSION_INTERPOLATION_SMOOTH;
emission_poof.size.min_v2 = v2(16, 16);
emission_poof.size.max_v2 = v2(0, 0);

// For centered rotations, the pivot should interpolate same as size (but half)
emission_poof.pivot.mode = EMISSION_PROPERTY_MODE_INTERPOLATE;
emission_poof.pivot.interp_kind = EMISSION_INTERPOLATION_SMOOTH;
emission_poof.pivot.min_v2 = v2(8, 8);
emission_poof.pivot.max_v2 = v2(0, 0);
}
Loading

0 comments on commit 23c1462

Please sign in to comment.