Compare commits

..

5 Commits

@ -15,3 +15,25 @@ You must clone with git lfs is, and download git lfs files in this repository. I
Open `art.blend`, go to the scripting tab and hit the play button run the script and export all the 3d assets. Then, make sure that when you build, you also build and run the codegen so that said assets and other files are copied and imported. For debug builds on windows, that's `call build_desktop_debug.bat codegen`, the codegen argument to the build script causing it to run codegen Open `art.blend`, go to the scripting tab and hit the play button run the script and export all the 3d assets. Then, make sure that when you build, you also build and run the codegen so that said assets and other files are copied and imported. For debug builds on windows, that's `call build_desktop_debug.bat codegen`, the codegen argument to the build script causing it to run codegen
To enable codegen error messages, change @echo off to @echo on in run_codegen.bat To enable codegen error messages, change @echo off to @echo on in run_codegen.bat
# Debugging in the web
To get this working, you're going to need to follow flooh's answer linked [here](https://groups.google.com/g/emscripten-discuss/c/DEmpyGoq6kE/m/Bx44ZmfmAAAJ), and copy pasted for redundancy here:
```
It should definitely work on Vanilla Chrome, but setting everything up can be a bit finicky:
- install the Debugging extension: https://chrome.google.com/webstore/detail/cc%20%20-devtools-support-dwa/pdcpmagijalfljmkmjngeonclgbbannb
- in the Dev Tools settings, search for 'WebAssembly Debugging' and check that box
- compile your code with '-O0 -g' (no optimization, and debug info enabled'
- IMPORTANT: in the Chrome debugger, there's a 'Filesystem' tab on the left side which is very easy to miss. Here you need to navigate to your project directory and allow Chrome to access that area of your filesystem.
(I think/hope these are all steps)
When you load your application you should see something like this on the Dev Tools console:
[C/C++ DevTools Support (DWARF)] Loading debug symbols for http://localhost:8080/cube-sapp.wasm...
[C/C++ DevTools Support (DWARF)] Loaded debug symbols for http://localhost:8080/cube-sapp.wasm, found 91 source file(s)
...and if everything works it should look roughly like this in the debugger:
```

@ -16,17 +16,21 @@
{enum: Raphael, dialog: "What a psycho...", to: Daniel} {enum: Raphael, dialog: "What a psycho...", to: Daniel}
{can_hear: [Daniel, Raphael, Passerby]} {can_hear: [Daniel, Raphael, Passerby]}
{enum: Passerby, dialog: "Yo", to: Raphael} {enum: Passerby, dialog: "Yo?", to: Daniel}
{enum: Raphael, dialog: "What's up", to: Passerby} {enum: Daniel, dialog: "Are you askin' a question", to: Passerby}
{enum: Passerby, dialog: "What do you think of farmers", to: Raphael} {enum: Passerby, dialog: "I guess so? What do you think of farmers?", to: Daniel}
{enum: Raphael, dialog: "What?", to: Passerby} {enum: Daniel, dialog: "I don't tolerate questions. Get out of my sight before I make you!", to: Passerby, action: ACT_aim_shotgun, action_argument: "Passerby"}
{enum: Daniel, dialog: "Let me 'say somthin here. Farmers are the backbone of this town, so you'd best give them some respect", to: Passerby} {enum: Raphael, dialog: "What's going on here?", to: Daniel}
{enum: Raphael, dialog: "I mean, scientists really are what's most important", to: Daniel} {enum: Daniel, dialog: "THIS DAMNED FOOL DOESN'T UNDERSTAND RESPECT", to: Raphael}
{enum: Daniel, dialog: "First of all, what the hell is a scientist? Second of all, whoever they are, if they can't eat they're worthless!", to: Raphael} {enum: Raphael, dialog: "Easy man, easy.", to: Daniel}
{enum: Raphael, dialog: "FIne fine whatever, no need to get heated...", to: Daniel} {enum: Daniel, dialog: "I WON'T TOLERATE IT", to: Raphael}
{enum: Daniel, dialog: "Anyways, sorry about that. What's your name?", to: Passerby} {enum: Passerby, dialog: "Hey man woah, just put down the gun", to: Daniel}
{enum: Passerby, dialog: "Nevermind I'll just take my leave, later.", to: Daniel} {enum: Daniel, dialog: "YOU BETTER MAKE ME!", to: Passerby}
{enum: Passerby, dialog: "Why do you have the gun anyways?", to: Daniel}
{enum: Daniel, dialog: "ANOTHER QUESTION??? YOU HAD THIS COMING TO YOU!", to: Passerby, action: ACT_fire_shotgun}
{enum: Raphael, dialog: "Oh God! What have you done??", to: Daniel}
{enum: Daniel, dialog: "Exactly what I'll do to you if you don't keep your mouth shut", to: Raphael, action: ACT_put_shotgun_away}
{enum: Raphael, dialog: "Y-y-y-yes sir.", to: Daniel}
/* /*
{can_hear: [WellDweller, Farmer, ManInBlack]}, {can_hear: [WellDweller, Farmer, ManInBlack]},

@ -1,7 +1,7 @@
call run_codegen.bat || goto :error call run_codegen.bat || goto :error
copy marketing_page\favicon.ico %OUTPUT_FOLDER%\favicon.ico copy marketing_page\favicon.ico %OUTPUT_FOLDER%\favicon.ico
copy main.c %OUTPUT_FOLDER%\main.c || goto :error @REM copy main.c %OUTPUT_FOLDER%\main.c || goto :error
@echo on @echo on
emcc ^ emcc ^

@ -4,7 +4,7 @@ rmdir /S /q build_web
mkdir build_web mkdir build_web
@REM set FLAGS=-fsanitize=undefined -fsanitize=address @REM set FLAGS=-fsanitize=undefined -fsanitize=address
set FLAGS=-O0 --source-map-base http://localhost:8000/ -g3 -gdwarf -DDEVTOOLS set FLAGS=-O0 -g -DDEVTOOLS
set OUTPUT_FOLDER=build_web set OUTPUT_FOLDER=build_web

@ -5,7 +5,8 @@
// @TODO allow AI to prefix out of character statemetns with [ooc], this is a well khnown thing on role playing forums so gpt would pick up on it. // @TODO allow AI to prefix out of character statemetns with [ooc], this is a well khnown thing on role playing forums so gpt would pick up on it.
const char *global_prompt = const char *global_prompt =
"You are a character in a simple western video game. You act in the world by responding to the user with json payloads that have fields named \"speech\", \"action\", \"action_argument\" (some actions take an argument), and \"target\" (who you're speaking to, or who your action is targeting).\n" "You are a character in a simple western video game. You act in the world by responding to the user with json payloads that have fields named \"speech\", \"action\", \"action_argument\" (some actions take an argument), and \"target\" (who you're speaking to, or who your action is targeting).\n"
"You speak only when you have something to say, or are responding to somebody, and use short, concise, punchy language. If you're just overhearing what other people are saying, you only say something when absolutely compelled to do so" "You speak only when you have something to say, or are responding to somebody, and use short, concise, punchy language. If you're just overhearing what other people are saying, you only say something when absolutely compelled to do so.\n"
"But if somebody talks directly to you, you usually say someting."
; ;
const char *top_of_header = "" const char *top_of_header = ""

@ -1,7 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#define DESKTOP #define DESKTOP
#include "better_assert.h" #include "utility.h"
#include "buff.h" #include "buff.h"
@ -23,8 +23,6 @@
#pragma warning(pop) #pragma warning(pop)
#define Log(...) { printf("Codegen: "); printf(__VA_ARGS__); }
void dump(MD_Node* from) { void dump(MD_Node* from) {
printf("/ %.*s\n", MD_S8VArg(from->string)); printf("/ %.*s\n", MD_S8VArg(from->string));
int d = 0; int d = 0;

108
main.c

@ -28,6 +28,8 @@
#define SOKOL_GLES2 #define SOKOL_GLES2
#endif #endif
#include "utility.h"
#ifdef WINDOWS #ifdef WINDOWS
@ -132,7 +134,14 @@ void *web_arena_push(WebArena *arena, size_t amount)
} }
void *to_return = arena->data + arena->pos; void *to_return = arena->data + arena->pos;
arena->pos += amount; arena->pos += amount;
assert(arena->pos < arena->cap);
bool arena_ok = arena->pos < arena->cap;
if(!arena_ok)
{
Log("Arena size: %lu\n", arena->cap);
Log("Arena pos: %lu\n", arena->pos);
}
assert(arena_ok);
return to_return; return to_return;
} }
@ -2728,13 +2737,13 @@ void create_screenspace_gfx_state()
.label = "outline-pass", .label = "outline-pass",
}); });
desc.sample_count = 0; desc.sample_count = 1;
desc.label = "threedee-pass-render-target"; desc.label = "threedee-pass-render-target";
state.threedee_pass_image = sg_make_image(&desc); state.threedee_pass_image = sg_make_image(&desc);
desc.label = "threedee-pass-depth-render-target"; desc.label = "threedee-pass-depth-render-target";
desc.pixel_format = SG_PIXELFORMAT_DEPTH_STENCIL; desc.pixel_format = SG_PIXELFORMAT_DEPTH;
state.threedee_pass_depth_image = sg_make_image(&desc); state.threedee_pass_depth_image = sg_make_image(&desc);
state.threedee_pass = sg_make_pass(&(sg_pass_desc){ state.threedee_pass = sg_make_pass(&(sg_pass_desc){
@ -3291,21 +3300,19 @@ void init(void)
assert(desc); assert(desc);
shd = sg_make_shader(desc); shd = sg_make_shader(desc);
state.threedee_pip = sg_make_pipeline(&(sg_pipeline_desc) state.threedee_pip = sg_make_pipeline(&(sg_pipeline_desc){
{
.shader = shd, .shader = shd,
.depth = { .layout = {.attrs = {
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true
},
.layout = {
.attrs =
{
[ATTR_threedee_vs_pos_in].format = SG_VERTEXFORMAT_FLOAT3, [ATTR_threedee_vs_pos_in].format = SG_VERTEXFORMAT_FLOAT3,
[ATTR_threedee_vs_uv_in].format = SG_VERTEXFORMAT_FLOAT2, [ATTR_threedee_vs_uv_in].format = SG_VERTEXFORMAT_FLOAT2,
} }},
.depth = {
.pixel_format = SG_PIXELFORMAT_DEPTH,
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
}, },
.colors[0].blend = (sg_blend_state) { // allow transparency .colors[0].blend = (sg_blend_state){
// allow transparency
.enabled = true, .enabled = true,
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA, .src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, .dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
@ -3325,6 +3332,7 @@ void init(void)
{ {
.shader = shd, .shader = shd,
.depth = { .depth = {
.pixel_format = SG_PIXELFORMAT_DEPTH,
.compare = SG_COMPAREFUNC_LESS_EQUAL, .compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true .write_enabled = true
}, },
@ -5588,13 +5596,14 @@ void frame(void)
// draw the 3d render // draw the 3d render
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y), screen_size()), IMG(state.threedee_pass_image), WHITE, .layer = LAYER_WORLD, .custom_pipeline = state.twodee_colorcorrect_pip }); draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y), screen_size()), IMG(state.threedee_pass_image), WHITE, .layer = LAYER_WORLD, .custom_pipeline = state.twodee_colorcorrect_pip });
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y), screen_size()), IMG(state.outline_pass_image), WHITE, .layer = LAYER_UI_FG, .custom_pipeline = state.twodee_outline_pip, .layer = LAYER_UI}); draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y), screen_size()), IMG(state.outline_pass_image), WHITE, .custom_pipeline = state.twodee_outline_pip, .layer = LAYER_UI});
// 2d drawing TODO move this to when the drawing is flushed. // 2d drawing TODO move this to when the drawing is flushed.
sg_begin_default_pass(&state.clear_depth_buffer_pass_action, sapp_width(), sapp_height()); sg_begin_default_pass(&state.clear_depth_buffer_pass_action, sapp_width(), sapp_height());
sg_apply_pipeline(state.twodee_pip); sg_apply_pipeline(state.twodee_pip);
// @Place(text input drawing) // @Place(text input drawing)
#ifdef DESKTOP
draw_quad((DrawParams){quad_at(V2(0,screen_size().y), screen_size()), IMG(image_white_square), blendalpha(BLACK, text_input_fade*0.3f), .layer = LAYER_UI_FG}); draw_quad((DrawParams){quad_at(V2(0,screen_size().y), screen_size()), IMG(image_white_square), blendalpha(BLACK, text_input_fade*0.3f), .layer = LAYER_UI_FG});
Vec2 edge_of_text = MulV2F(screen_size(), 0.5f); Vec2 edge_of_text = MulV2F(screen_size(), 0.5f);
if(text_input_buffer_length > 0) if(text_input_buffer_length > 0)
@ -5604,6 +5613,7 @@ void frame(void)
} }
Vec2 cursor_center = V2(edge_of_text.x,screen_size().y/2.0f); Vec2 cursor_center = V2(edge_of_text.x,screen_size().y/2.0f);
draw_quad((DrawParams){quad_centered(cursor_center, V2(3.0f, 80.0f)), IMG(image_white_square), blendalpha(WHITE, text_input_fade * (sinf((float)elapsed_time*8.0f)/2.0f + 0.5f)), .layer = LAYER_UI_FG}); draw_quad((DrawParams){quad_centered(cursor_center, V2(3.0f, 80.0f)), IMG(image_white_square), blendalpha(WHITE, text_input_fade * (sinf((float)elapsed_time*8.0f)/2.0f + 0.5f)), .layer = LAYER_UI_FG});
#endif
// Draw Tilemap draw tilemap tilemap drawing // Draw Tilemap draw tilemap tilemap drawing
#if 0 #if 0
@ -6407,6 +6417,7 @@ ISANERROR("Don't know how to do this stuff on this platform.")
it->generation = gen; it->generation = gen;
} }
} }
ENTITIES_ITER(gs.entities) ENTITIES_ITER(gs.entities)
{ {
if (it->perceptions_dirty && !npc_does_dialog(it)) if (it->perceptions_dirty && !npc_does_dialog(it))
@ -6445,7 +6456,6 @@ ISANERROR("Don't know how to do this stuff on this platform.")
#endif #endif
#ifdef DESKTOP #ifdef DESKTOP
// desktop http request, no more mocking
MD_ArenaTemp scratch = MD_GetScratch(0, 0); MD_ArenaTemp scratch = MD_GetScratch(0, 0);
MD_String8 ai_response = {0}; MD_String8 ai_response = {0};
@ -6475,20 +6485,12 @@ ISANERROR("Don't know how to do this stuff on this platform.")
char *target = characters[it->memories_last->context.author_npc_kind].name; char *target = characters[it->memories_last->context.author_npc_kind].name;
target = characters[NPC_Player].name; target = characters[NPC_Player].name;
ai_response = FmtWithLint(frame_arena, "{\"target\": \"%s\", \"action\": \"%s\", \"action_argument\": \"The Player\", \"speech\": \"%s\"}", target, action, next_dialog); ai_response = FmtWithLint(frame_arena, "{\"target\": \"%s\", \"action\": \"%s\", \"action_argument\": \"The Player\", \"speech\": \"%s\"}", target, action, next_dialog);
#ifdef DESKTOP
it->times_talked_to += 1; it->times_talked_to += 1;
#endif
} }
else else
{ {
ai_response = MD_S8Lit("{\"target\": \"nobody\", \"action\": \"none\", \"speech\": \"\"}"); ai_response = MD_S8Lit("{\"target\": \"nobody\", \"action\": \"none\", \"speech\": \"\"}");
} }
}
else
{
MD_String8 post_request_body = FmtWithLint(scratch.arena, "|%.*s", MD_S8VArg(prompt_str));
it->gen_request_id = make_generation_request(post_request_body);
}
// something to mock // something to mock
if (ai_response.size > 0) if (ai_response.size > 0)
@ -6501,8 +6503,6 @@ ISANERROR("Don't know how to do this stuff on this platform.")
error_message = parse_chatgpt_response(scratch.arena, it, ai_response, &a); error_message = parse_chatgpt_response(scratch.arena, it, ai_response, &a);
} }
if (mocking_the_ai_response)
{
assert(succeeded); assert(succeeded);
assert(error_message.size == 0); assert(error_message.size == 0);
@ -6510,27 +6510,17 @@ ISANERROR("Don't know how to do this stuff on this platform.")
assert(valid_str.size == 0); assert(valid_str.size == 0);
perform_action(&gs, it, a); perform_action(&gs, it, a);
} }
else
{
if(succeeded)
{
if (error_message.size == 0)
{
perform_action(&gs, it, a);
} }
else else
{ {
Log("There was an error with the AI: %.*s", MD_S8VArg(error_message)); MD_String8 post_request_body = FmtWithLint(scratch.arena, "|%.*s", MD_S8VArg(prompt_str));
append_to_errors(it, error_message); it->gen_request_id = make_generation_request(post_request_body);
}
}
}
} }
MD_ReleaseScratch(scratch); MD_ReleaseScratch(scratch);
#undef SAY #undef SAY
#endif } #endif // desktop endif
} }
} }
else else
@ -6606,25 +6596,25 @@ ISANERROR("Don't know how to do this stuff on this platform.")
float speed = 0.0f; float speed = 0.0f;
{ {
if(gs.player->killed) gs.player->state = CHARACTER_KILLED; if(gs.player->killed) gs.player->state = CHARACTER_KILLED;
if(gs.player->state == CHARACTER_WALKING)
switch(gs.player->state)
{ {
case CHARACTER_WALKING:
player_armature.go_to_animation = MD_S8Lit("Running"); player_armature.go_to_animation = MD_S8Lit("Running");
} break;
else if(gs.player->state == CHARACTER_IDLE) case CHARACTER_IDLE:
{
player_armature.go_to_animation = MD_S8Lit("Idle"); player_armature.go_to_animation = MD_S8Lit("Idle");
} break;
else if(gs.player->state == CHARACTER_KILLED) case CHARACTER_KILLED:
{
player_armature.go_to_animation = MD_S8Lit("Die Backwards"); player_armature.go_to_animation = MD_S8Lit("Die Backwards");
player_armature.next_animation_isnt_looping = true; player_armature.next_animation_isnt_looping = true;
break;
} }
else assert(false);
if (gs.player->state == CHARACTER_WALKING) switch (gs.player->state)
{ {
case CHARACTER_WALKING:
speed = PLAYER_SPEED; speed = PLAYER_SPEED;
if (LenV2(movement) == 0.0) if (LenV2(movement) == 0.0)
{ {
@ -6633,17 +6623,13 @@ ISANERROR("Don't know how to do this stuff on this platform.")
else else
{ {
} }
} break;
else if (gs.player->state == CHARACTER_IDLE) case CHARACTER_IDLE:
{ if (LenV2(movement) > 0.01)
if (LenV2(movement) > 0.01) gs.player->state = CHARACTER_WALKING; gs.player->state = CHARACTER_WALKING;
} break;
else if (gs.player->state == CHARACTER_KILLED) case CHARACTER_KILLED:
{ break;
}
else
{
assert(false); // unknown character state? not defined how to process
} }
} // not time stopped } // not time stopped
@ -7359,7 +7345,7 @@ sapp_desc sokol_main(int argc, char* argv[])
.frame_cb = frame, .frame_cb = frame,
.cleanup_cb = cleanup, .cleanup_cb = cleanup,
.event_cb = event, .event_cb = event,
.sample_count = 4, .sample_count = 1, // bumping this back to 4 is troublesome for web, because there's a mismatch in sample counts. Perhaps we must upgrade to gles3, in doing so, we should upgrade to the newest sokol gfx.
.width = 800, .width = 800,
.height = 600, .height = 600,
//.gl_force_gles2 = true, not sure why this was here in example, look into //.gl_force_gles2 = true, not sure why this was here in example, look into

@ -2,7 +2,7 @@
#include "buff.h" #include "buff.h"
#include "HandmadeMath.h" // vector types in entity struct definition #include "HandmadeMath.h" // vector types in entity struct definition
#include "better_assert.h" #include "utility.h"
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <stdlib.h> // atoi #include <stdlib.h> // atoi
@ -13,9 +13,6 @@
#define DO_CHATGPT_PARSING #define DO_CHATGPT_PARSING
#define Log(...) { printf("%s Log %d | ", __FILE__, __LINE__); printf(__VA_ARGS__); }
// Never expected such a stupid stuff from such a great director. If there is 0 stari can give that or -200 to this movie. Its worst to see and unnecessary loss of money // Never expected such a stupid stuff from such a great director. If there is 0 stari can give that or -200 to this movie. Its worst to see and unnecessary loss of money
#define PushWithLint(arena, list, ...) { MD_S8ListPushFmt(arena, list, __VA_ARGS__); if(false) printf( __VA_ARGS__); } #define PushWithLint(arena, list, ...) { MD_S8ListPushFmt(arena, list, __VA_ARGS__); if(false) printf( __VA_ARGS__); }
@ -427,26 +424,25 @@ MD_String8 generate_chatgpt_prompt(MD_Arena *arena, GameState *gs, Entity *e, Ca
// dump a human understandable sentence description of what happened in this memory // dump a human understandable sentence description of what happened in this memory
if(it->action_taken != ACT_none) if(it->action_taken != ACT_none)
{ {
if(it->action_taken == ACT_join) switch(it->action_taken)
{ {
case ACT_none:
break;
case ACT_join:
AddFmt("%s joined %s\n", characters[it->context.author_npc_kind].name, characters[it->action_argument.targeting].name); AddFmt("%s joined %s\n", characters[it->context.author_npc_kind].name, characters[it->action_argument.targeting].name);
} break;
else if(it->action_taken == ACT_leave) case ACT_leave:
{
// Needs better handling of when you leave, because the person you were following died. Maybe entities don't die anymore?
AddFmt("%s left their party\n", characters[it->context.author_npc_kind].name); AddFmt("%s left their party\n", characters[it->context.author_npc_kind].name);
} break;
else if(it->action_taken == ACT_aim_shotgun) case ACT_aim_shotgun:
{
AddFmt("%s aimed their shotgun at %s\n", characters[it->context.author_npc_kind].name, characters[it->action_argument.targeting].name); AddFmt("%s aimed their shotgun at %s\n", characters[it->context.author_npc_kind].name, characters[it->action_argument.targeting].name);
} break;
else if(it->action_taken == ACT_fire_shotgun) case ACT_fire_shotgun:
{
AddFmt("%s fired their shotgun at %s, brutally murdering them.\n", characters[it->context.author_npc_kind].name, characters[it->action_argument.targeting].name); AddFmt("%s fired their shotgun at %s, brutally murdering them.\n", characters[it->context.author_npc_kind].name, characters[it->action_argument.targeting].name);
} break;
else case ACT_put_shotgun_away:
{ AddFmt("%s holstered their shotgun, no longer threatening anybody\n", characters[it->context.author_npc_kind].name);
assert(false); break;
} }
} }
if(it->speech.text_length > 0) if(it->speech.text_length > 0)

@ -508,6 +508,7 @@ func main() {
logResponses = os.Getenv("LOG_RESPONSES") != "" logResponses = os.Getenv("LOG_RESPONSES") != ""
doCors = os.Getenv("CORS") != "" doCors = os.Getenv("CORS") != ""
if doCors { log.Println("Doing cors"); }
c = openai.NewClient(api_key) c = openai.NewClient(api_key)
http.HandleFunc("/completion", completion) http.HandleFunc("/completion", completion)

@ -0,0 +1,12 @@
#include <stdlib.h>
void assert_less(int x, int y) {
if (x >= y) {
abort();
}
}
int main() {
assert_less(10, 20);
assert_less(30, 20);
}

@ -5,6 +5,50 @@
@ctype vec3 Vec3 @ctype vec3 Vec3
@ctype vec2 Vec2 @ctype vec2 Vec2
@block inverse_functions
// Webgl 1 doesn't have inverse() but we need it, pulled from https://github.com/glslify/glsl-inverse/blob/master/index.glsl
mat4 my_inverse(mat4 m) {
float
a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],
a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],
a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],
a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],
b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,
det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
return mat4(
a11 * b11 - a12 * b10 + a13 * b09,
a02 * b10 - a01 * b11 - a03 * b09,
a31 * b05 - a32 * b04 + a33 * b03,
a22 * b04 - a21 * b05 - a23 * b03,
a12 * b08 - a10 * b11 - a13 * b07,
a00 * b11 - a02 * b08 + a03 * b07,
a32 * b02 - a30 * b05 - a33 * b01,
a20 * b05 - a22 * b02 + a23 * b01,
a10 * b10 - a11 * b08 + a13 * b06,
a01 * b08 - a00 * b10 - a03 * b06,
a30 * b04 - a31 * b02 + a33 * b00,
a21 * b02 - a20 * b04 - a23 * b00,
a11 * b07 - a10 * b09 - a12 * b06,
a00 * b09 - a01 * b07 + a02 * b06,
a31 * b01 - a30 * b03 - a32 * b00,
a20 * b03 - a21 * b01 + a22 * b00) / det;
}
@end
// for this block, define a variable called `model_space_pos` to be used as an input // for this block, define a variable called `model_space_pos` to be used as an input
@block vs_compute_light_output @block vs_compute_light_output
@ -12,7 +56,7 @@
vec4 frag_pos = view * world_space_frag_pos; vec4 frag_pos = view * world_space_frag_pos;
//@Speed I think we can just take the third row here and be fine. //@Speed I think we can just take the third row here and be fine.
light_dir = normalize(inverse(directional_light_space_matrix) * vec4(0.0, 0.0, -1.0, 0.0)).xyz; light_dir = normalize(my_inverse(directional_light_space_matrix) * vec4(0.0, 0.0, -1.0, 0.0)).xyz;
light_space_fragment_position = directional_light_space_matrix * vec4(world_space_frag_pos.xyz, 1.0); light_space_fragment_position = directional_light_space_matrix * vec4(world_space_frag_pos.xyz, 1.0);
@ -47,6 +91,8 @@ float decode_normalized_float32(vec4 v)
return sign * (v.z*255.0 + v.y); return sign * (v.z*255.0 + v.y);
} }
@include_block inverse_functions
void main() { void main() {
vec4 total_position = vec4(0.0f); vec4 total_position = vec4(0.0f);
@ -104,6 +150,8 @@ uniform vs_params {
vec3 wobble_world_source; vec3 wobble_world_source;
}; };
@include_block inverse_functions
void main() { void main() {
//vec3 transformed_pos = vec3(pos_in.x, pos_in.y + sin(pos_in.x * 5.0 + pos_in.y * 9.0 + time*1.9)*0.045, pos_in.z); //vec3 transformed_pos = vec3(pos_in.x, pos_in.y + sin(pos_in.x * 5.0 + pos_in.y * 9.0 + time*1.9)*0.045, pos_in.z);

@ -23,8 +23,8 @@
#define BUBBLE_LINES_PER_PAGE 2 #define BUBBLE_LINES_PER_PAGE 2
#define AI_MAX_BUBBLE_PAGES_IN_OUTPUT 2 #define AI_MAX_BUBBLE_PAGES_IN_OUTPUT 2
#define ARENA_SIZE (1024*1024*10) #define ARENA_SIZE (1024*1024*20)
#define BIG_ARENA_SIZE (ARENA_SIZE * 8) #define BIG_ARENA_SIZE (ARENA_SIZE * 4)
#ifdef DEVTOOLS #ifdef DEVTOOLS
// server url cannot have trailing slash // server url cannot have trailing slash
@ -49,7 +49,7 @@
#define MAXIMUM_THREEDEE_THINGS 1024 #define MAXIMUM_THREEDEE_THINGS 1024
#define ANIMATION_BLEND_TIME 0.15f #define ANIMATION_BLEND_TIME 0.15f
#define REMEMBERED_MEMORIES 32 #define REMEMBERED_MEMORIES 64
#define REMEMBERED_ERRORS 6 #define REMEMBERED_ERRORS 6
#define MAX_AFTERIMAGES 6 #define MAX_AFTERIMAGES 6

@ -1,16 +1,21 @@
#pragma once
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#ifdef WEB #ifdef WEB
#include <assert.h> //#include <assert.h>
#include <signal.h>
#endif #endif
static inline void assert_impl(bool cond, const char *expression) static void assert_impl(bool cond, const char *expression)
{ {
if(!cond) if(!cond)
{ {
fprintf(stderr, "Assertion failed: %s\n", expression); fprintf(stderr, "Assertion failed: %s\n", expression);
#ifdef WEB #ifdef WEB
assert(false); raise(SIGTRAP);
//assert(false);
#elif defined(DESKTOP) #elif defined(DESKTOP)
__debugbreak(); __debugbreak();
#else #else
@ -23,3 +28,5 @@ static inline void assert_impl(bool cond, const char *expression)
#endif #endif
#define assert(cond) assert_impl(cond, #cond) #define assert(cond) assert_impl(cond, #cond)
#define Log(...) { printf("%s Log %d | ", __FILE__, __LINE__); printf(__VA_ARGS__); }

@ -216,7 +216,7 @@ body {
}; };
window.onerror = function(event) { window.onerror = function(event) {
console.log("onerror: " + event.message); console.log("onerror: " + event.message);
for(;;) {} //for(;;) {}
}; };
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
@ -367,6 +367,8 @@ function load_all() {
console.log("Reading full game"); console.log("Reading full game");
let decoded = decode(read_data); let decoded = decode(read_data);
Module.ccall('read_from_save_data', 'void', ['array', 'number'], [new Uint8Array(decoded), decoded.byteLength]); Module.ccall('read_from_save_data', 'void', ['array', 'number'], [new Uint8Array(decoded), decoded.byteLength]);
} else {
console.log("Couldn't find full game");
} }
} }
} }

Loading…
Cancel
Save