Skip to content

Commit

Permalink
2023.7
Browse files Browse the repository at this point in the history
Maintenance release:

new: bt demo
new: mesh_bounds()
new: tty_detach()
new: forked milestone in https://github.com/r-lyeh/FWK.2022
chg: reduced project size
chg: reduced project cook time
chg: html5: instantiate web server only if content is not being served
chg: added tools/editor/plugins/ stub folder
chg: upgrade teal + gamecontrollerdb + tlse
chg: updated docs
fix: fixed issue when mounting empty zipfiles (likely to happen in computers with many cpu cores) (thanks @zpl-zak!)
fix: flipped shadertoys when used as texture (fwk_render)
fix: html5: added pthreads support (@zpl-zak)
fix: html5: allowed coi requests in localhost served contents (@zpl-zak)
fix: fixed leak (3rd_https)
fix: fixed ui_notify crash when no cooked fonts were available
brk: renamed WITH_ > ENABLE_ directives
  • Loading branch information
r-lyeh committed Dec 6, 2024
1 parent a363433 commit 0e0d604
Show file tree
Hide file tree
Showing 1,534 changed files with 1,790,422 additions and 0 deletions.
707 changes: 707 additions & 0 deletions 2023.7/MAKE.bat

Large diffs are not rendered by default.

337 changes: 337 additions & 0 deletions 2023.7/README.md

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions 2023.7/demos/00-loop.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "fwk.h" // Minimal C sample

int main() {
window_create(75.0, 0); // 75% size, no extra flags

while( window_swap() && !input(KEY_ESC) ) { // game loop
puts("hello FWK from C!");
}
}
31 changes: 31 additions & 0 deletions 2023.7/demos/00-script.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "fwk.h"

#define SCRIPT(...) #__VA_ARGS__

#if 0 // teal
script_run("local tl=require(\"tl\")\ntl.loader()");
script_run("addsub = require(\"s2\"); print (addsub.add(10, 20))");
s2.tl:
local function add(a: number, b: number): number
return a + b
end
local s = add(1,2)
print(s)
#endif

int main() {
script_init();

script_run(SCRIPT(
window_create(75.0,0);
while window_swap() do
ddraw_grid(10);
if ui_panel("Hello from Lua!", 0) then
ui_panel_end();
end;
end;
));

// script test (lua)
script_run( "-- Bye.lua\nio.write(\"script test: Bye world!, from \", _VERSION, \"\\n\")" );
}
167 changes: 167 additions & 0 deletions 2023.7/demos/01-demo2d.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// 2d demo: window, audio, camera, font, tiled, render, fx, spritesheet, input, ui. @todo: spine
// - rlyeh, public domain.
//
// Compile with:
// `make demos\01-demo2d.c` (windows)
// `sh MAKE.bat demos/01-demo2d.c` (linux, osx)

#include "fwk.h"

void demo_kids(vec3 offs) {
// init
static texture_t kids; do_once kids = texture( "spriteSheetExample.png", TEXTURE_LINEAR );
static vec3 pos[2] = {{490,362},{442,362}}, vel[2] = {0};
static int row[2] = {0,3}, frame[2] = {0};
static int inputs[2][4] = {{KEY_W,KEY_A,KEY_S,KEY_D},{KEY_UP,KEY_LEFT,KEY_DOWN,KEY_RIGHT}};

// move
for( int i = 0; i < countof(pos); ++i ) {
vel[i].x = input(inputs[i][3]) - input(inputs[i][1]);
vel[i].y = input(inputs[i][2]) - input(inputs[i][0]);
pos[i].x = fmod(pos[i].x + vel[i].x, window_width() + 128);
pos[i].y = fmod(pos[i].y + vel[i].y, window_height() + 128);
frame[i] += vel[i].x || vel[i].y;
}

// render
for( int i = 0; i < countof(pos); ++i ) {
int col = frame[i] / 10, num_frame = row[i] * 4 + col % 4; // 4x4 tilesheet
float position[3] = {pos[i].x,pos[i].y,pos[i].y}, offset[2]={0,0}, scale[2]={0.5,0.5};
float spritesheet[3]={num_frame,4,4};
sprite_sheet(kids,
spritesheet, // num_frame in a 4x4 spritesheet
position, 0, // position(x,y,depth:sort-by-Y), angle
offset, scale, // offset(x,y), scale(x,y)
false, WHITE, false // is_additive, tint color, resolution-independent
);
}
}

