Skip to content

Commit a363433

Browse files
committed
2023.4
new: added camera_fov() new: added file checksums (file_crc32, file_md5, file_sha1) new: added ui_enable() / ui_disable() (fwk_ui) new: added window_color() (fwk_window) new: added waypoints in demo/04-actor.c for upcoming AI pass new: added navmesh test files from mikko mononen for upcoming NAV pass brk: camera_teleport() signature brk: deprecated mesh_create(), renamed mesh_upgrade() > mesh_update() (fwk_render) brk: renamed fourcc > cc4; added cc8 brk: renamed FWK_C > FWK_IMPLEMENTATION directive brk: renamed os_exec > app_exec, cpu_cores > app_cores, battery > app_battery, signals_install > signal_hooks chg: reduced hello.c size (/) chg: tweaked font sizes H1..H6 (fwk_font) chg: updated roadmap fix: added missing EASE_FLAGS for ease() fix: fixed 04-actor.c not being compiled on tcc+linux fix: fixed hello.c not being compiled as objc file (osx, MAKE.bat) fix: normalized zero-length vectors (norm2/3/4) fix: prevented profiler panel from overlapping other panels with PANEL_OPEN flag (fwk_profile) fix: removed extra arg in array_pop_front() fix: updated docs fix: updated doom/anarch makefiles lab: added 04-lod demo, 3rd_polychop.h (demos/) lab: added experimental python bindings (demo_python.py, fwk.py) lab: added behavior tree for upcoming demo
1 parent c54314f commit a363433

File tree

1,821 files changed

+2108142
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,821 files changed

+2108142
-0
lines changed

2023.4/MAKE.bat

Lines changed: 683 additions & 0 deletions
Large diffs are not rendered by default.

2023.4/README.md

Lines changed: 367 additions & 0 deletions
Large diffs are not rendered by default.

2023.4/demos/00-ui.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// hello ui: config, window, system, ui, video
2+
// - rlyeh, public domain.
3+
//
4+
// Compile with:
5+
// `make demos\00-ui.c` (windows)
6+
// `sh MAKE.bat demos/00-ui.c` (linux, osx)
7+
8+
#include "fwk.h"
9+
10+
int main() {
11+
float app_volume = 1.00f;
12+
unsigned app_size = flag("--fullscreen") ? 100 : 75;
13+
unsigned app_flags = flag("--msaa") ? WINDOW_MSAA4 : 0;
14+
unsigned app_target_fps = optioni("--fps", 60); // --fps=30, --fps=45, etc. defaults to 60.
15+
16+
// window api (fullscreen or 75% sized, optional MSAA flags)
17+
window_create(app_size, app_flags);
18+
window_title(__FILE__);
19+
window_fps_lock(app_target_fps);
20+
21+
// load video
22+
video_t *v = video( "bjork-all-is-full-of-love.mp4", VIDEO_RGB );
23+
24+
// app loop
25+
while( window_swap() ) {
26+
// input controls
27+
if( input(KEY_ESC) ) break;
28+
29+
// profile api
30+
texture_t *textures;
31+
profile( "Video decoder" ) {
32+
// video api: decode frame and get associated textures (audio is sent to audiomixer automatically)
33+
textures = video_decode( v );
34+
// fullscreen video
35+
// if(video_is_rgb(v)) fullscreen_quad_rgb( textures[0], 1.3f );
36+
// else fullscreen_quad_ycbcr( textures, 1.3f );
37+
}
38+
39+
// create menubar on top
40+
int choice1 = ui_menu("File;Shell;Exit");
41+
int choice2 = ui_menu("Help;About");
42+
if( choice1 == 1 ) system(ifdef(win32, "start \"\" cmd", ifdef(osx, "open sh", "xdg-open sh")));
43+
if( choice1 == 2 ) exit(0);
44+
45+
// showcase a few ui widgets
46+
ui_demo(0);
47+
48+
// create ui panel
49+
if( ui_panel("myPanel", PANEL_OPEN) ) {
50+
// Print some numbers
51+
ui_section("Stats");
52+
ui_label2("FPS", va("%5.2f", window_fps()));
53+
ui_separator();
54+
55+
// add some buttons
56+
ui_section("Buttons");
57+
if( ui_button("Screenshot") ) window_screenshot(__FILE__ ".png"), ui_notify(0,ICON_MD_WARNING "Screenshot");
58+
if( ui_button("Record Video") ) window_record(__FILE__ ".mp4"), ui_notify(0,ICON_MD_WARNING "Recoding video");
59+
if( ui_button("Toggle fullscreen") ) window_fullscreen( !window_has_fullscreen() );
60+
ui_separator();
61+
62+
// some more video controls
63+
ui_section("Video");
64+
if( ui_button("Rewind") ) video_seek(v, video_position(v) - 3);
65+
if( ui_button("Pause") ) video_pause(v, video_is_paused(v) ^ 1);
66+
if( ui_button("Forward") ) video_seek(v, video_position(v) + 3);
67+
if( ui_slider2("Volume", &app_volume, va("%.2f", app_volume))) audio_volume_master(app_volume);
68+
69+
// end of panel. must be enclosed within same if() branch.
70+
ui_panel_end();
71+
}
72+
73+
// create window
74+
static int open = 1;
75+
if( ui_window("myWindow", &open) ) {
76+
// present decoded texture in a widget, without any label (NULL)
77+
ui_texture( NULL, textures[0] );
78+
// end of window. must be enclosed within same if() branch.
79+
ui_window_end();
80+
}
81+
}
82+
}
83+
84+
// this demo supersedes following old sources:
85+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-hello.c
86+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-video.c

