prosperon/source/engine/yugine.c

309 lines
5.9 KiB
C
Raw Normal View History

2023-01-04 18:09:42 -06:00
#include "yugine.h"
2022-02-04 11:36:24 -06:00
#include "camera.h"
2022-01-19 16:43:21 -06:00
#include "engine.h"
2023-05-12 13:22:05 -05:00
#include "font.h"
#include "gameobject.h"
2022-02-04 11:36:24 -06:00
#include "input.h"
#include "openglrender.h"
2023-05-12 13:22:05 -05:00
#include "window.h"
2023-03-24 14:01:01 -05:00
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
#include "timer.h"
2023-04-22 14:07:37 -05:00
#include "quickjs/quickjs.h"
#include "ffi.h"
2023-05-12 13:22:05 -05:00
#include "script.h"
2022-12-23 13:48:29 -06:00
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include "2dphysics.h"
2023-05-30 11:39:22 -05:00
#ifdef __linux__
2023-05-12 13:22:05 -05:00
#include <execinfo.h>
2023-05-30 11:39:22 -05:00
#endif
#include <signal.h>
#include <time.h>
2022-02-04 11:36:24 -06:00
2022-08-14 14:19:36 -05:00
#include "string.h"
2023-05-04 17:07:00 -05:00
#define SOKOL_TRACE_HOOKS
#define SOKOL_GFX_IMPL
2023-05-30 11:39:22 -05:00
#define SOKOL_GLES3
2023-05-04 17:07:00 -05:00
#include "sokol/sokol_gfx.h"
2022-02-04 11:36:24 -06:00
int physOn = 0;
2022-02-06 10:14:57 -06:00
double renderlag = 0;
2022-08-12 14:03:56 -05:00
double physlag = 0;
double updatelag = 0;
2023-05-12 13:22:05 -05:00
double renderMS = 1 / 165.f;
2023-05-29 10:47:30 -05:00
double physMS = 1 / 165.f;
double updateMS = 1 / 165.f;
2022-02-04 11:36:24 -06:00
static int sim_play = 0;
2023-05-24 20:45:50 -05:00
double lastTick = 0.0;
2023-03-10 13:13:48 -06:00
static int phys_step = 0;
2022-08-14 14:19:36 -05:00
2022-12-22 16:58:06 -06:00
static float timescale = 1.f;
2022-12-29 04:26:21 -06:00
#define FPSBUF 10
static double framems[FPSBUF];
int framei = 0;
int fps;
2022-12-27 17:54:39 -06:00
#define SIM_STOP 0
#define SIM_PLAY 1
#define SIM_PAUSE 2
#define SIM_STEP 3
2023-05-27 10:13:20 -05:00
#ifdef __TINYC__
int backtrace(void **buffer, int size) {
extern uint64_t *__libc_stack_end;
uint64_t **p, *bp, *frame;
asm ("mov %%rbp, %0;" : "=r" (bp));
p = (uint64_t**) bp;
int i = 0;
while (i < size) {
frame = p[0];
if (frame < bp || frame > __libc_stack_end) {
return i;
}
buffer[i++] = p[1];
p = (uint64_t**) frame;
}
return i;
}
#endif
2023-05-30 11:39:22 -05:00
2023-05-12 13:22:05 -05:00
void print_stacktrace() {
2023-05-30 11:39:22 -05:00
#ifdef __linux__
2023-05-12 13:22:05 -05:00
void *ents[512];
2023-05-27 10:13:20 -05:00
size_t size = backtrace(ents, 512);
2023-05-12 13:22:05 -05:00
YughCritical("====================BACKTRACE====================");
char **stackstr = backtrace_symbols(ents, size);
2023-05-27 10:13:20 -05:00
YughCritical("Stack size is %d.", size);
2023-05-12 13:22:05 -05:00
for (int i = 0; i < size; i++)
YughCritical(stackstr[i]);
2023-05-12 13:22:05 -05:00
js_stacktrace();
2023-05-30 11:39:22 -05:00
#endif
}
void seghandle(int sig) {
#ifdef __linux__
2023-05-12 13:22:05 -05:00
if (strsignal(sig))
YughCritical("CRASH! Signal: %s.", strsignal(sig));
2023-05-12 13:22:05 -05:00
print_stacktrace();
2023-05-12 13:22:05 -05:00
exit(1);
#endif
}
2022-02-04 11:36:24 -06:00
2023-06-28 11:35:41 -05:00
const char *engine_info()
{
char str[100];
snprintf(str, 100, "Yugine version %s, %s build.\nCopyright 2022-2023 odplot productions LLC.\n", VER, INFO);
return str;
}
2023-04-22 14:07:37 -05:00
2023-05-12 13:22:05 -05:00
void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uint32_t line, const char *file, void *data) {
2023-05-04 17:07:00 -05:00
mYughLog(0, 1, line, file, "tag: %s, msg: %s", tag, msg);
}
2022-08-07 01:43:45 -05:00
int main(int argc, char **args) {
2023-05-12 13:22:05 -05:00
int logout = 1;
script_startup();
2023-07-02 23:05:21 -05:00
logout = 0;
2023-05-12 13:22:05 -05:00
for (int i = 1; i < argc; i++) {
if (args[i][0] == '-') {
switch (args[i][1]) {
case 'l':
if (i + 1 < argc && args[i + 1][0] != '-') {
log_setfile(args[i + 1]);
i++;
continue;
} else {
YughError("Expected a file for command line arg '-l'.");
exit(1);
2022-08-14 14:19:36 -05:00
}
2023-05-12 13:22:05 -05:00
case 'v':
2023-06-28 11:35:41 -05:00
printf(engine_info());
2023-05-12 13:22:05 -05:00
exit(1);
break;
case 's':
compile_script(args[2]);
exit(0);
case 'm':
logLevel = atoi(args[2]);
break;
case 'c':
logout = 0;
break;
}
2022-08-14 14:19:36 -05:00
}
2023-05-12 13:22:05 -05:00
}
2022-08-14 14:19:36 -05:00
2022-12-23 13:48:29 -06:00
#if DBG
2023-05-12 13:22:05 -05:00
if (logout) {
time_t now = time(NULL);
char fname[100];
snprintf(fname, 100, "yugine-%d.log", now);
log_setfile(fname);
}
YughInfo("Starting yugine version %s.", VER);
FILE *sysinfo = NULL;
/* sysinfo = popen("uname -a", "r");
if (!sysinfo) {
YughWarn("Failed to get sys info.");
} else {
log_cat(sysinfo);
pclose(sysinfo);
}*/
signal(SIGSEGV, seghandle);
signal(SIGABRT, seghandle);
signal(SIGFPE, seghandle);
signal(SIGBUS, seghandle);
2022-12-23 13:48:29 -06:00
#endif
2023-05-12 13:22:05 -05:00
engine_init();
2022-01-19 16:43:21 -06:00
2023-05-12 13:22:05 -05:00
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
YughInfo("Refresh rate is %d", vidmode->refreshRate);
2022-08-15 16:38:21 -05:00
2023-05-12 13:22:05 -05:00
renderMS = 1.0 / vidmode->refreshRate;
2023-05-04 17:07:00 -05:00
2023-05-12 13:22:05 -05:00
sg_setup(&(sg_desc){
2023-05-04 17:07:00 -05:00
.logger = {
2023-05-12 13:22:05 -05:00
.func = sg_logging,
.user_data = NULL,
2023-05-04 17:07:00 -05:00
},
2023-05-24 20:45:50 -05:00
2023-05-12 13:22:05 -05:00
.buffer_pool_size = 1024,
.context.sample_count = 1,
});
input_init();
openglInit();
2023-06-28 11:35:41 -05:00
int argsize = 0;
for (int i = 1; i < argc; i++) {
argsize += strlen(args[i]);
if (argc > i+1) argsize++;
}
2023-05-12 13:22:05 -05:00
2023-06-28 11:35:41 -05:00
char cmdstr[argsize];
cmdstr[0] = '\0';
YughWarn("num is %d", argc);
for (int i = 0; i < argc; i++) {
strcat(cmdstr, args[i]);
if (argc > i+1) strcat(cmdstr, " ");
}
script_evalf("cmd_args('%s');", cmdstr);
2023-05-24 20:45:50 -05:00
2023-05-12 13:22:05 -05:00
while (!want_quit()) {
double elapsed = glfwGetTime() - lastTick;
deltaT = elapsed;
lastTick = glfwGetTime();
2023-05-22 00:08:08 -05:00
//double wait = fmax(0, renderMS - elapsed);
if (sim_playing())
input_poll(fmax(0, renderMS-elapsed));
else
input_poll(1000);
2023-05-12 13:22:05 -05:00
window_all_handle_events();
framems[framei++] = elapsed;
if (framei == FPSBUF) framei = 0;
if (sim_play == SIM_PLAY || sim_play == SIM_STEP) {
timer_update(elapsed * timescale);
physlag += elapsed;
call_updates(elapsed * timescale);
2023-08-17 20:13:17 -05:00
// TODO: Physics is not independent ...
2023-05-29 10:47:30 -05:00
// while (physlag >= physMS) {
2023-05-12 13:22:05 -05:00
phys_step = 1;
physlag -= physMS;
phys2d_update(physMS * timescale);
2023-05-27 07:01:17 -05:00
call_physics(physMS * timescale);
2023-05-12 13:22:05 -05:00
if (sim_play == SIM_STEP) sim_pause();
phys_step = 0;
2023-05-29 10:47:30 -05:00
// }
2023-05-12 13:22:05 -05:00
}
renderlag += elapsed;
2022-01-19 16:43:21 -06:00
2023-05-12 13:22:05 -05:00
if (renderlag >= renderMS) {
renderlag -= renderMS;
window_renderall();
2022-01-19 16:43:21 -06:00
}
2023-05-12 13:22:05 -05:00
gameobjects_cleanup();
}
return 0;
2022-01-19 16:43:21 -06:00
}
2023-05-12 13:22:05 -05:00
int frame_fps() {
double fpsms = 0;
for (int i = 0; i < FPSBUF; i++) {
fpsms += framems[i];
}
2022-12-29 04:26:21 -06:00
2023-05-12 13:22:05 -05:00
return FPSBUF / fpsms;
2022-12-29 04:26:21 -06:00
}
int sim_playing() { return sim_play == SIM_PLAY; }
int sim_paused() { return sim_play == SIM_PAUSE; }
int sim_stopped() { return sim_play == SIM_STOP; }
2022-12-22 16:58:06 -06:00
void sim_start() {
sim_play = SIM_PLAY;
}
void sim_pause() {
sim_play = SIM_PAUSE;
}
void sim_stop() {
2023-05-12 13:22:05 -05:00
/* Revert starting state of everything from sim_start */
sim_play = SIM_STOP;
}
2023-03-10 13:13:48 -06:00
int phys_stepping() { return phys_step; }
void sim_step() {
if (sim_paused()) {
2023-05-12 13:22:05 -05:00
YughInfo("Step");
sim_play = SIM_STEP;
}
2022-12-22 16:58:06 -06:00
}
2022-12-22 16:58:06 -06:00
void set_timescale(float val) {
2023-05-12 13:22:05 -05:00
timescale = val;
}