void demo_hud() {
// draw pixel-art hud, 16x16 ui element, scaled and positioned in resolution-independant way
static texture_t inputs; do_once inputs = texture( "prompts_tilemap_34x24_16x16x1.png", TEXTURE_LINEAR );
float spritesheet[3] = {17,34,24}, offset[2] = {0, - 2*absf(sin(window_time()*5))}; // sprite cell and animation
float scale[2] = {3, 3}, tile_w = 16 * scale[0], tile_h = 16 * scale[1]; // scaling
float position[3] = {window_width() - tile_w, window_height() - tile_h, window_height() }; // position in screen-coordinates (x,y,z-index)
sprite_sheet(inputs, spritesheet, position, 0/*deg*/, offset, scale, false, WHITE, 1);
}

int main() {
// window (80% sized, MSAA x4 flag)
window_create(80.0, WINDOW_MSAA4);
window_title(__FILE__);

// tiled map
tiled_t tmx = tiled(vfs_read("castle.tmx"));
// tmx.parallax = true;

// spine model
//spine_t *spn = spine("goblins.json", "goblins.atlas", 0);

// camera 2d
camera_t cam = camera();
cam.position = vec3(window_width()/2, window_height()/2, 3); // at(CX,CY) zoom(x3)
camera_enable(&cam);

// audio (both clips & streams)
audio_t clip1 = audio_clip( "coin.wav" );
audio_t clip2 = audio_clip( "pew.sfxr" );
audio_t stream1 = audio_stream( "larry.mid" );
audio_t stream2 = audio_stream( "monkey1.mid" );
audio_t BGM = stream1;
audio_play(BGM, 0);

// font config: faces (6 max) and colors (10 max)
#define FONT_CJK FONT_FACE3
#define FONT_YELLOW FONT_COLOR2
#define FONT_LIME FONT_COLOR3
font_face(FONT_CJK, "mplus-1p-medium.ttf", 48.f, FONT_JP|FONT_2048); // CJK|FONT_2048|FONT_OVERSAMPLE_Y);
font_color(FONT_YELLOW, RGB4(255,255,0,255));
font_color(FONT_LIME, RGB4(128,255,0,255));

// fx: load all post fx files in all subdirs. enable a few filters by default
fx_load("fx**.fs");
fx_enable(fx_find("fxCRT2.fs"), 1);
fx_enable(fx_find("fxGrain.fs"), 1);
fx_enable(fx_find("fxContrast.fs"), 1);
fx_enable(fx_find("fxVignette.fs"), 1);

// demo loop
while (window_swap() && !input_down(KEY_ESC)) {

// handle input
if( input_down(KEY_F5) ) window_reload();
if( input_down(KEY_F11) ) window_fullscreen( !window_has_fullscreen() );

// camera panning (x,y) & zooming (z)
if( !ui_hover() && !ui_active() ) {
if( input(MOUSE_L) ) cam.position.x += input_diff(MOUSE_X);
if( input(MOUSE_L) ) cam.position.y += input_diff(MOUSE_Y);
cam.position.z += input_diff(MOUSE_W) * 0.1;
}

// apply post-fxs from here
fx_begin();

profile("Rendering") {
vec3 center = add3(cam.position,vec3(-window_width()/1,-window_height()/2,0));
// render tiled map
tiled_render(tmx, center);
//
demo_kids(vec3(0,0,1));
demo_hud();
// render spine model
// spine_animate(spn, !window_has_pause() * window_delta());
// spine_render(spn, vec3(cam.position.x, cam.position.y, 1), true );
// sprite_flush();
}

// subtitle sample
font_print(
FONT_BOTTOM FONT_CENTER
FONT_CJK FONT_H1
FONT_YELLOW "私はガラスを食べられます。" FONT_LIME "それは私を傷つけません。\n"
);

// post-fxs end here
fx_end();

// ui
if( ui_panel("Audio", 0)) {
static float bgm = 1, sfx = 1, master = 1;
if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm);
if( ui_slider2("SFX", &sfx, va("%.2f", sfx))) audio_volume_clip(sfx);
if( ui_slider2("Master", &master, va("%.2f", master))) audio_volume_master(master);
if( ui_label2_toolbar("BGM: Leisure Suit Larry", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream1, AUDIO_SINGLE_INSTANCE);
if( ui_label2_toolbar("BGM: Monkey Island", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream2, AUDIO_SINGLE_INSTANCE);
if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(clip1, 0);
if( ui_label2_toolbar("SFX: Pew", ICON_MD_VOLUME_UP)) audio_play(clip2, 0);
ui_panel_end();
}
if( ui_panel("Tiled", 0)) {
ui_float("Zoom in", &cam.position.z);
tiled_ui(&tmx);
ui_panel_end();
}
/*if( ui_panel("Spine", 0)) {
spine_ui(spn);
ui_panel_end();
}*/
if( ui_panel("FX", 0) ) {
for( int i = 0; i < 64; ++i ) {
char *name = fx_name(i); if( !name ) break;
bool b = fx_enabled(i);
if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1);
}
ui_panel_end();
}
}
}