2023.4/demos/00-ui.png

194 KB
Loading

2023.4/demos/01-sprite.c

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// sprite demo: window, audio, camera, font, tiled, render, fx, spritesheet, input, ui. @todo: finish spine
2+
// - rlyeh, public domain.
3+
//
4+
// Compile with:
5+
// `make demos\01-sprite.c` (windows)
6+
// `sh MAKE.bat demos/01-sprite.c` (linux, osx)
7+
8+
#include "fwk.h"
9+
10+
void demo_kids(vec3 offs) {
11+
// init
12+
static texture_t kids; do_once kids = texture( "spriteSheetExample.png", TEXTURE_LINEAR );
13+
static vec3 pos[2] = {{490,362},{442,362}}, vel[2] = {0};
14+
static int row[2] = {0,3}, frame[2] = {0};
15+
static int inputs[2][4] = {{KEY_W,KEY_A,KEY_S,KEY_D},{KEY_UP,KEY_LEFT,KEY_DOWN,KEY_RIGHT}};
16+
17+
// move
18+
for( int i = 0; i < countof(pos); ++i ) {
19+
vel[i].x = input(inputs[i][3]) - input(inputs[i][1]);
20+
vel[i].y = input(inputs[i][2]) - input(inputs[i][0]);
21+
pos[i].x = fmod(pos[i].x + vel[i].x, window_width() + 128);
22+
pos[i].y = fmod(pos[i].y + vel[i].y, window_height() + 128);
23+
frame[i] += vel[i].x || vel[i].y;
24+
}
25+
26+
// render
27+
for( int i = 0; i < countof(pos); ++i ) {
28+
int col = frame[i] / 10, num_frame = row[i] * 4 + col % 4; // 4x4 tilesheet
29+
float position[3] = {pos[i].x,pos[i].y,pos[i].y}, offset[2]={0,0}, scale[2]={0.5,0.5};
30+
float spritesheet[3]={num_frame,4,4};
31+
sprite_sheet(kids,
32+
spritesheet, // num_frame in a 4x4 spritesheet
33+
position, 0, // position(x,y,depth:sort-by-Y), angle
34+
offset, scale, // offset(x,y), scale(x,y)
35+
false, WHITE, false // is_additive, tint color, resolution-independent
36+
);
37+
}
38+
}
39+
40+
void demo_hud() {
41+
// draw pixel-art hud, 16x16 ui element, scaled and positioned in resolution-independant way
42+
static texture_t inputs; do_once inputs = texture( "prompts_tilemap_34x24_16x16x1.png", TEXTURE_LINEAR );
43+
float spritesheet[3] = {17,34,24}, offset[2] = {0, - 2*absf(sin(window_time()*5))}; // sprite cell and animation
44+
float scale[2] = {3, 3}, tile_w = 16 * scale[0], tile_h = 16 * scale[1]; // scaling
45+
float position[3] = {window_width() - tile_w, window_height() - tile_h, window_height() }; // position in screen-coordinates (x,y,z-index)
46+
sprite_sheet(inputs, spritesheet, position, 0/*deg*/, offset, scale, false, WHITE, 1);
47+
}
48+
49+
int main() {
50+
// window (80% sized, MSAA x4 flag)
51+
window_create(80.0, WINDOW_MSAA4);
52+
window_title(__FILE__);
53+
54+
// tiled map
55+
tiled_t tmx = tiled(vfs_read("castle.tmx"));
56+
// tmx.parallax = true;
57+
58+
// spine model
59+
//spine_t *spn = spine("goblins.json", "goblins.atlas", 0);
60+
61+
// camera 2d
62+
camera_t cam = camera();
63+
cam.position = vec3(window_width()/2, window_height()/2, 3); // at(CX,CY) zoom(x3)
64+
camera_enable(&cam);
65+
66+
// audio (both clips & streams)
67+
audio_t clip1 = audio_clip( "coin.wav" );
68+
audio_t clip2 = audio_clip( "pew.sfxr" );
69+
audio_t stream1 = audio_stream( "larry.mid" );
70+
audio_t stream2 = audio_stream( "monkey1.mid" );
71+
audio_t BGM = stream1;
72+
audio_play(BGM, 0);
73+
74+
// font config: faces (6 max) and colors (10 max)
75+
#define FONT_CJK FONT_FACE3
76+
#define FONT_YELLOW FONT_COLOR2
77+
#define FONT_LIME FONT_COLOR3
78+
font_face(FONT_CJK, "mplus-1p-medium.ttf", 48.f, FONT_JP|FONT_2048); // CJK|FONT_2048|FONT_OVERSAMPLE_Y);
79+
font_color(FONT_YELLOW, RGB4(255,255,0,255));
80+
font_color(FONT_LIME, RGB4(128,255,0,255));
81+
82+
// fx: load all post fx files in all subdirs. enable a few filters by default
83+
fx_load("fx**.fs");
84+
fx_enable(fx_find("fxCRT2.fs"), 1);
85+
fx_enable(fx_find("fxGrain.fs"), 1);
86+
fx_enable(fx_find("fxContrast.fs"), 1);
87+
fx_enable(fx_find("fxVignette.fs"), 1);
88+
89+
// demo loop
90+
while (window_swap() && !input_down(KEY_ESC)) {
91+
92+
// handle input
93+
if( input_down(KEY_F5) ) window_reload();
94+
if( input_down(KEY_F11) ) window_fullscreen( !window_has_fullscreen() );
95+
96+
// camera panning (x,y) & zooming (z)
97+
if( !ui_hover() && !ui_active() ) {
98+
if( input(MOUSE_L) ) cam.position.x += input_diff(MOUSE_X);
99+
if( input(MOUSE_L) ) cam.position.y += input_diff(MOUSE_Y);
100+
cam.position.z += input_diff(MOUSE_W) * 0.1;
101+
}
102+
103+
// apply post-fxs from here
104+
fx_begin();
105+
106+
profile("Rendering") {
107+
vec3 center = add3(cam.position,vec3(-window_width()/1,-window_height()/2,0));
108+
// render tiled map
109+
tiled_render(tmx, center);
110+
//
111+
demo_kids(vec3(0,0,1));
112+
demo_hud();
113+
// render spine model
114+
// spine_animate(spn, !window_has_pause() * window_delta());
115+
// spine_render(spn, vec3(cam.position.x, cam.position.y, 1), true );
116+
// sprite_flush();
117+
}
118+
119+
// subtitle sample
120+
font_print(
121+
FONT_BOTTOM FONT_CENTER
122+
FONT_CJK FONT_H1
123+
FONT_YELLOW "私はガラスを食べられます。" FONT_LIME "それは私を傷つけません。\n"
124+
);
125+
126+
// post-fxs end here
127+
fx_end();
128+
129+
// ui
130+
if( ui_panel("Audio", 0)) {
131+
static float bgm = 1, sfx = 1, master = 1;
132+
if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm);
133+
if( ui_slider2("SFX", &sfx, va("%.2f", sfx))) audio_volume_clip(sfx);
134+
if( ui_slider2("Master", &master, va("%.2f", master))) audio_volume_master(master);
135+
if( ui_label2_toolbar("BGM: Leisure Suit Larry", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream1, AUDIO_SINGLE_INSTANCE);
136+
if( ui_label2_toolbar("BGM: Monkey Island", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream2, AUDIO_SINGLE_INSTANCE);
137+
if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(clip1, 0);
138+
if( ui_label2_toolbar("SFX: Pew", ICON_MD_VOLUME_UP)) audio_play(clip2, 0);
139+
ui_panel_end();
140+
}
141+
if( ui_panel("Tiled", 0)) {
142+
ui_float("Zoom in", &cam.position.z);
143+
tiled_ui(&tmx);
144+
ui_panel_end();
145+
}
146+
/*if( ui_panel("Spine", 0)) {
147+
spine_ui(spn);
148+
ui_panel_end();
149+
}*/
150+
if( ui_panel("FX", 0) ) {
151+
for( int i = 0; i < 64; ++i ) {
152+
char *name = fx_name(i); if( !name ) break;
153+
bool b = fx_enabled(i);
154+
if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1);
155+
}
156+
ui_panel_end();
157+
}
158+
}
159+
}
160+
161+
// this demo supersedes following old sources:
162+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-audio.c
163+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-font.c
164+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-spine.c
165+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-sprite.c
166+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-tiled.c
167+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-tilemap.c

