From 3c3bf65c564e5df5e4d2e8fdcfe5a05bccb372ee Mon Sep 17 00:00:00 2001 From: Cameron Reikes Date: Sun, 16 Oct 2022 07:43:12 -0700 Subject: [PATCH] Debug drawing and better build shortcut --- build_debug.bat | 2 +- debugdraw.c | 76 +++++++++++++++++++++++++++++++++++++++++ gamestate.c | 9 +++++ main.c | 90 +++++++++++++++++++++++++++++-------------------- tooling.ahk | 15 ++++++++- types.h | 6 +++- 6 files changed, 158 insertions(+), 40 deletions(-) create mode 100644 debugdraw.c diff --git a/build_debug.bat b/build_debug.bat index 496f2aa..a7fd93a 100644 --- a/build_debug.bat +++ b/build_debug.bat @@ -7,5 +7,5 @@ IF %ERRORLEVEL% NEQ 0 ECHO ERROR download sokol-shdc from https://github.com/flo @REM example of how to compile shaders: sokol-shdc.exe --input triangle.glsl --output triangle.gen.h --slang glsl330:hlsl5:metal_macos -cl /MP /Zi /Fd"flight.pdb" /I"thirdparty" /Fe"flight" /I"thirdparty\enet\include" main.c gamestate.c server.c^ +cl /MP /Zi /Fd"flight.pdb" /I"thirdparty" /Fe"flight" /I"thirdparty\enet\include" main.c gamestate.c server.c debugdraw.c^ thirdparty\enet\callbacks.c thirdparty\enet\compress.c thirdparty\enet\host.c thirdparty\enet\list.c thirdparty\enet\packet.c thirdparty\enet\peer.c thirdparty\enet\protocol.c thirdparty\enet\win32.c Ws2_32.lib winmm.lib \ No newline at end of file diff --git a/debugdraw.c b/debugdraw.c new file mode 100644 index 0000000..44cd5fb --- /dev/null +++ b/debugdraw.c @@ -0,0 +1,76 @@ +#include "sokol_gfx.h" +#include "sokol_gp.h" +#include "types.h" + +#define MAX_COMMANDS 64 + +typedef struct Command +{ + enum + { + rect, + line + } type; + union + { + // rect + V2 center; + + // line + struct + { + V2 from; + V2 to; + }; + }; +} Command; + +// thread local variables so debug drawing in server thread +// doesn't fuck up main thread +static __declspec(thread) Command commands[MAX_COMMANDS] = {0}; +static __declspec(thread) int command_i = 0; + +void dbg_drawall() +{ + // return; + sgp_set_color(0.4f, 0.8f, 0.2f, 0.8f); + for (int i = 0; i < command_i; i++) + { + const float size = 0.05f; + switch(commands[i].type) + { + case rect: + V2 center = commands[i].center; + V2 upper_left = V2add(center, (V2){.x = -size / 2.0f, .y = -size / 2.0f}); + sgp_draw_filled_rect(upper_left.x, upper_left.y, size, size); + break; + case line: + V2 from = commands[i].from; + V2 to = commands[i].to; + sgp_draw_line(from.x, from.y, to.x, to.y); + break; + } + } + command_i = 0; +} + +void dbg_line(V2 from, V2 to) +{ + commands[command_i] = (Command){ + .type = line, + .from = from, + .to = to, + }; + command_i++; + command_i %= MAX_COMMANDS; +} + +void dbg_rect(V2 center) +{ + commands[command_i] = (Command){ + .type = rect, + .center = center, + }; + command_i++; + command_i %= MAX_COMMANDS; +} \ No newline at end of file diff --git a/gamestate.c b/gamestate.c index 0952e63..633fd8f 100644 --- a/gamestate.c +++ b/gamestate.c @@ -60,6 +60,7 @@ static void modify_interval(struct Body *from, float *from_interval, V2 center, } } + void process(struct GameState *gs, float dt) { int num_bodies = gs->num_boxes; @@ -113,6 +114,10 @@ void process(struct GameState *gs, float dt) V2 axis = V2normalize(V2sub(to->position, from->position)); V2 center = V2scale(V2add(to->position, from->position), 0.5f); + dbg_line(from->position, to->position); + + dbg_rect(center); + float from_interval[2] = {1000.0f, -1000.0f}; float to_interval[2] = {1000.0f, -1000.0f}; modify_interval(from, from_interval, center, axis); @@ -120,9 +125,13 @@ void process(struct GameState *gs, float dt) assert(from_interval[0] < from_interval[1]); assert(to_interval[0] < to_interval[1]); + // @BeforeShip debug compile time flag in preprocessor + if (from_interval[1] > to_interval[0]) // intersecting { float intersection_depth = from_interval[1] - to_interval[0]; + + from->position = V2add(from->position, V2scale(axis, intersection_depth*-0.5f)); to->position = V2add(to->position, V2scale(axis, intersection_depth*0.5f)); } diff --git a/main.c b/main.c index 53dd229..0692f49 100644 --- a/main.c +++ b/main.c @@ -14,7 +14,6 @@ #include "types.h" - static struct GameState gs = {0}; static int myplayer = -1; static bool mouse_down = false; @@ -35,8 +34,6 @@ void init(void) exit(-1); } - - sgp_desc sgpdesc = {0}; sgp_setup(&sgpdesc); if (!sgp_is_valid()) @@ -102,40 +99,46 @@ static void frame(void) // networking { ENetEvent event; - while(true) + while (true) { int enet_status = enet_host_service(client, &event, 0); - if(enet_status > 0 ) + if (enet_status > 0) { - switch(event.type) + switch (event.type) { - case ENET_EVENT_TYPE_CONNECT: - Log("New client from host %x\n", event.peer->address.host); - break; - case ENET_EVENT_TYPE_RECEIVE: - // @Robust @BeforeShip use some kind of serialization strategy that checks for out of bounds - // and other validation instead of just casting to a struct - // "Alignment of structure members can be different even among different compilers on the same platform, let alone different platforms." - // ^^ need serialization strategy that accounts for this if multiple platforms is happening https://stackoverflow.com/questions/28455163/how-can-i-portably-send-a-c-struct-through-a-network-socket - struct ServerToClient msg; - if(event.packet->dataLength != sizeof(msg)) - { - Log("Unknown packet size: %zd\n", event.packet->dataLength); - } else { - memcpy(&msg, event.packet->data, sizeof(msg)); - myplayer = msg.your_player; - gs = msg.cur_gs; - } - enet_packet_destroy(event.packet); - break; - case ENET_EVENT_TYPE_DISCONNECT: - fprintf(stderr, "Disconnected from server\n"); - exit(-1); - break; + case ENET_EVENT_TYPE_CONNECT: + Log("New client from host %x\n", event.peer->address.host); + break; + case ENET_EVENT_TYPE_RECEIVE: + // @Robust @BeforeShip use some kind of serialization strategy that checks for out of bounds + // and other validation instead of just casting to a struct + // "Alignment of structure members can be different even among different compilers on the same platform, let alone different platforms." + // ^^ need serialization strategy that accounts for this if multiple platforms is happening https://stackoverflow.com/questions/28455163/how-can-i-portably-send-a-c-struct-through-a-network-socket + struct ServerToClient msg; + if (event.packet->dataLength != sizeof(msg)) + { + Log("Unknown packet size: %zd\n", event.packet->dataLength); + } + else + { + memcpy(&msg, event.packet->data, sizeof(msg)); + myplayer = msg.your_player; + gs = msg.cur_gs; + } + enet_packet_destroy(event.packet); + break; + case ENET_EVENT_TYPE_DISCONNECT: + fprintf(stderr, "Disconnected from server\n"); + exit(-1); + break; } - } else if(enet_status == 0) { + } + else if (enet_status == 0) + { break; - } else if(enet_status < 0) { + } + else if (enet_status < 0) + { fprintf(stderr, "Error receiving enet events: %d\n", enet_status); break; } @@ -152,17 +155,16 @@ static void frame(void) }; curmsg.input = input; - ENetPacket * packet = enet_packet_create((void*)&curmsg, sizeof(curmsg), ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); + ENetPacket *packet = enet_packet_create((void *)&curmsg, sizeof(curmsg), ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); enet_peer_send(peer, 0, packet); - // process(&gs, (float)sapp_frame_duration()); + process(&gs, (float)sapp_frame_duration()); } // drawing { sgp_begin(width, height); sgp_viewport(0, 0, width, height); - // sgp_project(-ratio, ratio, 1.0f, -1.0f); sgp_project(0.0f, width, 0.0f, height); // Draw background color @@ -172,13 +174,14 @@ static void frame(void) // Drawing in world space now sgp_translate(width / 2, height / 2); sgp_scale_at(300.0f + funval, 300.0f + funval, 0.0f, 0.0f); + + // camera go to player if (myplayer != -1) { sgp_translate(-gs.players[myplayer].body.position.x, -gs.players[myplayer].body.position.y); } sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); - sgp_draw_filled_rect(100.0f, 100.0f, 400.0f, 400.0f); // stars const int num = 50; @@ -200,20 +203,33 @@ static void frame(void) continue; sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); sgp_push_transform(); - sgp_rotate_at(p->body.rotation,p->body.position.x, p->body.position.y); + sgp_rotate_at(p->body.rotation, p->body.position.x, p->body.position.y); sgp_draw_filled_rect(p->body.position.x - halfbox, p->body.position.y - halfbox, BOX_SIZE, BOX_SIZE); sgp_pop_transform(); + + sgp_set_color(1.0f, 0.0f, 0.0f, 1.0f); + V2 vel = (V2scale(V2sub(p->body.position, p->body.old_position), 60.0f)); + V2 to = V2add(p->body.position, vel); + sgp_draw_line(p->body.position.x, p->body.position.y, to.x, to.y); } // boxes { - sgp_set_color(0.5f, 0.5f, 0.5f, 1.0f); for (int i = 0; i < gs.num_boxes; i++) { + sgp_set_color(0.5f, 0.5f, 0.5f, 1.0f); sgp_draw_filled_rect(gs.boxes[i].body.position.x - halfbox, gs.boxes[i].body.position.y - halfbox, BOX_SIZE, BOX_SIZE); + + sgp_set_color(1.0f, 0.0f, 0.0f, 1.0f); + V2 vel = (V2scale(V2sub(gs.boxes[i].body.position, gs.boxes[i].body.old_position), 60.0f)); + V2 to = V2add(gs.boxes[i].body.position, vel); + sgp_draw_line(gs.boxes[i].body.position.x, gs.boxes[i].body.position.y, to.x, to.y); } } + sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); + dbg_drawall(); + // sgp_draw_line(5.0f, 5.0f, 5.0f, 10.0f); // sgp_draw_line() // sgp_rotate_at(time, 0.0f, 0.0f); diff --git a/tooling.ahk b/tooling.ahk index 0f7c8f4..a4b0255 100644 --- a/tooling.ahk +++ b/tooling.ahk @@ -4,6 +4,18 @@ SendMode, Input SetBatchLines, -1 SetWorkingDir, %A_ScriptDir% +^b:: +WinKill, Flight +Sleep, 20 +WinKill, Flight +Sleep, 20 +WinKill, Flight +WinActivate, flightbuild +If WinActive("flightbuild") +{ + Send, build_debug.bat && flight.exe --host{Enter} +} +return ^+b:: WinKill, Flight @@ -15,4 +27,5 @@ WinActivate, flightbuild If WinActive("flightbuild") { Send, build_debug.bat && START /B flight.exe && flight.exe --host{Enter} -} \ No newline at end of file +} +return \ No newline at end of file diff --git a/types.h b/types.h index 90c655f..5203468 100644 --- a/types.h +++ b/types.h @@ -80,9 +80,13 @@ struct ClientToServer void server(void *data); // gamestate - void process(struct GameState *gs, float dt); // does in place +// debug draw +void dbg_drawall(); +void dbg_line(V2 from, V2 to); +void dbg_rect(V2 center); + // all the math is static so that it can be defined in each compilation unit its included in static V2 V2add(V2 a, V2 b)