// this demo supersedes following old sources:
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-audio.c
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-font.c
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-spine.c
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-sprite.c
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-tiled.c
// https://github.com/r-lyeh/FWK/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-tilemap.c
57 changes: 57 additions & 0 deletions 2023.7/demos/01-easing.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "fwk.h"

struct {
float (*ease)(float);
const char *name;
} easings[] = {
{ease_linear, "ease_linear"},
{ease_out_sine, "ease_out_sine"},
{ease_out_quad, "ease_out_quad"},
{ease_out_cubic, "ease_out_cubic"},
{ease_out_quart, "ease_out_quart"},
{ease_out_quint, "ease_out_quint"},
{ease_out_expo, "ease_out_expo"},
{ease_out_circ, "ease_out_circ"},
{ease_out_back, "ease_out_back"},
{ease_out_elastic, "ease_out_elastic"},
{ease_out_bounce, "ease_out_bounce"},
{ease_in_sine, "ease_in_sine"},
{ease_in_quad, "ease_in_quad"},
{ease_in_cubic, "ease_in_cubic"},
{ease_in_quart, "ease_in_quart"},
{ease_in_quint, "ease_in_quint"},
{ease_in_expo, "ease_in_expo"},
{ease_in_circ, "ease_in_circ"},
{ease_in_back, "ease_in_back"},
{ease_in_elastic, "ease_in_elastic"},
{ease_in_bounce, "ease_in_bounce"},
{ease_inout_sine, "ease_inout_sine"},
{ease_inout_quad, "ease_inout_quad"},
{ease_inout_cubic, "ease_inout_cubic"},
{ease_inout_quart, "ease_inout_quart"},
{ease_inout_quint, "ease_inout_quint"},
{ease_inout_expo, "ease_inout_expo"},
{ease_inout_circ, "ease_inout_circ"},
{ease_inout_back, "ease_inout_back"},
{ease_inout_elastic, "ease_inout_elastic"},
{ease_inout_bounce, "ease_inout_bounce"},
{ease_inout_perlin, "ease_inout_perlin"},
};

int main() {
window_create(0.75, WINDOW_SQUARE);
while(window_swap()) {
static double timer = 0; timer = fmod(timer+window_delta(), 2); // loops every 2s

static int open = 1;
if( ui_window("ease", &open) ) {
float linear_delta = timer / 2.f; // delta is [0..1]
for( int i = 0; i < countof(easings); ++i) {
float nonlinear_delta = easings[i].ease(linear_delta);
// visualize
ui_slider( easings[i].name, &nonlinear_delta );
}
ui_window_end();
}
}
}
111 changes: 111 additions & 0 deletions 2023.7/demos/01-font.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include "fwk.h"