2023.4/demos/01-sprite.png

1.01 MB
Loading

2023.4/demos/02-ddraw.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// ddraw demo: fps camera, renderdd, collide, math, ui, fx
2+
// - rlyeh, public domain.
3+
//
4+
// Compile with:
5+
// `make demos\02-ddraw.c` (windows)
6+
// `sh MAKE.bat demos/02-ddraw.c` (linux, osx)
7+
8+
#include "fwk.h"
9+
10+
int main() {
11+
bool do_colliders_demo = 1;
12+
bool do_debugdraw_demo = 0;
13+
14+
// 75% size, MSAAx2
15+
window_create(75.0, WINDOW_MSAA2);
16+
window_title(__FILE__);
17+
18+
// camera that points to origin
19+
camera_t cam = camera();
20+
// load skybox folder (no flags)
21+
skybox_t sky = skybox("cubemaps/stardust", 0);
22+
// load all postfx files in all subdirs
23+
fx_load("fx**.fs");
24+
25+
// main loop
26+
while( window_swap() ) {
27+
28+
// input handler
29+
if (input_down(KEY_F11) ) window_fullscreen( window_has_fullscreen()^1 );
30+
if (input_down(KEY_ESC) ) break;
31+
32+
// fps camera
33+
profile("FPS camera") {
34+
if( input(GAMEPAD_CONNECTED) ) {
35+
vec2 filtered_lpad = input_filter_deadzone(input2(GAMEPAD_LPAD), 0.15f/*do_gamepad_deadzone*/ + 1e-3 );
36+
vec2 filtered_rpad = input_filter_deadzone(input2(GAMEPAD_RPAD), 0.15f/*do_gamepad_deadzone*/ + 1e-3 );
37+
vec2 mouse = scale2(vec2(filtered_rpad.x, filtered_rpad.y), 1.0f);
38+
vec3 wasdec = scale3(vec3(filtered_lpad.x, input(GAMEPAD_LT) - input(GAMEPAD_RT), filtered_lpad.y), 1.0f);
39+
camera_move(&cam, wasdec.x,wasdec.y,wasdec.z);
40+
camera_fps(&cam, mouse.x,mouse.y);
41+
window_cursor( true );
42+
} else {
43+
bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R);
44+
if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f);
45+
vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active);
46+
vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed);
47+
camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z);
48+
camera_fps(&cam, mouse.x,mouse.y);
49+
window_cursor( !active );
50+
}
51+
}
52+
53+
fx_begin();
54+
55+
// draw skybox
56+
skybox_render(&sky, cam.proj, cam.view);
57+
58+
// world
59+
ddraw_grid(0);
60+
61+
// boids
62+
static swarm_t sw;
63+
profile("boids") {
64+
do_once sw = swarm();
65+
do_once array_push(sw.steering_targets, vec3(0,0,0));
66+
do_once for(int i = 0; i < 100; ++i)
67+
array_push(sw.boids, boid(scale3(rnd3(),10), rnd3())); // pos,vel
68+
69+
// move
70+
sw.steering_targets[0] = cam.position;
71+
swarm_update(&sw, window_delta());
72+
73+
// draw
74+
for (int j = 0, end = array_count(sw.boids); j < end; ++j) {
75+
vec3 dir = norm3(sub3(sw.boids[j].position, sw.boids[j].prev_position));
76+
ddraw_boid(sw.boids[j].position, dir);
77+
}
78+
}
79+
80+
// showcase many debugdraw shapes
81+
if( do_debugdraw_demo ) {
82+
ddraw_demo();
83+
}
84+
85+
// showcase many colliding tests
86+
if( do_colliders_demo ) {
87+
collide_demo();
88+
}
89+
90+
fx_end();
91+
92+
// ui
93+
if( ui_panel("App", 0) ) {
94+
ui_bool("Collide demo", &do_colliders_demo);
95+
ui_bool("DebugDraw demo", &do_debugdraw_demo);
96+
ui_panel_end();
97+
}
98+
if( ui_panel("Swarm", 0) ) {
99+
ui_swarm(&sw);
100+
ui_panel_end();
101+
}
102+
if( ui_panel("Camera", 0)) {
103+
if( ui_float("Speed", &cam.speed) ) {}
104+
if( ui_float3("Position", cam.position.v3) ) {}
105+
ui_panel_end();
106+
}
107+
if( ui_panel("FX", 0) ) {
108+
for( int i = 0; i < 64; ++i ) {
109+
char *name = fx_name(i); if( !name ) break;
110+
bool b = fx_enabled(i);
111+
if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1);
112+
}
113+
ui_panel_end();
114+
}
115+
}
116+
}
117+
118+
// this demo supersedes following old sources:
119+
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-collide.c

2023.4/demos/02-ddraw.png

313 KB
Loading

0 commit comments

Comments
 (0)