Archived
1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
skcblitz/program.h
2025-09-02 14:43:36 +02:00

743 lines
27 KiB
C

byte win_down(byte bind) {
return sys.binds[bind].pressed;
}
byte win_pressed(byte bind) {
return sys.binds[bind].active;
}
void handle_int(int sig) {
sys.interrupted = 1;
fprintf(stderr, "\n");
}
void input() {
bind_t *bind;
for(int z = 0; z < KEY_BINDS; z++) {
bind = &sys.binds[z];
if(sys.input ^ 1) {
bind->pressed = 0;
}
else if(bind->key >= 1 && bind->key <= KEYSYM_LAST) {
bind->pressed = wcf.active && (wcf_getkey(wcf.active, bind->key) == KEY_PRESS);
}
else if(bind->key >= -MOUSE_BTN_C && bind->key <= -MOUSE_LEFT) {
bind->pressed = wcf.active && !(wcf.active->open) && ((wcf.active->mouse >> (-MOUSE_LEFT - bind->key)) & 1);
if(!sys.mouse_bind)
bind->last_state = bind->pressed;
}
else if(bind->key >= -SCROLL_RIGHT && bind->key <= -SCROLL_UP) {
bind->pressed = wcf.active && !(wcf.active->open) && ((wcf.active->scroll >> (-SCROLL_UP - bind->key)) & 1);
}
else {
bind->pressed = 0;
}
bind->active = bind->pressed && !(bind->last_state);
bind->last_state = bind->pressed;
}
sys.mouse_bind = 1;
if(wcf.active)
wcf.active->scroll = 0;
if(win_pressed(KEY_QUIT)) {
sys.interrupted = 1;
}
if(win_pressed(KEY_SYNC)) {
cvar_setint("win_sync", sys.win_vsync ? sys.sync_limit : (sys.sync_limited ? -1 : 0));
}
if(win_pressed(KEY_SCREENSHOT)) {
sys.screenshot = 1;
}
if(win_pressed(KEY_PLAYER)) {
plr_rand();
if(snd.player && snd.player->open)
gui_update_text(gui_get(snd.player, 1));
}
if(wcf.active && wcf.active->world) {
if(win_pressed(KEY_FULLSCREEN)) {
win_full(!sys.win_full);
}
if(win_pressed(KEY_MENU)) {
gui_open(wcf.active, wcf.active->open ^ 1);
}
if(win_pressed(KEY_SHOW)) {
if(sys.draw_debug) {
sys.draw_debug = sys.draw_fps = 0;
}
else {
sys.draw_debug = sys.draw_fps;
sys.draw_fps = 1;
}
}
}
if(wcf.active && wcf.active->world && !wcf.active->open) {
if(wcf.active->world->pointed && win_pressed(KEY_FLY)) {
world_remove(wcf.active->world, wcf.active->world->pointed);
}
if(wcf.active->world->noclip) {
if((!(wcf.active->world->camonly) && win_pressed(KEY_NOCLIP)) || (wcf.active->world->camonly && win_pressed(KEY_CAMERA))) {
if(wcf.active->world->camonly && wcf.active->world->entity) {
cam_angle_ent(&wcf.active->world->camera, wcf.active->world->entity);
cam_pos_ent(&wcf.active->world->camera, wcf.active->world->entity, 0.0);
}
log_hud(wcf.active, wcf.active->world->camonly ? STR_CAMERA_OFF : STR_NOCLIP_OFF);
wcf.active->world->noclip = wcf.active->world->camonly = 0;
}
}
else if(wcf.active->world->entity) {
if(win_pressed(KEY_NOCLIP)) {
log_hud(wcf.active, STR_NOCLIP_ON);
wcf.active->world->noclip = 1;
}
else if(win_pressed(KEY_CAMERA)) {
log_hud(wcf.active, STR_CAMERA_ON);
wcf.active->world->noclip = wcf.active->world->camonly = 1;
}
}
if(win_down(KEY_ZOOM_IN)) {
cam_zoom(&wcf.active->world->camera, 0.05f);
}
if(win_down(KEY_ZOOM_OUT)) {
cam_zoom(&wcf.active->world->camera, -0.05f);
}
if((wcf.active->world->noclip && wcf.active->world->camonly) || !(wcf.active->world->entity)) {
float speed = sys.speed * (win_down(KEY_FAST) ? 20.0f : 5.0f);
if(win_down(KEY_DOWN)) {
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_DOWN);
}
if(win_down(KEY_UP)) {
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_UP);
}
if(win_down(KEY_FORWARD)) {
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_FORWARD);
}
if(win_down(KEY_BACKWARD)) {
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_BACKWARD);
}
if(win_down(KEY_LEFT)) {
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_LEFT);
}
if(win_down(KEY_RIGHT)) {
cam_move_noclip(&wcf.active->world->camera, sys.fdelta, speed, DIR_RIGHT);
}
}
else {
wcf.active->world->entity->speed = /* sys.speed_fixed ? 1.0f : */ sys.speed;
wcf.active->world->entity->sprint = win_down(KEY_FAST);
wcf.active->world->entity->sneak = win_down(KEY_DOWN);
wcf.active->world->entity->jump = win_down(KEY_UP);
wcf.active->world->entity->forward = (win_down(KEY_FORWARD) ? 1.0f : 0.0f) + (win_down(KEY_BACKWARD) ? -1.0f : 0.0f);
wcf.active->world->entity->strafe = (win_down(KEY_LEFT) ? 1.0f : 0.0f) + (win_down(KEY_RIGHT) ? -1.0f : 0.0f);
}
// if(wld.entity && !(wld.camonly))
// ent_angle_cam(wld.entity, &wld.camera);
}
if(!(sys.keywait))
sys.input = 1;
}
void screenshot() {
time_t t = time(0);
struct tm *date = localtime(&t);
struct stat statbuf;
int stride = (((wcf.current->frame_x * 3) & 3) ? (4 + ((wcf.current->frame_x * 3) & ~3)) : (wcf.current->frame_x * 3));
int n = 0;
byte *data = mem_alloc(stride * wcf.current->frame_y, MEM_IMAGE);
mkdir(DIR_SCREENSHOTS, 0777);
do {
sprintf(sys.work_buf, DIR_SCREENSHOTS"/screen_%02d-%02d-%d_%02d-%02d-%02d%s%.0d.png",
date->tm_mday, date->tm_mon + 1, date->tm_year + 1900, date->tm_hour, date->tm_min, date->tm_sec, n ? "_" : "", n);
n++;
}
while(!stat(sys.work_buf, &statbuf));
glReadPixels(wcf.current->offset_x, (wcf.current->fb_y - wcf.current->frame_y) - wcf.current->offset_y,
wcf.current->frame_x, wcf.current->frame_y, GL_RGB, GL_UNSIGNED_BYTE, data);
if(img_save(sys.work_buf, wcf.current->frame_x, wcf.current->frame_y, 0, 1, stride, data))
logu(LOG_SYS, STR_MSG_SCREENSHOT, sys.work_buf);
mem_free(data);
}
const char *framecode() {
return (sys.tmr_framerate >= 59.0f) ? COL_GREEN : ((sys.tmr_framerate >= 29.0f) ? COL_YELLOW : ((sys.tmr_framerate >= 14.0f) ? COL_ORANGE : COL_RED));
}
const char *tpscode() {
return (sys.tick_tickrate >= (((float)sys.tick_target / 1000.0f) - 1.0f)) ? COL_GREEN : ((sys.tick_tickrate >= (((float)sys.tick_target / 1000.0f) / 2.0f - 1.0f)) ? COL_YELLOW :
((sys.tick_tickrate >= (((float)sys.tick_target / 1000.0f) / 4.0f - 1.0f)) ? COL_ORANGE : COL_RED));
}
ulong perf_get(byte section) {
return sys.tmr_profile[(sys.perf_swap ? 0 : PERF_SECTIONS) + section];
}
byte gl_isdebug() {
int flags;
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
return (flags & GL_CONTEXT_FLAG_DEBUG_BIT) == GL_CONTEXT_FLAG_DEBUG_BIT;
}
const char *gl_getsuffix() {
int mask;
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
if(mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
return " compat";
else if(mask & GL_CONTEXT_CORE_PROFILE_BIT)
return " core";
else
return "";
}
void print_debug(world_t *world) {
int pos;
pos = sprintf(sys.work_buf,
"%s%.2f"COL_RESET" %s, @ "COL_RED"%.1f "COL_GREEN"%.1f "COL_CYAN"%.1f"COL_RESET", Y "COL_MAGENTA"%.1f"COL_RESET", P "COL_YELLOW"%.1f"COL_RESET
", H %.1f, F %.1f, Z %.1f, M "COL_RED"%.1f "COL_GREEN"%.1f "COL_CYAN"%.1f"COL_RESET
,
framecode(), (sys.tmr_framerate < 1.0f) ? (1.0f / sys.tmr_framerate) : sys.tmr_framerate, sys.tmr_framerate < 1.0f ? "SPF" : "FPS",
world->camera.pos_x, world->camera.pos_y, world->camera.pos_z, world->camera.yaw, world->camera.pitch, (world->entity && !world->camonly) ? world->entity->eye : 0.0,
gdr.fov, world->camera.zoom * (gdr.fov - 1.0f),
world->entity ? world->entity->motion_x : 0.0, world->entity ? world->entity->motion_y : 0.0, world->entity ? world->entity->motion_z : 0.0
);
if(world->pointed)
pos = sprintf(&sys.work_buf[pos],
", -> "COL_YELLOW"#%llu "COL_RESET"("COL_RED"%.1f "COL_GREEN"%.1f "COL_CYAN"%.1f"COL_RESET")"
,
world->pointed, world->look_pos X, world->look_pos Y, world->look_pos Z
);
}
void tick_start(world_t *world) {
world->last_cx = (int)NEG_OFFSET(world->camera.pos_x, CHUNK_SIZE);
world->last_cy = (int)NEG_OFFSET(world->camera.pos_y, CHUNK_SIZE);
world->last_cz = (int)NEG_OFFSET(world->camera.pos_z, CHUNK_SIZE);
if(world->entity && !(world->camonly))
ent_angle_cam(world->entity, &world->camera);
}
void tick_main(world_t *world) {
ent_tick(&world->entity_base);
}
void tick_end(world_t *world) {
if(world->entity && !(world->camonly))
cam_pos_ent(&world->camera, world->entity, sys.tick_fraction);
if(world->last_cx != (int)NEG_OFFSET(world->camera.pos_x, CHUNK_SIZE) || world->last_cy != (int)NEG_OFFSET(world->camera.pos_y, CHUNK_SIZE) ||
world->last_cz != (int)NEG_OFFSET(world->camera.pos_z, CHUNK_SIZE))
world->light_dirty = 1;
}
void tick() {
window_t *win;
sys.tick_stime = tmr_rtime();
if((sys.tick_stime - sys.tick_update) >= 1000000ULL) {
sys.tick_tickrate = ((float)sys.tick_done) * 1000000.0f / ((float)(ulong)(sys.tick_stime - sys.tick_update));
sys.tick_done = 0;
sys.tick_update = sys.tick_stime;
}
if(sys.ticked ^ 1) {
sys.tick_time = 0ULL;
return;
}
sys.tick_torun += (((ulong)sys.tick_target) * sys.tmr_delta) / 1000ULL;
sys.tick_frame = 0;
for(win = wcf.window_list; win; win = win->next) {
if(win->world)
tick_start(win->world);
}
while(sys.tick_torun >= 1000000ULL) {
for(win = wcf.window_list; win; win = win->next) {
if(win->world)
tick_main(win->world);
}
sys.tick_done += 1ULL;
sys.tick_frame += 1;
sys.tick_total += 1ULL;
sys.tick_torun -= 1000000ULL;
if((sys.tick_ftime = (tmr_rtime() - sys.tick_stime)) >= (((ulong)sys.tick_timeout) * 1000ULL)) {
logw(LOG_TIC, STR_TICK_TIMEOUT, sys.tick_ftime / 1000ULL, sys.tick_timeout, sys.tick_torun / 1000000ULL);
sys.tick_torun = 0ULL;
break;
}
}
sys.tick_fraction = ((double)sys.tick_torun) / 1000000.0;
for(win = wcf.window_list; win; win = win->next) {
if(win->world)
tick_end(win->world);
}
sys.tick_ttime += sys.tick_ftime;
sys.tick_time = sys.tick_frame ? (sys.tick_ftime / (ulong)sys.tick_frame) : 0ULL;
}
void tick_target(float tps) {
sys.tick_target = (int)(tps * 1000.0f);
sys.tick_torun = 0ULL;
sys.tick_done = 0ULL;
sys.tick_update = tmr_rtime();
sys.ticked = tps > 0.0f;
}
float rfloat(float min, float max) {
return ((float)(int)(rand() % 1000000000)) / 1000000000.0f * (max - min) + min;
}
void floor_test(world_t *world, material_t *mat, int n) {
for(int z = 0; z < n; z++) {
world_add_floor(world, rfloat(-1800.0f, 1800.0f), rfloat(-230.0f, 230.0f), rfloat(-1800.0f, 1800.0f), rfloat(8.0f, 40.0f), rfloat(8.0f, 40.0f), mat);
}
}
void snd_apply() {
plr_debug(cvar_byte("mid_debug_events"));
for(int z = 0; z < SND_VOLUMES; z++) {
plr_volume(z, (ushort)(cvar_float(snd_cvar_volume[z]) * 32767.0f));
}
}
void save_vars() {
cvar_setint("win_pos_x", sys.console->xpos);
cvar_setint("win_pos_y", sys.console->ypos);
cvar_setint("win_width", sys.console->xsize);
cvar_setint("win_height", sys.console->ysize);
}
static const float lm_test[] = {20.0f, 20.0f, 40.0f, 20.0f, 20.0f, 40.0f};
float wg_test(void *p, float x, float z) {
noisegen_t *gen = (noisegen_t*)p;
// float n = (x * x + z * z) *
// (sinf(7.57f * M_PI*2.0f*x) + 1.0f) * (sinf(16.7585f * M_PI*2.0f*z) + 1.0f) * (sinf(8.657f * M_PI*2.0f*x) + 1.0f) * (sinf(6.75485f * M_PI*2.0f*z) + 1.0f);
// srand((int)(x * 16384.0f) ^ (int)(z * 16384.0f));
// n += rfloat(0.0f, n / 8.0f);
double n;
noise_gen(gen, &n, (double)x, 0, (double)z, 1, 1, 1, 512.0, 512.0, 512.0);
return (float)(n / 512.0);
}
uint tex_test, tex_floor;
material_t *mat_test;
material_t *mat_floor;
material_t *mat_grid;
material_t *mat_vis;
void start(char **cmds, int n_cmds) {
tex_load(&tex_test, "textures/test.png", TEX_FLAG_FILTER | TEX_FLAG_MIPMAP);
tex_load(&tex_floor, "textures/floor.png", TEX_FLAG_FILTER | TEX_FLAG_MIPMAP);
mat_test = gfx_add_material(tex_test, 512.0f, 0xffffff, 4.0f, NULL);
mat_floor = gfx_add_material(tex_floor, 512.0f, 0xffffff, 1.0f, NULL);
mat_grid = gfx_add_material(0, 512.0f, 0xffffff, 1.0f, gdr.shd_grid);
mat_vis = gfx_add_material(0, 512.0f, 0xffffff, 1.0f, gdr.shd_vis);
// plr_play("/home/sen/Musik/midi50k/Video_Games/ff/ff2cecil.mid", 0);
for(int z = 0; z < n_cmds; z++) {
if(strlen(cmds[z]) >= CON_LINE)
loge(LOG_SYS, STR_CON_TOOLONG, z + 1);
else
con_exec(cmds[z]);
}
}
void test(window_t *win) {
world_init(win, 0.0, 32.0, 0.0, 90.0f, 0.0f);
noisegen_t gen;
ulong rng = rng_rseed();
noise_gen_init(&gen, &rng, 16);
switch(rng_zrange(&rng, 3)) {
case 0:
for(int z = 0; z < 10; z++) {
world_add_box(win->world, 10.0f + (float)z * 2.0f, 64.0f, 20.0f, 4.0f, (float)(z + 1) * 0.5f, 6.0f, mat_test);
}
world_add_graph(win->world, wg_test, &gen, -1536.0f, 0.0f, -1536.0f, 3072.0f, 0.125f, 3072.0f, mat_floor,
128, 128, 0.0f, 0.0f, 512.0f, 512.0f, 1);
light_b lamp;
for(int z = 0; z < 256; z++) {
light_init_def(&lamp, ((rand() & 0xff) | 0x40) << ((rand() % 3) << 3), 1.0f);
world_add_light(win->world, &lamp, rfloat(-1250.0f, 1250.0f), rfloat(4.0f, 8.0f), rfloat(-1250.0f, 1250.0f));
}
break;
case 1:
world_add_graph(win->world, wg_test, &gen, -1536.0f, 0.0f, -1536.0f, 3072.0f, 2.0f, 3072.0f, mat_grid,
128, 128, 0.0f, 0.0f, 512.0f, 512.0f, 1);
break;
case 2:
world_add_graph(win->world, wg_test, &gen, -1536.0f, 0.0f, -1536.0f, 3072.0f, 1.0f, 3072.0f, mat_vis,
256, 256, 0.0f, 0.0f, 512.0f, 512.0f, 1);
break;
}
noise_gen_free(&gen);
}
void run() {
window_t *win;
PERF_FIRST()
while(sys.interrupted ^ 1) {
PERF_START(PERF_TIMING)
sys.tmr_current = tmr_rtime();
sys.tmr_delta = sys.tmr_current - sys.tmr_last;
sys.tmr_last = sys.tmr_current;
sys.fdelta = ((float)sys.tmr_delta) / 1000000.0f;
if((sys.tmr_current - sys.tmr_update) >= 1000000ULL) {
sys.tmr_framerate = ((float)sys.tmr_frames) * 1000000.0f / ((float)(ulong)(sys.tmr_current - sys.tmr_update));
sys.tmr_frames = 0;
sys.tmr_update = sys.tmr_current;
// logi(LOG_SYS, "%.3f FPS", sys.tmr_framerate);
}
PERF_SEC(PERF_INPUT)
for(win = wcf.window_list; win; win = win->next) {
gui_check(win);
}
input();
if(wcf.active)
gui_await(wcf.active);
PERF_SEC(PERF_TICK)
tick();
PERF_SEC(PERF_UPDATE)
plr_update();
for(win = wcf.window_list; win; win = win->next) {
if(win->world) {
// wcf_selcontext(wcf.active);
// glViewport(0, 0, wcf.active->fb_x, wcf.active->fb_y);
world_update(win->world);
win->world->pointed = box_get_pointed(win->world, &win->world->camera, win->world->look_pos);
}
}
PERF_SEC(PERF_RENDER)
gdr.lists_drawn = 0;
gdr.tris_drawn = 0;
for(win = wcf.window_list; win; win = win->next) {
if(win->world) {
wcf_selcontext(win);
gdr.shader = 0;
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, gdr.post ? win->world->fb_post : 0);
glClearColor(gdr.clear_r, gdr.clear_g, gdr.clear_b, gdr.clear_a);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(gdr.wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glViewport(win->offset_x, (win->fb_y - win->frame_y) - win->offset_y,
win->frame_x, win->frame_y);
// gfx_pass_world();
// glBindTexture(GL_TEXTURE_2D, gdr.tex_test);
// glDrawArrays(GL_TRIANGLES, 0, 36);
// draw_floor(gdr.world);
draw_world(win->world);
// ...
// glViewport(0, 0, wld.window->fb_x, wld.window->fb_y);
if(gdr.wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
PERF_SEC(PERF_GUI)
for(win = wcf.window_list; win; win = win->next) {
wcf_selcontext(win);
gdr.shader = 0;
glViewport(0, 0, win->fb_x, win->fb_y);
glDisable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, win->fb_gui);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
if(win->redraw) {
win->redraw = 0;
glClear(GL_COLOR_BUFFER_BIT);
}
if(win->fb_x && win->fb_y)
gfx_draw_gui(win);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if(gdr.post && win->world)
gfx_blit(win->world->fbtex_post);
gfx_draw_rect(0, win->offset_y - (win->fb_x - win->frame_x) / 2, win->fb_x, win->frame_y + win->fb_x - win->frame_x, (win->fb_x - win->frame_x) / 2,
0, 0, 0, sys.style.wbrdr_top, sys.style.wbrdr_btm);
if(!(win->world))
gfx_draw_rect(win->offset_x, win->offset_y, win->frame_x, win->frame_y, 0, 0, sys.style.bg_top, sys.style.bg_btm, 0, 0);
else if(!win->open)
gfx_draw_rect(win->offset_x + (win->frame_x / 2) - 16, win->offset_y + (win->frame_y / 2) - 16, 32, 32, 0, gdr.tex_crosshair,
win->world->pointed ? 0xffffffff : 0xffcfcfcf, win->world->pointed ? 0xffffffff : 0xffcfcfcf, 0, 0);
gfx_blit(win->fbtex_gui);
if(win == wcf.active)
gfx_draw_gui_overlay(win);
if(win->drag_x || win->drag_y) {
sprintf(sys.work_buf, "%d x %d", win->frame_x, win->frame_y);
txt_draw(0, 0, 0, sys.font.yglyph, sys.font.yglyph,
0, 0, win->fb_x, win->fb_y,
0xffff0000, 0xff000000, &sys.font, sys.work_buf);
}
if(sys.hud_overlay && win->world)
gfx_draw_con_overlay(win);
if(sys.draw_fps && win->world) {
// gfx_pass_text();
if(sys.draw_debug) {
print_debug(win->world);
txt_draw(win->offset_x, win->offset_y + (sys.hud_bottom ? 0 : (win->frame_y - sys.font.yglyph)),
0, sys.font.yglyph, sys.font.yglyph,
win->offset_x, win->offset_y + (sys.hud_bottom ? 0 : (win->frame_y - sys.font.yglyph)),
win->offset_x + win->frame_x, win->offset_y + win->frame_y,
0xffffffff, 0x40000000, &sys.font, sys.work_buf);
// print_profile();
// txt_draw(win->offset_x + win->frame_x - ((sys.mono.xglyph - 1) * 28), win->offset_y, 0, sys.mono.yglyph, sys.mono.yglyph,
// win->offset_x + win->frame_x - ((sys.mono.xglyph - 1) * 28), win->offset_y, win->offset_x + win->frame_x, win->offset_y + win->frame_y,
// 0xffffffff, 0x40000000, &sys.mono, sys.work_buf);
}
else {
sprintf(sys.work_buf, "%s%.2f", framecode(), sys.tmr_framerate);
txt_draw(win->offset_x, win->offset_y + (sys.hud_bottom ? 0 : (win->frame_y - sys.font.yglyph)),
0, sys.font.yglyph, sys.font.yglyph,
win->offset_x, win->offset_y + (sys.hud_bottom ? 0 : (win->frame_y - sys.font.yglyph)),
win->offset_x + win->frame_x, win->offset_y + win->frame_y,
0xffffffff, 0x40000000, &sys.font, sys.work_buf);
}
}
}
PERF_SEC(PERF_REST)
if(sys.screenshot) {
sys.screenshot = 0;
if(wcf.active) {
wcf_selcontext(wcf.active);
glViewport(0, 0, wcf.active->fb_x, wcf.active->fb_y);
screenshot();
}
}
if(sys.cfg_dirty) {
save_vars();
cvar_save();
sys.cfg_dirty = 0;
}
PERF_SEC(PERF_SWAP)
for(win = wcf.window_list; win; win = win->next) {
wcf_selcontext(win);
glViewport(0, 0, win->fb_x, win->fb_y);
if(sys.gl_flush)
glFlush(); // glFinish();
wcf_swap(win);
}
PERF_SEC(PERF_EVENTS)
snd_log_flush();
wcf_poll();
PERF_SEC(PERF_WAIT)
while(sys.sync_limited && (tmr_rtime() - sys.tmr_current) < (1000000ULL / sys.sync_limit)) {
;
}
sys.tmr_frames += 1;
PERF_END()
}
PERF_LAST()
}
void end() {
wcf_end();
// #ifdef MEM_TRACING
// logt(LOG_MEM, STR_MEM_FREE, SYS_BASE, (ulong)(&sys), sys.mem_alloc -= SYS_BASE, "base");
// #else
sys.mem_alloc -= SYS_BASE;
// #endif
logp(LOG_MEM, STR_MEM_PEAK, sys.mem_peak);
if(sys.mem_alloc) {
logw(LOG_MEM, STR_MEM_LEAK, sys.mem_alloc);
}
logi(LOG_SYS, STR_EXIT);
sys_remove_handlers();
}
void finish() {
logi(LOG_SYS, STR_SHUTDOWN);
// world_delete(wld.world);
// wld.world = NULL;
plr_end();
if(snd_end())
logi(LOG_SYS, STR_SND_STOP);
save_vars();
win_end();
con_end();
cvar_end();
gfx_end();
end();
}
void snd_start(byte disabled) {
const char *devname = snd_edevice[cvar_int("snd_device_type")];
if(!strcmp(devname, "hw") || !strcmp(devname, "plughw")) {
int dev = cvar_int("snd_device_index");
int sub = cvar_int("snd_device_sub");
sprintf(sys.work_buf, dev < 0 ? "default" : (sub < 0 ? "%s:%d" : "%s:%d,%d"), devname, dev, sub);
devname = sys.work_buf;
}
uint samplerate = snd_init(devname, cvar_int("snd_sample_rate"), cvar_byte("snd_sample_format") ? 32 : 16, cvar_int("snd_frame_size"), cvar_int("snd_buffer_size"), disabled);
snd_log_flush();
if(samplerate)
logi(LOG_SYS, STR_SND_START, devname, samplerate);
else if(!disabled && strcmp(devname, "none"))
loge(LOG_SYS, STR_SND_STARTERR, devname);
}
void snd_restart() {
byte disabled = sgt.disabled;
plr_end();
if(snd_end())
logi(LOG_SYS, STR_SND_STOP);
memset(&sgt, 0, sizeof(isnd_t));
memset(&snd, 0, sizeof(snd_t));
snd_start(disabled);
snd_apply();
}
const char *gl_debug_source(uint src) {
switch(src) {
case GL_DEBUG_SOURCE_API:
return "API";
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
return "WIN";
case GL_DEBUG_SOURCE_SHADER_COMPILER:
return "SHD";
case GL_DEBUG_SOURCE_THIRD_PARTY:
return "3RD";
case GL_DEBUG_SOURCE_APPLICATION:
return "PRG";
case GL_DEBUG_SOURCE_OTHER:
default:
return "XXX";
}
}
const char *gl_debug_type(uint type) {
switch(type) {
case GL_DEBUG_TYPE_ERROR:
return "ERR!";
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
return "DEPR";
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
return "NDEF";
case GL_DEBUG_TYPE_PORTABILITY:
return "PORT";
case GL_DEBUG_TYPE_PERFORMANCE:
return "PERF";
case GL_DEBUG_TYPE_MARKER:
return "MARK";
case GL_DEBUG_TYPE_PUSH_GROUP:
return "GPSH";
case GL_DEBUG_TYPE_POP_GROUP:
return "GPOP";
case GL_DEBUG_TYPE_OTHER:
default:
return "XXXX";
}
}
byte gl_debug_severity(uint level) {
switch(level) {
case GL_DEBUG_SEVERITY_HIGH:
return LOG_ERROR;
case GL_DEBUG_SEVERITY_MEDIUM:
return LOG_WARN;
case GL_DEBUG_SEVERITY_LOW:
return LOG_INFO;
case GL_DEBUG_SEVERITY_NOTIFICATION:
default:
return LOG_PERF;
}
}
void gl_debug_callback(uint src, uint type, uint id, uint level, int len, const char *msg, const void *user) {
byte lvl = gl_debug_severity(level);
const char *color = log_colors[lvl];
log_str(LOG_GFX, lvl, COL_DGRAY"[%sGL:%d"COL_DGRAY"][%s%s"COL_DGRAY"][%s%s"COL_DGRAY"]%s %s",
color, id, color, gl_debug_source(src), color, gl_debug_type(type), color, msg);
}
byte init(const char *cfgfile, const char *langfile, byte loglevel, byte gldebug, byte nosound) {
clockid_t timer;
sys_setup_handlers();
sys_test_handlers(getenv("ERROR_HANDLER_TEST"));
timer = tmr_gettimer();
memset(&sys, 0, sizeof(sys_t));
memset(&gdr, 0, sizeof(gfx_t));
memset(&sgt, 0, sizeof(isnd_t));
memset(&snd, 0, sizeof(snd_t));
signal(SIGINT, handle_int);
sys.tmr_timer = (ulong)timer;
sys.tmr_start = tmr_time();
sys.log_level = loglevel == 0xff ? LOG_INFO : loglevel;
sys.log_set = loglevel;
sys.cfg_file = cfgfile;
sys.rng_uniq = 8682522807148012L;
con_reset();
loc_init();
loc_def();
if(langfile)
loc_load(langfile);
logi(LOG_SYS, SYS_PROGRAM_FULL);
logi(LOG_SYS, STR_BUILD_COMPILER, BUILD_COMP);
logi(LOG_SYS, STR_BUILD_SYSTEM, BUILD_SYS);
// #ifdef MEM_TRACING
// logt(LOG_MEM, STR_MEM_ALLOC, SYS_BASE, (ulong)(&sys), sys.mem_alloc = sys.mem_peak = SYS_BASE, "base");
// #else
sys.mem_alloc = sys.mem_peak = SYS_BASE;
// #endif
if(!wcf_init(gldebug))
return 0;
if(!(sys.console = wcf_create(SYS_PROGRAM, 1))) {
loge(LOG_GFX, STR_WIN_CREATE_ERR);
wcf_end();
return 0;
}
if(gl_isdebug()) {
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, 1);
glDebugMessageCallback(gl_debug_callback, NULL);
}
logi(LOG_GFX, "OpenGL %s%s%s", glGetString(GL_VERSION), gl_getsuffix(), gl_isdebug() ? " debug" : "");
logi(LOG_GFX, "GLSL %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
logi(LOG_GFX, "GL_VENDOR: %s", glGetString(GL_VENDOR));
logi(LOG_GFX, "GL_RENDERER: %s", glGetString(GL_RENDERER));
logi(LOG_SYS, STR_STARTUP);
if(!gfx_init()) {
gfx_end();
end();
return 0;
}
cvar_init();
con_init();
win_init();
win_sync(cvar_int("win_sync"));
snd_start(nosound);
snd_apply();
light_setup(cvar_int("gl_dynlight_max"));
cvar_setdef("tic_target");
tex_load(&gdr.tex_logo, "textures/logo.png", 0);
tex_load(&gdr.tex_crosshair, "textures/crosshair.png", 0);
return 1;
}
/*
txt_draw(80, 80, 0, 18, 18, 80, 80, sys.fb_x - 80, sys.fb_y - 80, 0xff1f1f1f, 0x40000000, &sys.font,
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_BLACK" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_DGRAY" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_GRAY" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_LGRAY" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_WHITE" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_RED" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_GREEN" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_BLUE" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_YELLOW" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_MAGENTA" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_CYAN" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_VIOLET" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_ORANGE" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_CRIMSON" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_MIDNIGHT" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_NEON" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_AUX1" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_AUX2" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_AUX3" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_AUX4" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_AUX5" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_AUX6" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_AUX7" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_AUX8" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~"STR_UNK"§°²³´µÄÖÜßäöü€"STR_WSPC"\n"
COL_RESET"END\n"
);
*/