2023-01-04 18:09:42 -06:00
|
|
|
#include "yugine.h"
|
|
|
|
|
2023-05-04 00:03:36 -05:00
|
|
|
|
2022-02-04 11:36:24 -06:00
|
|
|
#include "camera.h"
|
|
|
|
#include "window.h"
|
2022-01-19 16:43:21 -06:00
|
|
|
#include "engine.h"
|
2022-02-04 11:36:24 -06:00
|
|
|
#include "input.h"
|
|
|
|
#include "openglrender.h"
|
2023-02-02 17:52:15 -06:00
|
|
|
#include "gameobject.h"
|
2023-04-22 14:07:37 -05:00
|
|
|
#include "font.h"
|
2023-02-02 17:52:15 -06:00
|
|
|
|
2023-03-24 14:01:01 -05:00
|
|
|
#define MINIAUDIO_IMPLEMENTATION
|
|
|
|
#include "miniaudio.h"
|
|
|
|
|
2023-02-02 17:52:15 -06:00
|
|
|
#include "timer.h"
|
|
|
|
|
2023-04-22 14:07:37 -05:00
|
|
|
#include "quickjs/quickjs.h"
|
|
|
|
|
2022-08-14 18:10:29 -05:00
|
|
|
#include "script.h"
|
2023-02-02 17:52:15 -06:00
|
|
|
#include "ffi.h"
|
2022-12-23 13:48:29 -06:00
|
|
|
|
2022-11-18 12:03:07 -06:00
|
|
|
#include "log.h"
|
2022-11-24 01:54:17 -06:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2022-12-22 03:50:40 -06:00
|
|
|
#include "2dphysics.h"
|
|
|
|
|
2022-11-24 01:54:17 -06:00
|
|
|
#include <signal.h>
|
|
|
|
#include <time.h>
|
2023-04-28 12:49:18 -05:00
|
|
|
#include <execinfo.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
|
|
|
|
#define SOKOL_GLCORE33
|
|
|
|
#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;
|
|
|
|
|
2022-12-20 08:16:26 -06:00
|
|
|
double renderMS = 1/165.f;
|
2022-08-12 14:03:56 -05:00
|
|
|
double physMS = 1/120.f;
|
|
|
|
double updateMS = 1/60.f;
|
2022-02-04 11:36:24 -06:00
|
|
|
|
2022-08-14 14:19:36 -05:00
|
|
|
static int ed = 1;
|
2022-12-22 03:50:40 -06:00
|
|
|
static int sim_play = 0;
|
|
|
|
static double lastTick;
|
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
|
|
|
|
2023-02-28 17:03:28 -06:00
|
|
|
#define SIM_STOP 0
|
|
|
|
#define SIM_PLAY 1
|
|
|
|
#define SIM_PAUSE 2
|
|
|
|
#define SIM_STEP 3
|
|
|
|
|
2023-04-24 17:22:18 -05:00
|
|
|
void print_stacktrace()
|
|
|
|
{
|
2023-03-17 10:25:35 -05:00
|
|
|
void *ents[512];
|
2022-11-24 01:54:17 -06:00
|
|
|
size_t size;
|
|
|
|
|
|
|
|
size = backtrace(ents, 512);
|
|
|
|
|
|
|
|
YughCritical("====================BACKTRACE====================");
|
|
|
|
char **stackstr = backtrace_symbols(ents, size);
|
|
|
|
|
2023-02-02 17:52:15 -06:00
|
|
|
YughInfo("Stack size is %d.", size);
|
|
|
|
|
2023-04-25 11:55:33 -05:00
|
|
|
for (int i = 0; i < size; i++)
|
2022-11-24 01:54:17 -06:00
|
|
|
YughCritical(stackstr[i]);
|
|
|
|
|
2023-04-28 12:49:18 -05:00
|
|
|
js_stacktrace();
|
2023-04-24 17:22:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void seghandle(int sig) {
|
|
|
|
#ifdef __linux__
|
2023-04-25 11:55:33 -05:00
|
|
|
if (strsignal(sig))
|
2023-04-24 17:22:18 -05:00
|
|
|
YughCritical("CRASH! Signal: %s.", strsignal(sig));
|
|
|
|
|
|
|
|
print_stacktrace();
|
2023-02-02 17:52:15 -06:00
|
|
|
|
2023-03-17 10:25:35 -05:00
|
|
|
exit(1);
|
2022-12-12 10:48:21 -06:00
|
|
|
#endif
|
2022-11-24 01:54:17 -06:00
|
|
|
}
|
2022-02-04 11:36:24 -06:00
|
|
|
|
2023-04-22 14:07:37 -05:00
|
|
|
void compile_script(const char *file)
|
|
|
|
{
|
|
|
|
const char *script = slurp_text(file);
|
|
|
|
JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAG_COMPILE_ONLY|JS_EVAL_TYPE_GLOBAL);
|
|
|
|
size_t out_len;
|
|
|
|
uint8_t *out;
|
|
|
|
out = JS_WriteObject(js, &out_len, obj, JS_WRITE_OBJ_BYTECODE);
|
|
|
|
|
|
|
|
FILE *f = fopen("out.jsc", "w");
|
|
|
|
fwrite(out, sizeof out[0], out_len, f);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
|
2023-05-04 17:07:00 -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)
|
|
|
|
{
|
|
|
|
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) {
|
2022-12-15 17:30:22 -06:00
|
|
|
int logout = 1;
|
2023-03-17 10:25:35 -05:00
|
|
|
ed = 1;
|
2022-12-15 17:30:22 -06:00
|
|
|
|
2023-04-22 14:07:37 -05:00
|
|
|
script_startup();
|
|
|
|
|
2022-08-14 14:19:36 -05:00
|
|
|
for (int i = 1; i < argc; i++) {
|
|
|
|
if (args[i][0] == '-') {
|
2022-11-24 01:54:17 -06:00
|
|
|
switch(args[i][1]) {
|
|
|
|
case 'p':
|
|
|
|
ed = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
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-11-24 10:58:36 -06:00
|
|
|
case 'v':
|
|
|
|
printf("Yugine version %s, %s build.\n", VER, INFO);
|
2023-02-23 17:03:58 -06:00
|
|
|
printf("Copyright 2022-2023 odplot productions LLC.\n");
|
2022-11-24 10:58:36 -06:00
|
|
|
exit(1);
|
|
|
|
break;
|
|
|
|
|
2023-04-22 14:07:37 -05:00
|
|
|
case 's':
|
|
|
|
compile_script(args[2]);
|
|
|
|
exit(0);
|
|
|
|
|
2023-04-24 17:22:18 -05:00
|
|
|
case 'm':
|
|
|
|
logLevel = atoi(args[2]);
|
|
|
|
break;
|
|
|
|
|
2022-12-14 13:01:42 -06:00
|
|
|
case 'h':
|
|
|
|
printf("-l Set log file\n");
|
2023-04-10 09:53:01 -05:00
|
|
|
printf("-p Launch engine in play mode instead of editor mode\n");
|
2022-12-14 13:01:42 -06:00
|
|
|
printf("-v Display engine info\n");
|
2023-02-23 17:03:58 -06:00
|
|
|
printf("-c Redirect logging to console\n");
|
2022-12-14 13:01:42 -06:00
|
|
|
exit(0);
|
|
|
|
break;
|
|
|
|
|
2022-12-15 17:30:22 -06:00
|
|
|
case 'c':
|
|
|
|
logout = 0;
|
|
|
|
break;
|
|
|
|
|
2022-08-14 14:19:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-23 13:48:29 -06:00
|
|
|
#if DBG
|
|
|
|
if (logout) {
|
2022-11-24 01:54:17 -06:00
|
|
|
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;
|
2023-04-19 15:16:35 -05:00
|
|
|
/* sysinfo = popen("uname -a", "r");
|
2022-11-24 01:54:17 -06:00
|
|
|
if (!sysinfo) {
|
|
|
|
YughWarn("Failed to get sys info.");
|
|
|
|
} else {
|
|
|
|
log_cat(sysinfo);
|
|
|
|
pclose(sysinfo);
|
2023-04-19 15:16:35 -05:00
|
|
|
}*/
|
2022-12-23 13:48:29 -06:00
|
|
|
signal(SIGSEGV, seghandle);
|
2023-02-23 17:03:58 -06:00
|
|
|
signal(SIGABRT, seghandle);
|
|
|
|
signal(SIGFPE, seghandle);
|
2023-04-24 17:22:18 -05:00
|
|
|
signal(SIGBUS, seghandle);
|
|
|
|
|
2022-12-23 13:48:29 -06:00
|
|
|
#endif
|
|
|
|
|
2022-01-19 16:43:21 -06:00
|
|
|
engine_init();
|
|
|
|
|
2022-08-15 16:38:21 -05:00
|
|
|
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
2022-11-18 12:03:07 -06:00
|
|
|
YughInfo("Refresh rate is %d", vidmode->refreshRate);
|
2022-08-15 16:38:21 -05:00
|
|
|
|
|
|
|
renderMS = 1.0/vidmode->refreshRate;
|
2023-05-04 17:07:00 -05:00
|
|
|
|
|
|
|
sg_setup(&(sg_desc){
|
|
|
|
.logger = {
|
|
|
|
.func = sg_logging,
|
|
|
|
.user_data = NULL,
|
|
|
|
},
|
|
|
|
});
|
2023-04-24 17:22:18 -05:00
|
|
|
|
2023-04-25 14:59:26 -05:00
|
|
|
input_init();
|
2023-04-24 17:22:18 -05:00
|
|
|
openglInit();
|
2022-08-15 16:38:21 -05:00
|
|
|
|
2023-03-17 10:25:35 -05:00
|
|
|
if (ed)
|
2023-04-22 16:44:26 -05:00
|
|
|
script_dofile("scripts/editor.js");
|
2023-03-17 10:25:35 -05:00
|
|
|
else
|
2023-04-24 17:22:18 -05:00
|
|
|
script_dofile("scripts/play.js");
|
2022-01-19 16:43:21 -06:00
|
|
|
|
2022-12-16 11:54:05 -06:00
|
|
|
while (!want_quit()) {
|
2022-12-20 08:16:26 -06:00
|
|
|
double elapsed = glfwGetTime() - lastTick;
|
|
|
|
deltaT = elapsed;
|
2022-08-12 14:03:56 -05:00
|
|
|
lastTick = glfwGetTime();
|
2022-12-29 04:26:21 -06:00
|
|
|
double wait = fmax(0, renderMS-elapsed);
|
|
|
|
input_poll(wait);
|
|
|
|
window_all_handle_events();
|
2022-01-19 16:43:21 -06:00
|
|
|
|
2022-12-29 04:26:21 -06:00
|
|
|
framems[framei++] = elapsed;
|
2023-02-03 22:18:19 -06:00
|
|
|
|
|
|
|
if (framei == FPSBUF) framei = 0;
|
2022-12-20 08:16:26 -06:00
|
|
|
|
2023-02-28 17:03:28 -06:00
|
|
|
if (sim_play == SIM_PLAY || sim_play == SIM_STEP) {
|
2023-03-17 10:25:35 -05:00
|
|
|
timer_update(elapsed * timescale);
|
2022-12-22 03:50:40 -06:00
|
|
|
physlag += elapsed;
|
2022-12-22 16:58:06 -06:00
|
|
|
call_updates(elapsed * timescale);
|
|
|
|
while (physlag >= physMS) {
|
2023-03-10 13:13:48 -06:00
|
|
|
phys_step = 1;
|
2022-12-22 03:50:40 -06:00
|
|
|
physlag -= physMS;
|
2022-12-22 16:58:06 -06:00
|
|
|
phys2d_update(physMS * timescale);
|
2023-03-17 10:25:35 -05:00
|
|
|
call_physics(physMS * timescale);
|
2023-02-28 17:03:28 -06:00
|
|
|
if (sim_play == SIM_STEP) sim_pause();
|
2023-03-10 13:13:48 -06:00
|
|
|
phys_step = 0;
|
2022-12-22 03:50:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-03 22:18:19 -06:00
|
|
|
renderlag += elapsed;
|
|
|
|
|
2022-08-07 01:43:45 -05:00
|
|
|
if (renderlag >= renderMS) {
|
|
|
|
renderlag -= renderMS;
|
2022-12-20 08:16:26 -06:00
|
|
|
window_renderall();
|
2022-08-07 01:43:45 -05:00
|
|
|
}
|
2022-01-19 16:43:21 -06:00
|
|
|
|
2023-01-13 08:05:36 -06:00
|
|
|
gameobjects_cleanup();
|
2022-01-19 16:43:21 -06:00
|
|
|
}
|
2022-11-03 16:58:03 -05:00
|
|
|
|
|
|
|
return 0;
|
2022-01-19 16:43:21 -06:00
|
|
|
}
|
2022-12-22 03:50:40 -06:00
|
|
|
|
2022-12-29 04:26:21 -06:00
|
|
|
int frame_fps()
|
|
|
|
{
|
|
|
|
double fpsms = 0;
|
2023-02-03 22:18:19 -06:00
|
|
|
for (int i = 0; i < FPSBUF; i++) {
|
|
|
|
fpsms += framems[i];
|
|
|
|
}
|
2022-12-29 04:26:21 -06:00
|
|
|
|
2023-02-03 22:18:19 -06:00
|
|
|
return FPSBUF / fpsms;
|
2022-12-29 04:26:21 -06:00
|
|
|
}
|
|
|
|
|
2023-02-28 17:03:28 -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
|
|
|
|
2022-12-22 03:50:40 -06:00
|
|
|
void sim_start() {
|
2023-02-28 17:03:28 -06:00
|
|
|
sim_play = SIM_PLAY;
|
2022-12-22 03:50:40 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void sim_pause() {
|
2023-02-28 17:03:28 -06:00
|
|
|
sim_play = SIM_PAUSE;
|
2022-12-22 03:50:40 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void sim_stop() {
|
|
|
|
/* Revert starting state of everything from sim_start */
|
2023-02-28 17:03:28 -06:00
|
|
|
sim_play = SIM_STOP;
|
2022-12-22 03:50:40 -06:00
|
|
|
}
|
|
|
|
|
2023-03-10 13:13:48 -06:00
|
|
|
int phys_stepping() { return phys_step; }
|
|
|
|
|
2022-12-22 03:50:40 -06:00
|
|
|
void sim_step() {
|
2023-02-06 17:21:00 -06:00
|
|
|
if (sim_paused()) {
|
2023-02-28 17:03:28 -06:00
|
|
|
YughInfo("Step");
|
|
|
|
sim_play = SIM_STEP;
|
2023-02-06 17:21:00 -06:00
|
|
|
}
|
2022-12-22 16:58:06 -06:00
|
|
|
}
|
2022-12-22 03:50:40 -06:00
|
|
|
|
2022-12-22 16:58:06 -06:00
|
|
|
void set_timescale(float val) {
|
|
|
|
timescale = val;
|
2023-02-02 17:52:15 -06:00
|
|
|
}
|