int main() {
window_create(75.0, WINDOW_MSAA8);

// style: our aliases
#define FONT_REGULAR FONT_FACE1
#define FONT_ITALIC FONT_FACE2
#define FONT_BOLD FONT_FACE3
#define FONT_JAPANESE FONT_FACE4
#define FONT_MONOSPACE FONT_FACE5

#define FONT_GRAY FONT_COLOR2
#define FONT_ORANGE FONT_COLOR3
#define FONT_LIME FONT_COLOR4
#define FONT_GREEN FONT_COLOR5
#define FONT_CYAN FONT_COLOR6

#define FONT_LARGEST FONT_H1
#define FONT_LARGE FONT_H2
#define FONT_MEDIUM FONT_H3
#define FONT_NORMAL FONT_H4
#define FONT_SMALL FONT_H5
#define FONT_TINY FONT_H6

// style: atlas size, unicode ranges and font faces (up to 6 faces)
font_face(FONT_REGULAR, "Carlito-Regular.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048);
font_face(FONT_ITALIC, "Carlito-Italic.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048);
font_face(FONT_BOLD, "Carlito-Bold.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048);
font_face(FONT_JAPANESE, "mplus-1p-medium.ttf", 48.f, FONT_JP|FONT_2048); // CJK|FONT_2048|FONT_OVERSAMPLE_Y);
font_face(FONT_MONOSPACE, "Inconsolata-Regular.ttf", 24.f, FONT_EU|FONT_512);

// style: colors (up to 10 colors)
font_color(FONT_GRAY, RGB4(100,100,100,255));
font_color(FONT_ORANGE, RGB4(255,192,0,255));
font_color(FONT_LIME, RGB4(192,255,0,255));
font_color(FONT_GREEN, RGB4(0,255,192,255));
font_color(FONT_CYAN, RGB4(0,192,255,255));

// prepare color highlighting for following code snippet
const char *source =
FONT_MONOSPACE FONT_LARGEST
"int main(int argc, char **argv) {\n"
" for( int i = 0; i < 10; ++i)\n"
" puts(\"hello world\");\n"
" return 0;\n"
"}\n";
const void *colors = font_colorize(source, "void,int,char", "if,else,for,do,while,return,switch,case,break,default,");

// demo loop
while( window_swap() && !input(KEY_ESC) ) {
ddraw_grid(0);

// initial spacing
font_goto(0, 50);

// print a code snippet with syntax highlighting
font_highlight(source, colors);

// print a few strings with markup codes
font_print(
FONT_REGULAR
FONT_LARGEST FONT_GRAY "The quick "
FONT_LARGE FONT_LIME "brown "
FONT_MEDIUM FONT_GRAY "fox "
FONT_NORMAL "jumps over "
FONT_SMALL "the lazy "
FONT_TINY "dog.\n");

font_print(
FONT_REGULAR FONT_LARGE FONT_CYAN
"Now is the time for all " FONT_ITALIC "good men " FONT_REGULAR "to come to the aid of " FONT_BOLD "the party.\n");

font_print(
FONT_ITALIC FONT_LARGE FONT_GREEN
"Ég get etið gler án þess að meiða mig!\n");

font_print(
FONT_BOLD FONT_LARGE FONT_ORANGE
"Эх, чужак! Общий съём цен шляп (юфть)—вдрызг!.\n");

font_print(
FONT_JAPANESE
"私はガラスを食べられます。それは私を傷つけません。\n");

font_print( "This text ");
font_print( "should display concatenated, ");
font_print( "as there are no linefeeds.\n" );

// i18n: pangrams.txt file, line browser
static int counter = 0;
static array(char*) lines; do_once lines = strsplit( vfs_read("pangrams.txt"), "\r\n" );
counter += input_down(KEY_RIGHT)-input_down(KEY_LEFT);
counter += counter < 0 ? array_count(lines) : 0;
font_print( va("<< %s >>\n", lines[counter % array_count(lines)]) );

// this does not work yet. you cant chain alignments yet...
//font_print(FONT_TOP "Top" FONT_MIDDLE "Middle" FONT_BASELINE "Baseline" FONT_BOTTOM "Bottom\n");
//font_print(FONT_LEFT "Left" FONT_CENTER "Center" FONT_RIGHT "Right\n");

// ... alignment must be the first tag in a string for now. this is a temporary hack.
font_print(FONT_LEFT "left");
font_print(FONT_CENTER "center");
font_print(FONT_RIGHT "right");

font_print(FONT_TOP FONT_CENTER "top\n");
font_print(FONT_MIDDLE FONT_RIGHT "middle\n");
font_print(FONT_BASELINE FONT_RIGHT "baseline\n");
font_print(FONT_BOTTOM FONT_CENTER "bottom\n");
}
}
Loading

0 comments on commit 0e0d604

Please sign in to comment.