refactor; remove many unnecessary files and normalize data ingestion as buffer arrays

This commit is contained in:
2024-11-12 09:12:51 -06:00
parent ba9b1c1c9e
commit 8f983c2b43
43 changed files with 1140 additions and 2382 deletions

View File

@@ -8,7 +8,6 @@ if not get_option('editor')
add_project_arguments('-DNEDITOR', language:'c')
endif
add_project_arguments('-Wno-implicit-function-declaration', language: 'c')
add_project_arguments('-Wno-incompatible-function-pointer-types', language: 'c')
add_project_arguments('-Wno-incompatible-pointer-types', language: 'c')
add_project_arguments('-Wno-narrowing', language: 'cpp')
@@ -25,10 +24,12 @@ endif
cc = meson.get_compiler('c')
deps += cc.find_library('jemalloc')
if host_machine.system() == 'linux'
deps += cc.find_library('asound', required:true)
deps += [dependency('x11'), dependency('xi'), dependency('xcursor'), dependency('egl'), dependency('gl')]
link += '-fuse-ld=mold' # use mold, which is very fast, for debug builds
# link += '-fuse-ld=mold' # use mold, which is very fast, for debug builds
endif
if host_machine.system() == 'windows'
@@ -63,7 +64,7 @@ if storefront == 'steam'
endif
sources = []
src = ['anim.c', 'config.c', 'datastream.c','font.c','gameobject.c','HandmadeMath.c','input.c', 'jsffi.c','log.c','model.c','render.c','script.c','resources.c','simplex.c','spline.c','texture.c', 'timer.c', 'transform.c','warp.c','window.c','yugine.c']
src = ['anim.c', 'config.c', 'datastream.c','font.c','gameobject.c','HandmadeMath.c','jsffi.c','model.c','render.c','script.c','simplex.c','spline.c','texture.c', 'timer.c', 'transform.c','warp.c','yugine.c']
imsrc = ['GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp','imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','imnodes.cpp','implot_items.cpp','implot.cpp']

View File

@@ -61,11 +61,7 @@ actor.__stats = function () {
actor.hotreload = function (file) {
var script = Resources.replstrs(file);
script = `(function() {
var self = this;
var $ = this.__proto__;
${script};
})`;
script = `(function() { var self = this; var $ = this.__proto__;${script};})`;
var fn = os.eval(file, script);
for (var obj of actor_spawns[file]) {
@@ -147,7 +143,7 @@ actor.padawans = [];
global.app = Object.create(actor);
app.die = function () {
os.quit();
os.exit(0);
};
return { actor, app };

View File

@@ -1,5 +1,3 @@
"use math";
os.mem_limit.doc = "Set the memory limit of the runtime in bytes.";
os.gc_threshold.doc = "Set the threshold before a GC pass is triggered in bytes. This is set to malloc_size + malloc_size>>1 after a GC pass.";
os.max_stacksize.doc = "Set the max stack size in bytes.";
@@ -217,21 +215,24 @@ Resources.find_font = function(file, root = "") {
console.transcript = "";
console.say = function (msg) {
msg += "\n";
console.print(msg);
if (debug.termout) console.term_print(msg);
console.transcript += msg;
};
console.log = console.say;
globalThis.say = console.say;
globalThis.print = console.print;
console.rec = function(category, priority, line, file, msg)
{
return `${file}:${line}: [${category} ${priority}]: ${msg}`;
}
console.pprint = function (msg, lvl = 0) {
if (typeof msg === "object") msg = JSON.stringify(msg, null, 2);
var file = "nofile";
var line = 0;
console.rec(0, msg, file, line);
var caller = new Error().stack.split("\n")[2];
if (caller) {
@@ -242,8 +243,8 @@ console.pprint = function (msg, lvl = 0) {
m = md ? md[1] : 0;
if (m) line = m;
}
console.rec(lvl, msg, file, line);
var fmt = console.rec("script", lvl, line,file, msg);
console.log(fmt);
};
console.spam = function (msg) {
@@ -277,9 +278,9 @@ console.stack = function (skip = 0) {
};
console.stdout_lvl = 1;
console.trace = console.stack;
console.doc = {
log: "Output directly to in game console.",
level: "Set level to output logging to console.",
info: "Output info level message.",
warn: "Output warn level message.",
@@ -288,7 +289,6 @@ console.doc = {
write: "Write raw text to console.",
say: "Write raw text to console, plus a newline.",
stack: "Output a stacktrace to console.",
console: "Output directly to in game console.",
clear: "Clear console.",
};

View File

@@ -218,7 +218,7 @@ var entity = {
ent.ur.fresh ??= json.decode(json.encode(ent));
ent.ur.fresh.objects = {};
for (var i in ent.objects) ent.ur.fresh.objects[i] = ent.objects[i].instance_obj();
// for (var i in ent.objects) ent.ur.fresh.objects[i] = ent.objects[i].instance_obj();
profile.endreport(`make_${text}`);

View File

@@ -67,7 +67,7 @@ emitter.step = function (dt) {
// update all particles
for (var p of this.particles) {
p.time += dt;
p.transform.move(p.body.velocity.scale(dt));
p.transform.move(p.body.velocity?.scale(dt));
this.step_hook?.(p);
if (this.kill_hook?.(p) || p.time >= p.life) {
@@ -101,6 +101,7 @@ function update_emitters(dt) {
var arr = [];
function draw_emitters() {
return;
ssbo ??= render.make_textssbo();
render.use_shader("shaders/baseparticle.cg");
var buckets = {};

View File

@@ -2,6 +2,7 @@ globalThis.gamestate = {};
global.check_registers = function (obj) {
for (var reg in Register.registries) {
if (!Register.registries[reg].register) return;
if (typeof obj[reg] === "function") {
var fn = obj[reg].bind(obj);
fn.layer = obj[reg].layer;
@@ -21,6 +22,7 @@ global.obscure("global");
global.mixin("render");
global.mixin("debug");
global.mixin("repl");
global.mixin('layout')
var frame_t = profile.secs(profile.now());
@@ -54,31 +56,29 @@ sim.stepping = function () {
var physlag = 0;
var gggstart = game.engine_start;
game.engine_start = function (s) {
game.startengine = 1;
gggstart(
function () {
prosperon.SIGABRT = function()
{
console.log("ABORT");
console.stack();
}
prosperon.SIGSEGV = function()
{
console.stack();
os.exit(1);
}
prosperon.init = function () {
render.init();
imgui.init();
// global.mixin("sound.js");
world_start();
var moon = game.texture('moon');
if (moon) window.set_icon(moon.texture);
Object.readonly(window.__proto__, "vsync");
Object.readonly(window.__proto__, "enable_dragndrop");
Object.readonly(window.__proto__, "enable_clipboard");
Object.readonly(window.__proto__, "high_dpi");
Object.readonly(window.__proto__, "sample_count");
prosperon.camera = prosperon.make_camera();
var camera = prosperon.camera;
camera.transform.pos = [0, 0, -100];
camera.mode = "keep";
camera.break = "fit";
camera.size = game.size;
gamestate.camera = camera;
s();
world_start();
prosperon.camera = prosperon.make_camera();
prosperon.camera.transform.pos = [0, 0, -100];
prosperon.camera.mode = "keep";
prosperon.camera.break = "fit";
prosperon.camera.size = game.size;
shape.quad = {
pos: os.make_buffer([
@@ -119,17 +119,10 @@ game.engine_start = function (s) {
index: os.make_buffer([0, 1, 2, 2, 1, 3], 1),
count: 6,
};
render.init();
},
prosperon.process,
window.size.x,
window.size.y,
);
if (io.exists("game.js")) global.app = actor.spawn("game.js");
else global.app = actor.spawn("nogame.js");
};
game.startengine = 0;
prosperon.release_mode = function () {
prosperon.debug = false;
debug.kill();
@@ -176,7 +169,12 @@ game.doc = {};
game.doc.object = "Returns the entity belonging to a given id.";
game.doc.pause = "Pause game simulation.";
game.doc.play = "Resume or start game simulation.";
game.doc.camera = "Current camera.";
function calc_image_size(img)
{
if (!img.texture || !img.rect) return;
return [img.texture.width*img.rect.width, img.texture.height*img.rect.height];
}
game.tex_hotreload = function (file) {
if (!(file in game.texture.cache)) return;
@@ -365,20 +363,22 @@ game.texture = function (path) {
var ext = path.ext();
if (ext === 'ase' || ext === 'aseprite') {
console.info(`making out of an aseprite for ${path}`);
anim = os.make_aseprite(io.slurpbytes(path));
console.info(`raw anim is ${json.encode(anim)}`)
if (!anim) return;
if (anim.texture) {
// it was a single image
anim.texture.load_gpu();
game.texture.cache[path] = anim;
anim.size = calc_image_size(anim);
return anim;
}
// load all into gpu
for (var a in anim)
for (let frame of anim[a].frames)
for (let frame of anim[a].frames) {
frame.texture.load_gpu();
frame.size = calc_image_size(img);
}
game.texture.cache[path] = anim;
ret = game.texture.cache[path];
@@ -395,10 +395,12 @@ game.texture = function (path) {
anim.rect = anim.frames[0].rect;
anim.frames = undefined;
anim.texture.load_gpu();
anim.size = calc_image_size(anim);
game.texture.cache[path] = anim;
return anim;
}
game.texture.cache[path] = anim;
anim.frames[0].size = calc_image_size(anim.frames[0]);
anim.frames[0].texture.load_gpu();
return anim;
}
@@ -434,6 +436,7 @@ game.texture = function (path) {
game.texture.cache[path] = image;
game.texture.time_cache[path] = io.mod(path);
image.size = calc_image_size(image);
tex.load_gpu();
return game.texture.cache[path];
@@ -511,30 +514,19 @@ prosperon.touchpress = function (touches) {};
prosperon.touchrelease = function (touches) {};
prosperon.touchmove = function (touches) {};
prosperon.clipboardpaste = function (str) {};
prosperon.quit = function () {
prosperon.quit_hook?.();
};
globalThis.window = {};
window.size = [640, 480];
console.log(`window size set to ${window.size.slice()}`)
window.mode = "keep";
window.toggle_fullscreen = function () {
window.fullscreen = !window.fullscreen;
};
window.set_icon.doc = "Set the icon of the window using the PNG image at path.";
window.doc = {};
window.doc.dimensions = "Window width and height packaged in an array [width,height]";
window.doc.title = "Name in the title bar of the window.";
window.doc.boundingbox = "Boundingbox of the window, with top and right being its height and width.";
window.__proto__.toJSON = function () {
return {
size: this.size,
fullscreen: this.fullscreen,
title: this.title,
};
};
global.mixin("input");
global.mixin("std");
global.mixin("diff");
@@ -708,9 +700,6 @@ function world_start() {
game.cam = world;
}
window.title = `Prosperon v${prosperon.version}`;
window.size = [500, 500];
return {
Register,
sim,

View File

@@ -278,14 +278,10 @@ render.use_mat = function use_mat(mat) {
}
};
var models_array = [];
function set_model(t) {
if (cur.shader.vs.unimap.model) render.setunim4(0, cur.shader.vs.unimap.model.slot, t);
}
render.set_model = set_model;
var shaderlang = {
macos: "metal_macos",
windows: "hlsl5",
@@ -1047,7 +1043,7 @@ render.image = function image(image, rect = [0,0], rotation = 0, color = Color.w
var tex = image.texture;
if (!tex) return;
var image_size = calc_image_size(image);
var image_size = calc_image_size(image); //image.size;
var size = [rect.width ? rect.width : image_size.x, rect.height ? rect.height : image_size.y];
@@ -1131,7 +1127,7 @@ render.flush_text = function () {
};
var fontcache = {};
var datas= [];
render.get_font = function(path,size)
{
var parts = path.split('.');
@@ -1139,9 +1135,12 @@ render.get_font = function(path,size)
path = parts[0];
size = Number(parts[1]);
}
path = Resources.find_font(path);
var fontstr = `${path}.${size}`;
if (!fontcache[fontstr]) fontcache[fontstr] = os.make_font(path,size);
path = Resources.find_font(path);
var fontstr = `${path}.${size}`;
if (fontcache[fontstr]) return fontcache[fontstr];
var data = io.slurpbytes(path);
fontcache[fontstr] = os.make_font(data,size);
return fontcache[fontstr];
}
@@ -1277,7 +1276,7 @@ prosperon.make_camera = function () {
cam.far = -1000;
cam.ortho = true;
cam.viewport = [0, 0, 1, 1]; // normalized screen coordinates of where to draw
cam.size = window.size.slice(); // The render size of this camera in pixels
cam.size = game.size.slice(); // The render size of this camera in pixels
// In ortho mode, this determines how many pixels it will see
cam.mode = "stretch";
cam.screen2world = camscreen2world;
@@ -1310,7 +1309,6 @@ var imdebug = function () {
};
var imgui_fn = function () {
imgui.init();
imgui.newframe(window.size.x, window.size.y, 0.01);
if (debug.console)
debug.console = imgui.window("console", _ => {
@@ -1331,7 +1329,7 @@ var imgui_fn = function () {
window.set_icon(game.texture(window.icon));
});
});
imgui.button("quit", os.quit);
imgui.button("quit", os.exit);
});
imgui.menu("Debug", imdebug);
imgui.menu("View", _ => {
@@ -1457,6 +1455,7 @@ function dmon_cb(e)
render.hotreload(e.file);
}
// Ran once per frame
prosperon.process = function process() {
layout.newframe();
// check for hot reloading

View File

@@ -17,7 +17,7 @@ if (ignore = io.slurp('.prosperonignore')) {
var appy = {};
appy.inputs = {};
if (os.sys() === "macos") {
appy.inputs["S-q"] = os.quit;
appy.inputs["S-q"] = os.exit;
}
appy.inputs.f7 = function () {
@@ -35,7 +35,7 @@ appy.inputs.f10 = function () {
appy.inputs.f11 = window.toggle_fullscreen;
appy.inputs.f11.doc = "Toggle window fullscreen.";
appy.inputs.f11.title = "Toggle Fullscreen";
appy.inputs["M-f4"] = os.quit;
appy.inputs["M-f4"] = os.exit;
player[0].control(appy);
@@ -109,12 +109,6 @@ io.slurpwrite = function (path, c) {
return tmpslurpw(path, c);
};
var tmpcp = io.cp;
io.cp = function (f1, f2) {
io.mkpath(f2.dir());
tmpcp(f1, f2);
};
var tmprm = io.rm;
io.rm = function (f) {
tmprm(Resources.replpath(f));
@@ -160,8 +154,6 @@ Cmdline.register_order(
return;
}
window.size = [1280, 720];
window.mode = "full";
sim.pause();
game.engine_start(function () {
@@ -217,27 +209,83 @@ Cmdline.register_order(
// game.loadurs();
if (!io.exists(projectfile)) {
say("No game to play. Try making one with 'prosperon init'.");
console.log("No game to play. Try making one with 'prosperon init'.");
return;
}
var project = json.decode(io.slurp(projectfile));
game.title = project.title;
game.size = [1280, 720];
window.size = game.size;
if (io.exists("config.js")) global.mixin("config.js");
else console.warn("No config.js file found. Starting with default parameters.");
prosperon.title = project.title;
prosperon.width = 1280;
prosperon.height = 720;
prosperon.cleanup = function(){}
prosperon.event = function(e){
switch(e.type) {
case "mouse_move":
prosperon.mousemove(e.mouse, e.mouse_d);
break;
case "mouse_scroll":
prosperon.mousescroll(e.scroll);
break;
case "key_down":
prosperon.keydown(e.key_code, e.key_repeat);
break;
case "key_up":
prosperon.keyup(e.key_code);
break;
case "mouse_up":
prosperon.mouseup(e.mouse_button);
break;
case "mouse_down":
prosperon.mousedown(e.mouse_button);
break;
case "char":
prosperon.textinput(e.char_code);
break;
case "resized":
prosperon.resize([e.window_width, e.window_height]);
break;
case "iconified":
prosperon.iconified(false);
break;
case "restored":
prosperon.iconified(true);
break;
case "focused":
prosperon.focus(true);
break;
case "unfocused":
prosperon.focus(false);
break;
case "suspended":
prosperon.suspended(true);
break;
case "quit_requested":
os.exit(0);
break;
case "mouse_enter":
prosperon.mouseenter();
break;
case "mouse_leave":
prosperon.mouseleave();
break;
}
}
prosperon.frame = prosperon.process;
prosperon.icon = os.make_texture(io.slurpbytes('moon.gif'));
prosperon.high_dpi = 0;
prosperon.alpha = 1;
prosperon.fullscreen = 0;
prosperon.enable_clipboard = true;
prosperon.enable_dragndrop=true;
prosperon.max_dropped_files=1;
prosperon.swap_interval = 1;
if (project.title) window.title = project.title;
game.engine_start(function () {
if (io.exists("game.js")) global.app = actor.spawn("game.js");
else global.app = actor.spawn("nogame.js");
var icon = game.texture(project.icon);
if (icon) window.set_icon(icon.texture);
game.camera = world.spawn("camera2d");
});
game.engine_start(prosperon);
},
"Play the game present in this folder.",
);

View File

@@ -41,6 +41,6 @@ say(`Passed ${pass} tests and failed ${fail} [${((pass * 100) / (pass + fail)).t
say(`Failed tests are:`);
for (var f of failed) say(f);
os.quit();
os.exit(0);
return { test };

View File

@@ -1,5 +1,4 @@
#include "anim.h"
#include "log.h"
#include "stb_ds.h"
void animation_run(struct animation *anim, float now)

View File

@@ -1,13 +1,13 @@
#include "config.h"
#include "render.h"
#define SOKOL_TRACE_HOOKS
#define SOKOL_IMPL
#include "sokol/sokol_audio.h"
#define SOKOL_NO_ENTRY
#include "sokol/sokol_time.h"
#include "sokol/sokol_args.h"
#include "sokol/sokol_gfx.h"
#include "sokol/sokol_app.h"
#include "sokol/util/sokol_gl.h"
#include "sokol/sokol_log.h"
#include "sokol/sokol_glue.h"
#define CUTE_ASEPRITE_IMPLEMENTATION
#include "cute_aseprite.h"
@@ -18,9 +18,6 @@
#define STB_RECT_PACK_IMPLEMENTATION
#include "stb_rect_pack.h"
#define MSF_GIF_IMPL
#include "msf_gif.h"
#define STB_HEXWAVE_IMPLEMENTATION
#include "stb_hexwave.h"

View File

@@ -1,21 +0,0 @@
#ifndef CONFIG_H
#define CONFIG_H
#define MAXPATH 256 /* 255 chars + null */
#define MAXNAME 50
#define PI 3.14159265358979323846264338327950288f
#define DEG2RADS 0.0174532925199432957692369076848861271344287188854172545609719144f
#define RAD2DEGS 57.2958f
#if defined __linux__
#define SOKOL_GLCORE
#elif __EMSCRIPTEN__
#define SOKOL_WGPU
#elif __WIN32
#define SOKOL_D3D11
#elif __APPLE__
#define SOKOL_METAL
#endif
#endif

View File

@@ -1,20 +1,18 @@
#include "datastream.h"
#include "config.h"
#include "limits.h"
#include "log.h"
#include "resources.h"
#include "texture.h"
#include <stdbool.h>
#include <stdlib.h>
#include "font.h"
#include "render.h"
#include <string.h>
#include "cbuf.h"
#include "sokol/sokol_gfx.h"
void datastream_free(datastream *ds)
void datastream_free(JSRuntime *rt,datastream *ds)
{
sg_destroy_image(ds->img);
plm_destroy(ds->plm);
@@ -42,25 +40,14 @@ static void render_audio(plm_t *mpeg, plm_samples_t *samples, struct datastream
// ringpush(ds->ring, samples->interleaved[i]);
}
struct datastream *ds_openvideo(const char *path)
struct datastream *ds_openvideo(void *raw, size_t rawlen)
{
struct datastream *ds = malloc(sizeof(*ds));
size_t rawlen;
void *raw;
raw = slurp_file(path, &rawlen);
ds->plm = plm_create_with_memory(raw, rawlen, 0);
free(raw);
if (!ds->plm) {
YughError("Couldn't open %s", path);
}
YughWarn("Opened %s - framerate: %f, samplerate: %d,audio streams: %d, duration: %g",
path,
plm_get_framerate(ds->plm),
plm_get_samplerate(ds->plm),
plm_get_num_audio_streams(ds->plm),
plm_get_duration(ds->plm));
if (!ds->plm)
return NULL;
ds->img = sg_make_image(&(sg_image_desc){
.width = plm_get_width(ds->plm),

View File

@@ -3,6 +3,7 @@
#include <pl_mpeg.h>
#include <stdint.h>
#include <quickjs.h>
#include "sokol/sokol_gfx.h"
@@ -23,9 +24,9 @@ typedef struct datastream datastream;
struct texture;
void datastream_free(datastream *ds);
void datastream_free(JSRuntime *rt,datastream *ds);
struct datastream *ds_openvideo(const char *path);
struct datastream *ds_openvideo(void *raw, size_t rawlen);
struct texture *ds_maketexture(struct datastream *);
void ds_advance(struct datastream *ds, double);
void ds_seek(struct datastream *ds, double);

View File

@@ -1,20 +1,16 @@
#include "font.h"
#include "log.h"
#include <ctype.h>
#include "log.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <window.h>
#include "resources.h"
#include "render.h"
#include "stb_image_write.h"
#include "stb_rect_pack.h"
#include "stb_truetype.h"
#include "stb_ds.h"
#include "HandmadeMath.h"
@@ -30,7 +26,7 @@ struct text_vert {
static struct text_vert *text_buffer;
void font_free(font *f)
void font_free(JSRuntime *rt, font *f)
{
sg_destroy_image(f->texID);
free(f);
@@ -38,8 +34,6 @@ void font_free(font *f)
struct sFont *MakeSDFFont(const char *fontfile, int height)
{
YughInfo("Making sdf font %s.", fontfile);
int packsize = 1024;
struct sFont *newfont = calloc(1, sizeof(struct sFont));
newfont->height = height;
@@ -47,13 +41,13 @@ struct sFont *MakeSDFFont(const char *fontfile, int height)
char fontpath[256];
snprintf(fontpath, 256, "fonts/%s", fontfile);
unsigned char *ttf_buffer = slurp_file(fontpath, NULL);
// unsigned char *ttf_buffer = slurp_file(fontpath, NULL);
unsigned char *bitmap = malloc(packsize * packsize);
stbtt_fontinfo fontinfo;
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0))) {
YughError("Failed to make font %s", fontfile);
}
// if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0))) {
// YughError("Failed to make font %s", fontfile);
// }
for (int i = 32; i < 95; i++) {
int w, h, xoff, yoff;
@@ -63,17 +57,15 @@ struct sFont *MakeSDFFont(const char *fontfile, int height)
return newfont;
}
struct sFont *MakeFont(const char *fontfile, int height) {
struct sFont *MakeFont(void *ttf_buffer, size_t len, int height) {
if (!ttf_buffer)
return NULL;
int packsize = 2048;
struct sFont *newfont = calloc(1, sizeof(struct sFont));
newfont->height = height;
unsigned char *ttf_buffer = slurp_file(fontfile, NULL);
if (!ttf_buffer) {
YughWarn("Could not find font at %s.", fontfile);
return NULL;
}
unsigned char *bitmap = malloc(packsize * packsize);
stbtt_packedchar glyphs[95];
@@ -88,7 +80,7 @@ struct sFont *MakeFont(const char *fontfile, int height) {
stbtt_fontinfo fontinfo;
if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0))) {
YughError("Failed to make font %s", fontfile);
// YughError("Failed to make font %s", fontfile);
}
int ascent, descent, linegap;
@@ -98,7 +90,6 @@ struct sFont *MakeFont(const char *fontfile, int height) {
newfont->ascent = ascent*emscale;
newfont->descent = descent*emscale;
newfont->linegap = linegap*emscale;
newfont->texture = malloc(sizeof(texture));
newfont->texture->id = sg_make_image(&(sg_image_desc){
.type = SG_IMAGETYPE_2D,
@@ -131,12 +122,10 @@ struct sFont *MakeFont(const char *fontfile, int height) {
newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */
newfont->Characters[c].leftbearing = glyph.xoff;
// printf("char %c: ascent %g, yoff %g, yoff2 %g\n", c, newfont->ascent, glyph.yoff, glyph.yoff2);
newfont->Characters[c].topbearing = -glyph.yoff2;//newfont->ascent - glyph.yoff;
newfont->Characters[c].rect = r;
}
free(ttf_buffer);
free(bitmap);
return newfont;

View File

@@ -4,6 +4,8 @@
#include "sokol/sokol_gfx.h"
#include "render.h"
#include "HandmadeMath.h"
#include <quickjs.h>
#include "texture.h"
typedef enum {
LEFT,
@@ -39,9 +41,9 @@ struct sFont {
typedef struct sFont font;
typedef struct Character glyph;
void font_free(font *f);
void font_free(JSRuntime *rt,font *f);
struct sFont *MakeFont(const char *fontfile, int height);
struct sFont *MakeFont(void *data, size_t len, int height);
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color);
void renderText(const char *text, HMM_Vec2 pos, font *f, float scale, struct rgba color, float wrap);
HMM_Vec2 measure_text(const char *text, font *f, float scale, float letterSpacing, float wrap);

View File

@@ -1,58 +0,0 @@
#include "input.h"
#include "sokol/sokol_app.h"
#include "font.h"
#include "log.h"
#include "script.h"
#include "stb_ds.h"
#include "time.h"
#include <ctype.h>
#include "resources.h"
#include "jsffi.h"
void input_dropped_files(int n)
{
script_evalf("prosperon.droppedfile(`%s`);", sapp_get_dropped_file_path(0));
}
void input_clipboard_paste(char *str)
{
script_evalf("prosperon.clipboardpaste(`%s`);", sapp_get_clipboard_string());
}
static char *touch_jstrn(char *dest, int len, sapp_touchpoint *touch, int n)
{
dest[0] = 0;
char touchdest[512] = {0};
strncat(dest,"[", 512);
for (int i = 0; i < n; i++) {
snprintf(touchdest, 512, "{id:%zd, x:%g, y:%g},", touch[i].identifier, touch[i].pos_x, touch[i].pos_y);
strncat(dest,touchdest,512);
}
strncat(dest,"]", 512);
return dest;
}
void touch_start(sapp_touchpoint *touch, int n)
{
char dest[512] = {0};
script_evalf("prosperon.touchpress(%s);", touch_jstrn(dest, 512, touch, n));
}
void touch_move(sapp_touchpoint *touch, int n)
{
char dest[512] = {0};
script_evalf("prosperon.touchmove(%s);", touch_jstrn(dest,512,touch,n));
}
void touch_end(sapp_touchpoint *touch, int n)
{
char dest[512] = {0};
script_evalf("prosperon.touchend(%s);", touch_jstrn(dest,512,touch,n));
}
void touch_cancelled(sapp_touchpoint *touch, int n)
{
char dest[512] = {0};
script_evalf("prosperon.touchend(%s);", touch_jstrn(dest,512,touch,n));
}

View File

@@ -1,17 +0,0 @@
#ifndef INPUT_H
#define INPUT_H
#include "script.h"
#include <stdint.h>
#include "HandmadeMath.h"
#include "sokol_app.h"
void touch_start(sapp_touchpoint *touch, int n);
void touch_move(sapp_touchpoint *touch, int n);
void touch_end(sapp_touchpoint *touch, int n);
void touch_cancelled(sapp_touchpoint *touch, int n);
void input_dropped_files(int n);
void input_clipboard_paste(char *str);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,72 +1,7 @@
#ifndef FFI_H
#define FFI_H
#ifdef __cplusplus
extern "C" {
#endif
#include "quickjs.h"
#include "HandmadeMath.h"
#include <stdarg.h>
#include <chipmunk/chipmunk.h>
#include "qjs_macros.h"
void script_report_gc_time(double t, double startmem, double mem);
int JS_Is(JSValue v);
extern JSValue cpShape2js(cpShape *s);
void ffi_load();
JSValue vec22js(HMM_Vec2 v);
HMM_Vec2 js2vec2(JSValue v);
HMM_Vec4 js2vec4(JSValue v);
const char *js2str(JSValue v);
char *js2strdup(JSValue v);
JSValue bitmask2js(cpBitmask mask);
cpBitmask js2bitmask(JSValue v);
int js_print_exception(JSValue v);
struct rgba js2color(JSValue v);
double js2number(JSValue v);
JSValue number2js(double g);
uint64_t js2uint64(JSValue v);
JSValue str2js(const char *c, ...);
struct texture;
struct texture *js2texture(JSValue v);
void nota_int(char *blob);
void js_setprop_num(JSValue a, uint32_t n, JSValue v);
JSValue js_getpropidx(JSValue v, uint32_t i);
JSValue js_getpropstr(JSValue v, const char *str);
void jsfreestr(const char *str);
int js_arrlen(JSValue v);
void js_setpropstr(JSValue v, const char *str, JSValue p);
void js2floatarr(JSValue v, int n, float *a);
JSValue floatarr2js(int n, float *a);
float *js2newfloatarr(JSValue v);
int js2boolean(JSValue v);
JSValue boolean2js(int b);
char **js2strarr(JSValue v);
#define PREP_PARENT(TYPE, PARENT) \
TYPE##_proto = JS_NewObject(js); \
JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYPE##_funcs)); \
JS_SetPrototype(js, TYPE##_proto, PARENT##_proto); \
#ifdef __cplusplus
}
#endif
#include <quickjs.h>
void ffi_load(JSContext *js);
int js_print_exception(JSContext *js, JSValue v);
#endif

View File

@@ -1,117 +0,0 @@
#include "log.h"
#include "render.h"
#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include "yugine.h"
#include "resources.h"
#include "quickjs.h"
#include "script.h"
#ifdef __WIN32
#include "debugapi.h"
#endif
#define ESC "\033["
#define BLACK 30
#define RED 31
#define GREEN 32
#define YELLOW 33
#define BLUE 34
#define MAGENTA 35
#define CYAN 36
#define WHITE 37
#define COLOR(TXT, _C) ESC "22;" #_C "m" #TXT ESC "0m"
char *logstr[] = { "spam", "debug", "info", "warn", "error", "panic"};
char *logcolor[] = { COLOR(spam,37), COLOR(debug,32), COLOR(info,36), COLOR(warn,33), COLOR(error,31), COLOR(panic,45) };
char *catstr[] = {"engine", "script", "render"};
static FILE *logout; /* where logs are written to */
static FILE *writeout; /* where console is written to */
static FILE *dump; /* where data is dumped to */
int stdout_lvl = LOG_ERROR;
void log_init()
{
#ifndef NDEBUG
logout = fopen(".prosperon/log.txt", "w");
writeout = fopen(".prosperon/transcript.txt", "w");
dump = fopen(".prosperon/quickjs.txt", "w");
#endif
}
void log_shutdown()
{
fclose(logout);
fclose(writeout);
fclose(dump);
}
const char *logfmt = "%s:%d: [%s] %s, %s: ";
void mYughLog(int category, int priority, int line, const char *file, const char *message, ...)
{
#ifndef NDEBUG
time_t now = time(NULL);
struct tm *tinfo = localtime(&now);
char timebuf[80];
strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tinfo);
fprintf(logout, logfmt, file, line, timebuf, logstr[priority], catstr[category]);
va_list args;
va_start(args, message);
vfprintf(logout, message, args);
va_end(args);
fprintf(logout, "\n");
if (priority == LOG_DEBUG || priority >= stdout_lvl) {
printf(logfmt, file, line, timebuf, logcolor[priority], catstr[category]);
va_list args;
va_start(args,message);
vprintf(message, args);
va_end(args);
printf("\n");
}
if (priority >= LOG_PANIC) {
js_stacktrace();
#ifdef __WIN32
DebugBreak();
#else
raise(SIGTRAP);
#endif
}
#endif
}
/* print to stdout and console */
void log_print(const char *str)
{
#ifndef NDEBUG
fprintf(writeout, "%s", str);
#else
printf(str);
fflush(stdout);
#endif
}
void term_print(const char *str)
{
fprintf(stdout, "%s", str);
fflush(stdout);
}
void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uint32_t line, const char *file, void *data) {
lvl = LOG_PANIC-lvl;
mYughLog(LOG_RENDER, lvl, line, file, "tag: %s, id: %d, msg: %s", tag, id, msg);
}

View File

@@ -1,46 +0,0 @@
#ifndef LOG_H
#define LOG_H
#include <stdio.h>
#include <stdint.h>
#define LOG_SPAM 0
#define LOG_DEBUG 1
#define LOG_INFO 2
#define LOG_WARN 3
#define LOG_ERROR 4
#define LOG_PANIC 5
#define LOG_ENGINE 0
#define LOG_SCRIPT 1
#define LOG_RENDER 2
void log_init();
void log_shutdown();
extern int stdout_lvl;
#ifndef NDEBUG
#define YughLog(cat, pri, msg, ...) mYughLog(cat, pri, __LINE__, __FILE__, msg, ##__VA_ARGS__)
#define YughSpam(msg, ...) mYughLog(0, LOG_SPAM, __LINE__, __FILE__, msg, ##__VA_ARGS__);
#define YughInfo(msg, ...) mYughLog(0, LOG_INFO, __LINE__, __FILE__, msg, ##__VA_ARGS__);
#define YughWarn(msg, ...) mYughLog(0, LOG_WARN, __LINE__, __FILE__, msg, ##__VA_ARGS__);
#define YughError(msg, ...) mYughLog(0, LOG_ERROR, __LINE__, __FILE__, msg, ##__VA_ARGS__);
#define YughCritical(msg, ...) mYughLog(0, LOG_PANIC, __LINE__, __FILE__, msg, ##__VA_ARGS__);
#else
#define YughLog(cat, pri, msg, ...)
#define YughSpam(msg,...)
#define YughInfo(msg, ...)
#define YughWarn(msg, ...)
#define YughError(msg, ...)
#define YughCritical(msg, ...)
#endif
/* These log to the correct areas */
void mYughLog(int category, int priority, int line, const char *file, const char *message, ...);
void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uint32_t line, const char *file, void *data);
void log_print(const char *str);
void term_print(const char *str);
#endif

View File

@@ -1,7 +1,5 @@
#include "model.h"
#include "log.h"
#include "resources.h"
#include "stb_ds.h"
#include "gameobject.h"
@@ -268,7 +266,7 @@ skin *make_gltf_skin(cgltf_skin *skin, cgltf_data *data)
void skin_calculate(skin *sk)
{
animation_run(sk->anim, apptime());
// animation_run(sk->anim, apptime());
for (int i = 0; i < arrlen(sk->joints); i++) {
md5joint *md = sk->joints+i;
md->t = HMM_M4TRS(md->pos.xyz, md->rot, md->scale.xyz);

View File

@@ -91,10 +91,6 @@ static inline ImVec4 js2vec4(JSContext *js, JSValue v)
return c;
}
static int wantkeys = 0;
static int wantmouse = 0;
static inline JSValue vec22js(JSContext *js, ImVec2 vec)
{
JSValue v = JS_NewObject(js);
@@ -830,17 +826,14 @@ JSC_CCALL(imgui_endframe,
)
JSC_CCALL(imgui_wantmouse,
return JS_NewBool(js,wantmouse);
return JS_NewBool(js, ImGui::GetIO().WantCaptureMouse);
)
JSC_CCALL(imgui_wantkeys,
return JS_NewBool(js,wantkeys);
return JS_NewBool(js, ImGui::GetIO().WantCaptureKeyboard);
)
static int START=0;
JSC_CCALL(imgui_init,
if (START) return JS_UNDEFINED;
START = 1;
simgui_desc_t sdesc = {
.image_pool_size = 1024
};
@@ -963,9 +956,6 @@ extern "C" {
void gui_input(sapp_event *e)
{
simgui_handle_event(e);
ImGuiIO io = ImGui::GetIO();
wantkeys = io.WantCaptureKeyboard;
wantmouse = io.WantCaptureMouse;
}
JSValue js_imgui(JSContext *js)

View File

@@ -11,14 +11,14 @@
}
#define JSC_SCALL(NAME, ...) JSC_CCALL(NAME, \
const char *str = js2str(argv[0]); \
const char *str = JS_ToCString(js,argv[0]); \
__VA_ARGS__ ;\
JS_FreeCString(js,str); \
)
#define JSC_SSCALL(NAME, ...) JSC_CCALL(NAME, \
const char *str = js2str(argv[0]); \
const char *str2 = js2str(argv[1]); \
const char *str = JS_ToCString(js,argv[0]); \
const char *str2 = JS_ToCString(js,argv[1]); \
__VA_ARGS__ ; \
JS_FreeCString(js,str2); \
JS_FreeCString(js,str); \
@@ -35,35 +35,35 @@
#define JSC_DCALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(); return JS_UNDEFINED; }
#define JSC_1CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(argv[0])); return JS_UNDEFINED; }
#define JSC_2CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(argv[0]), js2number(argv[1])); return JS_UNDEFINED; }
#define JSC_3CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(argv[0]), js2number(argv[1]), js2number(argv[2])); return JS_UNDEFINED; }
#define JSC_4CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3])); return JS_UNDEFINED; }
#define JSC_5CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), js2number(argv[4])); return JS_UNDEFINED; }
#define JSC_6CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), js2number(argv[4]), js2number(argv[5])); return JS_UNDEFINED; }
#define JSC_7CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), js2number(argv[4]), js2number(argv[5]), js2number(argv[6])); return JS_UNDEFINED; }
#define JSC_1CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0])); return JS_UNDEFINED; }
#define JSC_2CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1])); return JS_UNDEFINED; }
#define JSC_3CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2])); return JS_UNDEFINED; }
#define JSC_4CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3])); return JS_UNDEFINED; }
#define JSC_5CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4])); return JS_UNDEFINED; }
#define JSC_6CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4]), js2number(js,argv[5])); return JS_UNDEFINED; }
#define JSC_7CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4]), js2number(js,argv[5]), js2number(js,argv[6])); return JS_UNDEFINED; }
#define GETSETPAIR(ID, ENTRY, TYPE, FN) \
JSValue js_##ID##_set_##ENTRY (JS_SETSIG) { \
js2##ID (self)->ENTRY = js2##TYPE (val); \
js2##ID (js, self)->ENTRY = js2##TYPE (js,val); \
{FN;} \
return JS_UNDEFINED; \
} \
\
JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \
return TYPE##2js(js2##ID (self)->ENTRY); \
return TYPE##2js(js,js2##ID (js, self)->ENTRY); \
} \
#define JSC_GETSET(ID, ENTRY, TYPE) GETSETPAIR( ID , ENTRY , TYPE , ; )
#define JSC_GETSET_APPLY(ID, ENTRY, TYPE) GETSETPAIR(ID, ENTRY, TYPE, ID##_apply(js2##ID (self));)
#define JSC_GETSET_APPLY(ID, ENTRY, TYPE) GETSETPAIR(ID, ENTRY, TYPE, ID##_apply(js2##ID (js, self));)
#define JSC_GETSET_CALLBACK(ID, ENTRY) \
JSValue js_##ID##_set_##ENTRY (JS_SETSIG) { \
JSValue fn = js2##ID (self)->ENTRY; \
JSValue fn = js2##ID (js, self)->ENTRY; \
if (!JS_IsUndefined(fn)) JS_FreeValue(js, fn); \
js2##ID (self)->ENTRY = JS_DupValue(js, val); \
js2##ID (js, self)->ENTRY = JS_DupValue(js, val); \
return JS_UNDEFINED; \
}\
JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { return JS_DupValue(js, js2##ID (self)->ENTRY); } \
JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { return JS_DupValue(js, js2##ID (js, self)->ENTRY); } \
#define JSC_GETSET_GLOBAL(ENTRY, TYPE) \
JSValue js_global_set_##ENTRY (JS_SETSIG) { \
@@ -75,21 +75,9 @@ JSValue js_global_get_##ENTRY (JSContext *js, JSValue self) { \
return TYPE##2js(ENTRY); \
} \
#define JSC_GETSET_BODY(ENTRY, CPENTRY, TYPE) \
JSValue js_gameobject_set_##ENTRY (JS_SETSIG) { \
cpBody *b = js2gameobject(self)->body; \
cpBodySet##CPENTRY (b, js2##TYPE (val)); \
return JS_UNDEFINED; \
} \
\
JSValue js_gameobject_get_##ENTRY (JSContext *js, JSValue self) { \
cpBody *b = js2gameobject(self)->body; \
return TYPE##2js (cpBodyGet##CPENTRY (b)); \
} \
#define JSC_GET(ID, ENTRY, TYPE) \
JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \
return TYPE##2js(js2##ID (self)->ENTRY); } \
return TYPE##2js(js,js2##ID (js, self)->ENTRY); } \
#define QJSCLASS(TYPE)\
static JSClassID js_##TYPE##_id;\
@@ -97,25 +85,25 @@ static int js_##TYPE##_count = 0; \
static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\
TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\
js_##TYPE##_count--; \
TYPE##_free(n);}\
TYPE##_free(rt,n);}\
static JSClassDef js_##TYPE##_class = {\
#TYPE,\
.finalizer = js_##TYPE##_finalizer,\
};\
TYPE *js2##TYPE (JSValue val) { \
TYPE *js2##TYPE (JSContext *js, JSValue val) { \
if (JS_IsUndefined(val)) return NULL; \
assert(JS_GetClassID(val) == js_##TYPE##_id); \
return JS_GetOpaque(val,js_##TYPE##_id); \
}\
JSValue TYPE##2js(TYPE *n) { \
JSValue TYPE##2js(JSContext *js, TYPE *n) { \
JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\
JS_SetOpaque(j,n);\
js_##TYPE##_count++; \
return j; }\
\
static JSValue js_##TYPE##_memid (JSContext *js, JSValue self) { return str2js("%p", js2##TYPE(self)); } \
static JSValue js_##TYPE##_memsize (JSContext *js, JSValue self) { return number2js(sizeof(TYPE)); } \
static JSValue js_##TYPE##__count (JSContext *js, JSValue self) { return number2js(js_##TYPE##_count); } \
static JSValue js_##TYPE##_memid (JSContext *js, JSValue self) { return JS_NewString(js,"p"); } \
static JSValue js_##TYPE##_memsize (JSContext *js, JSValue self) { return number2js(js,sizeof(TYPE)); } \
static JSValue js_##TYPE##__count (JSContext *js, JSValue self) { return number2js(js,js_##TYPE##_count); } \
#define QJSGLOBALCLASS(NAME) \
JSValue NAME = JS_NewObject(js); \
@@ -134,4 +122,9 @@ JS_SetPropertyStr(js, TYPE##_proto, "_count", JS_NewCFunction(js, &js_##TYPE##__
JS_SetPropertyStr(js, globalThis, #TYPE "_proto", JS_DupValue(js,TYPE##_proto)); \
JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \
#define PREP_PARENT(TYPE, PARENT) \
TYPE##_proto = JS_NewObject(js); \
JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYPE##_funcs)); \
JS_SetPrototype(js, TYPE##_proto, PARENT##_proto); \
#define countof(x) (sizeof(x)/sizeof((x)[0]))

View File

@@ -1,46 +1,14 @@
#include "render.h"
#include "config.h"
#include "datastream.h"
#include "font.h"
#include "gameobject.h"
#include "log.h"
#include "window.h"
#include "model.h"
#include "stb_ds.h"
#include "resources.h"
#include "yugine.h"
#include "sokol/sokol_app.h"
#define SOKOL_GLUE_IMPL
#include "sokol/sokol_glue.h"
#include "stb_image_write.h"
#include "sokol/sokol_gfx.h"
#include "sokol/sokol_glue.h"
#include "sokol/util/sokol_gl.h"
static HMM_Vec2 lastuse = {0};
HMM_Vec2 campos = {0,0};
float camzoom = 1;
viewstate globalview = {0};
sg_sampler std_sampler;
sg_sampler nofilter_sampler;
sg_sampler tex_sampler;
int TOPLEFT = 0;
sg_pass offscreen;
#include "sokol/sokol_app.h"
#include "HandmadeMath.h"
sg_pass_action pass_action = {0};
sg_pass_action off_action = {0};
sg_image screencolor = {0};
sg_image screendepth = {0};
sg_sampler std_sampler;
sg_sampler tex_sampler;
viewstate globalview = {0};
struct rfd {
int num_passes;
@@ -106,7 +74,6 @@ void trace_uninit_##NAME(sg_##NAME id, void *data) \
void trace_fail_##NAME(sg_##NAME id, void *data) \
{ \
sg_##NAME##_desc desc = sg_query_##NAME##_desc(id); \
YughError("Failed " #NAME " %d: %s", id, desc.label); \
} \
SG_TRACE_SET(buffer)
@@ -146,7 +113,7 @@ static sg_trace_hooks hooks = {
void render_init() {
sg_setup(&(sg_desc){
.environment = sglue_environment(),
.logger = { .func = sg_logging },
// .logger = { .func = sg_logging },
.buffer_pool_size = 1024,
.image_pool_size = 1024,
});
@@ -163,93 +130,6 @@ void render_init() {
.wrap_u = SG_WRAP_REPEAT,
.wrap_v = SG_WRAP_REPEAT
});
sg_features feat = sg_query_features();
TOPLEFT = feat.origin_top_left;
sg_color c = (sg_color){0,0,0,1};
pass_action = (sg_pass_action){
.colors[0] = {.load_action = SG_LOADACTION_CLEAR, .clear_value = c},
};
sg_color oc = (sg_color){35.0/255,60.0/255,92.0/255,1};
off_action = (sg_pass_action){
.colors[0] = {.load_action = SG_LOADACTION_CLEAR, .clear_value = oc},
.depth = {
.load_action = SG_LOADACTION_CLEAR,
.clear_value = 1
}
};
screencolor = sg_make_image(&(sg_image_desc){
.render_target = true,
.width = 500,
.height = 500,
.pixel_format = sapp_color_format(),
.sample_count = 1,
});
screendepth = sg_make_image(&(sg_image_desc){
.render_target = true,
.width =500,
.height=500,
.pixel_format = sapp_depth_format(),
.sample_count = 1
});
offscreen = (sg_pass){
.attachments = sg_make_attachments(&(sg_attachments_desc){
.colors[0].image = screencolor,
.depth_stencil.image = screendepth,
}),
.action = off_action,
};
}
HMM_Mat4 projection = {0.f};
HMM_Mat4 hudproj = {0.f};
HMM_Mat4 useproj = {0};
void openglRender(HMM_Vec2 usesize) {
if (usesize.x != lastuse.x || usesize.y != lastuse.y) {
sg_destroy_image(screencolor);
sg_destroy_image(screendepth);
sg_destroy_attachments(offscreen.attachments);
screencolor = sg_make_image(&(sg_image_desc){
.render_target = true,
.width = usesize.x,
.height = usesize.y,
.pixel_format = sapp_color_format(),
.sample_count = 1,
});
screendepth = sg_make_image(&(sg_image_desc){
.render_target = true,
.width =usesize.x,
.height=usesize.y,
.pixel_format = sapp_depth_format(),
.sample_count = 1
});
offscreen = (sg_pass){
.attachments = sg_make_attachments(&(sg_attachments_desc){
.colors[0].image = screencolor,
.depth_stencil.image = screendepth
}),
.action = off_action,
};
}
lastuse = usesize;
sg_begin_pass(&offscreen);
}
struct boundingbox cwh2bb(HMM_Vec2 c, HMM_Vec2 wh) {
struct boundingbox bb = {
.t = c.Y + wh.Y/2,
.b = c.Y - wh.Y/2,
.r = c.X + wh.X/2,
.l = c.X - wh.X/2
};
return bb;
}
float *rgba2floats(float *r, struct rgba c)

View File

@@ -1,34 +1,28 @@
#ifndef OPENGL_RENDER_H
#define OPENGL_RENDER_H
#include "config.h"
#if defined __linux__
#define SOKOL_GLCORE
#elif __EMSCRIPTEN__
#define SOKOL_WGPU
#elif __WIN32
#define SOKOL_D3D11
#elif __APPLE__
#define SOKOL_METAL
#endif
#include "sokol/sokol_gfx.h"
#include "HandmadeMath.h"
#include "gameobject.h"
#include "transform.h"
#include "model.h"
#define RGBA_MAX 255
#include "window.h"
extern struct rgba color_white;
extern struct rgba color_black;
extern struct rgba color_clear;
extern int TOPLEFT;
extern HMM_Vec3 dirl_pos;
extern HMM_Mat4 projection;
extern HMM_Mat4 hudproj;
extern HMM_Mat4 useproj;
extern sg_pass_action pass_action;
extern sg_sampler std_sampler;
extern sg_sampler tex_sampler;
extern sg_image screencolor;
extern sg_image screendepth;
typedef struct viewstate {
HMM_Mat4 v;
@@ -40,8 +34,6 @@ extern viewstate globalview;
void render_init();
void openglRender(HMM_Vec2 usesize);
void capture_screen(int x, int y, int w, int h, const char *path);
void gif_rec_start(int w, int h, int cpf, int bitdepth);
@@ -70,22 +62,13 @@ static inline rgba vec2rgba(HMM_Vec4 v) {
return (rgba){v.e[0]*255,v.e[1]*255,v.e[2]*255,v.e[3]*255};
}
struct boundingbox {
float t;
float b;
float r;
float l;
};
// rectangles are always defined with [x,y] in the bottom left
struct rect {
float x,y,w,h;
};
typedef struct rect rect;
struct boundingbox cwh2bb(HMM_Vec2 c, HMM_Vec2 wh);
float *rgba2floats(float *r, struct rgba c);
extern sg_blend_state blend_trans;
static inline float lerp(float f, float a, float b)
{

View File

@@ -1,219 +0,0 @@
#include "resources.h"
#include "config.h"
#include "log.h"
#include <dirent.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include "font.h"
#include <fcntl.h>
#ifndef __EMSCRIPTEN__
#include <ftw.h>
#endif
#include "sokol/sokol_fetch.h"
#include "stb_ds.h"
#if defined(_WIN32)
#include <direct.h>
#define mkdir(x,y) _mkdir(x)
#endif
char **prefabs;
static const char *cur_ext = NULL;
struct dirent *c_dirent = NULL;
char pathbuf[MAXPATH + 1];
void *os_slurp(const char *file, size_t *size)
{
FILE *f;
f = fopen(file, "rb");
if (!f) return NULL;
fseek(f, 0, SEEK_END);
size_t fsize = ftell(f);
rewind(f);
void *slurp = malloc(fsize);
fread(slurp, fsize, 1, f);
fclose(f);
if (size) *size = fsize;
return slurp;
}
#if defined(__linux__)
#include <unistd.h>
#include <stdio.h>
#elif defined(__APPLE__)
#include <mach-o/dyld.h>
#elif defined(_WIN32)
#include <windows.h>
#endif
int get_executable_path(char *buffer, unsigned int buffer_size) {
#if defined(__linux__)
ssize_t len = readlink("/proc/self/exe", buffer, buffer_size - 1);
if (len == -1) {
return 0;
}
buffer[len] = '\0';
return len;
#elif defined(__APPLE__)
if (_NSGetExecutablePath(buffer, &buffer_size) == 0) {
return buffer_size;
}
#elif defined(_WIN32)
return GetModuleFileName(NULL, buffer, buffer_size);
#endif
return 0;
}
void *gamedata;
static char *ext_paths = NULL;
#ifndef __EMSCRIPTEN__
static char **ls_paths = NULL;
static int ls_ftw(const char *path, const struct stat *sb, int typeflag)
{
if (typeflag == FTW_F && strlen(path) > 2)
arrpush(ls_paths, strdup(&path[2]));
return 0;
}
time_t file_mod_secs(const char *file) {
struct stat attr;
if (!stat(file,&attr))
return attr.st_mtime;
return -1;
}
// TODO: Not reentrant
char **ls(const char *path)
{
if (ls_paths) {
for (int i = 0; i < arrlen(ls_paths); i++)
free(ls_paths[i]);
arrfree(ls_paths);
}
ftw(path, ls_ftw, 10);
return ls_paths;
}
#else
void fill_extensions(char *paths, const char *path, const char *ext)
{};
char **ls(const char *path) { return NULL; }
void pack(const char *name, const char *dir) {}
#endif
char *str_replace_ext(const char *s, const char *newext) {
static char ret[256];
strncpy(ret, s, 256);
char *ext = strrchr(ret, '.');
strncpy(ext, newext, 10);
return ret;
}
void *slurp_file(const char *filename, size_t *size)
{
if (!access(filename, R_OK))
return os_slurp(filename, size);
}
char *slurp_text(const char *filename, size_t *size)
{
size_t len;
unsigned char *str = slurp_file(filename, &len);
if (!str) return NULL;
char *retstr = malloc(len+1);
memcpy(retstr, str, len);
retstr[len] = '\0';
free(str);
if (size) *size = len;
return retstr;
}
int cp(const char *p1, const char *p2)
{
size_t len;
void *data = slurp_file(p1, &len);
FILE *f = fopen(p2, "w");
if (!f) return 1;
fwrite(data, len, 1, f);
free(data);
fclose(f);
return 0;
}
int mkpath(char *path, mode_t mode)
{
char tmp[256];
char *p = NULL;
size_t len;
struct stat sb;
strncpy(tmp, path, sizeof(tmp));
len = strlen(tmp);
if (len > 0 && tmp[len - 1] == '/')
tmp[len - 1] = 0;
for (p = tmp + 1; *p; p++) {
if (*p == '/') {
*p = 0;
if (stat(tmp, &sb) != 0) {
if (errno != ENOENT || mkdir(tmp, mode) != 0) {
return -1;
}
} else if (!S_ISDIR(sb.st_mode)) {
errno = ENOTDIR;
return -1;
}
*p = '/';
}
}
if (stat(tmp, &sb) != 0) {
if (errno != ENOENT || mkdir(tmp, mode) != 0) {
return -1;
}
} else if (!S_ISDIR(sb.st_mode)) {
errno = ENOTDIR;
return -1;
}
return 0;
}
int slurp_write(void *txt, const char *filename, size_t len) {
FILE *f = fopen(filename, "w");
if (!f) return 1;
if (len < 0) len = strlen(txt);
fwrite(txt, len, 1, f);
fclose(f);
return 0;
}

View File

@@ -1,25 +0,0 @@
#ifndef RESOURCES_H
#define RESOURCES_H
#include <stdio.h>
#include "stb_ds.h"
#include "string.h"
#include <time.h>
extern char *DATA_PATH;
extern int LOADED_GAME;
char *str_replace_ext(const char *s, const char *newext);
FILE *res_open(char *path, const char *tag);
char **ls(const char *path);
int cp(const char *p1, const char *p2);
time_t file_mod_secs(const char *file);
void pack_start(const char *name);
void pack_add(const char *path);
void pack_end();
void *slurp_file(const char *filename, size_t *size);
char *slurp_text(const char *filename, size_t *size);
int slurp_write(void *txt, const char *filename, size_t len);
#endif

View File

@@ -1,18 +1,16 @@
#include "script.h"
#include "log.h"
#include "jsffi.h"
#include "stb_ds.h"
#include "resources.h"
#include <sokol/sokol_time.h>
#include <inttypes.h>
#include <limits.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdarg.h>
#include "jsffi.h"
JSContext *js = NULL;
JSRuntime *rt = NULL;
static JSContext *js = NULL;
static JSRuntime *rt = NULL;
#ifndef NDEBUG
#define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT
@@ -22,49 +20,35 @@ JSRuntime *rt = NULL;
static JSValue report_gc;
static uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename)
{
FILE *f;
uint8_t *buf;
size_t buf_len;
long lret;
char* read_file(const char* filename) {
// Open the file in read mode
FILE *file = fopen(filename, "r");
if (!file) {
perror("Failed to open file");
return NULL;
}
f = fopen(filename, "rb");
if (!f)
return NULL;
if (fseek(f, 0, SEEK_END) < 0)
goto fail;
lret = ftell(f);
if (lret < 0)
goto fail;
/* XXX: on Linux, ftell() return LONG_MAX for directories */
if (lret == LONG_MAX) {
errno = EISDIR;
goto fail;
}
buf_len = lret;
if (fseek(f, 0, SEEK_SET) < 0)
goto fail;
if (ctx)
buf = js_malloc(ctx, buf_len + 1);
else
buf = malloc(buf_len + 1);
if (!buf)
goto fail;
if (fread(buf, 1, buf_len, f) != buf_len) {
errno = EIO;
if (ctx)
js_free(ctx, buf);
else
free(buf);
fail:
fclose(f);
// Seek to the end of the file to get its size
fseek(file, 0, SEEK_END);
long file_size = ftell(file);
fseek(file, 0, SEEK_SET);
// Allocate memory for the file content, including the null terminator
char *content = (char*)malloc(file_size + 1);
if (!content) {
perror("Failed to allocate memory");
fclose(file);
return NULL;
}
buf[buf_len] = '\0';
fclose(f);
*pbuf_len = buf_len;
return buf;
// Read the entire file into the content buffer
fread(content, 1, file_size, file);
// Null-terminate the string
content[file_size] = '\0';
fclose(file);
return content;
}
void script_startup() {
@@ -83,41 +67,27 @@ void script_startup() {
JS_AddIntrinsicBigDecimal(js);
JS_AddIntrinsicOperators(js);
ffi_load();
ffi_load(js);
size_t len;
char *eng = slurp_text("engine.js", &len);
char *eng = read_file("engine.js");
JSValue v = script_eval("engine.js", eng);
JS_FreeValue(js, v);
free(eng);
}
static int stopped = 0;
void script_stop()
{
script_evalf("prosperon.quit();");
#ifndef LEAK
return;
#endif
script_gc();
return;
JS_FreeContext(js);
js = NULL;
JS_FreeRuntime(rt);
rt = NULL;
}
void script_gc() { JS_RunGC(rt); }
void script_mem_limit(size_t limit) { JS_SetMemoryLimit(rt, limit); }
void script_gc_threshold(size_t threshold) { JS_SetGCThreshold(rt, threshold); }
void script_max_stacksize(size_t size) { JS_SetMaxStackSize(rt, size); }
void js_stacktrace() {
if (!js) return;
#ifndef NDEBUG
script_evalf("console.stack();");
#endif
}
void script_evalf(const char *format, ...)
{
JSValue obj;
@@ -133,36 +103,20 @@ void script_evalf(const char *format, ...)
obj = JS_Eval(js, eval, len, "C eval", JS_EVAL_FLAGS);
free(eval);
js_print_exception(obj);
js_print_exception(js,obj);
JS_FreeValue(js,obj);
}
JSValue script_eval(const char *file, const char *script)
{
JSValue v = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAGS);
js_print_exception(v);
js_print_exception(js,v);
return v;
}
void script_call_sym(JSValue sym, int argc, JSValue *argv) {
if (!JS_IsFunction(js, sym)) return;
JSValue ret = JS_Call(js, sym, JS_UNDEFINED, argc, argv);
js_print_exception(ret);
js_print_exception(js,ret);
JS_FreeValue(js, ret);
}
JSValue script_call_sym_ret(JSValue sym, int argc, JSValue *argv) {
if (!JS_IsFunction(js, sym)) return JS_UNDEFINED;
JSValue ret = JS_Call(js, sym, JS_UNDEFINED, argc, argv);
return ret;
}
void out_memusage(const char *file)
{
FILE *f = fopen(file, "w");
if (!f) return;
JSMemoryUsage jsmem;
JS_ComputeMemoryUsage(rt, &jsmem);
JS_DumpMemoryUsage(f, &jsmem, rt);
fclose(f);
}

View File

@@ -1,44 +1,13 @@
#ifndef SCRIPT_H
#define SCRIPT_H
#ifdef __cplusplus
extern "C" {
#endif
#include "quickjs.h"
#include <time.h>
extern JSContext *js;
extern JSRuntime *rt;
struct phys_cbs {
JSValue begin;
JSValue bhit;
JSValue separate;
JSValue shit;
};
void script_startup();
void script_stop();
void out_memusage(const char *f);
void js_stacktrace();
void script_evalf(const char *format, ...);
JSValue script_eval(const char *file, const char *script);
void script_call_sym(JSValue sym, int argc, JSValue *argv);
JSValue script_call_sym_ret(JSValue sym, int argc, JSValue *argv);
void script_gc();
void script_mem_limit(size_t limit);
void script_gc_threshold(size_t threshold);
void script_max_stacksize(size_t size);
void _script_gcstart();
void _script_gcend();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,5 @@
#include "spline.h"
#include "stb_ds.h"
#include "log.h"
#include "transform.h"
#include "math.h"

View File

@@ -1,13 +1,11 @@
#include "texture.h"
#include "log.h"
#include "render.h"
#include "sokol/sokol_gfx.h"
#include <math.h>
#include <stb_image.h>
#include <stb_image_write.h>
#include "resources.h"
#include <string.h>
#include "stb_image_resize2.h"
@@ -159,62 +157,7 @@ void texture_offload(texture *tex)
}
}
/* If an empty string or null is put for path, loads default texture */
struct texture *texture_from_file(const char *path) {
if (!path) return NULL;
size_t rawlen;
unsigned char *raw = slurp_file(path, &rawlen);
if (!raw) return NULL;
unsigned char *data;
struct texture *tex = calloc(1, sizeof(*tex));
int n;
char *ext = strrchr(path, '.');
if (!strcmp(ext, ".qoi")) {
qoi_desc qoi;
data = qoi_decode(raw, rawlen, &qoi, 4);
tex->width = qoi.width;
tex->height = qoi.height;
n = qoi.channels;
} else if (!strcmp(ext, ".svg")) {
#ifndef NSVG
NSVGimage *svg = nsvgParse(raw, "px", 96);
struct NSVGrasterizer *rast = nsvgCreateRasterizer();
n=4;
tex->width=100;
tex->height=100;
float scale = tex->width/svg->width;
data = malloc(tex->width*tex->height*n);
nsvgRasterize(rast, svg, 0, 0, scale, data, tex->width, tex->height, tex->width*n);
free(svg);
free(rast);
#else
YughWarn("Prosperon was built without SVG capabilities.");
return;
#endif
} else {
data = stbi_load_from_memory(raw, rawlen, &tex->width, &tex->height, &n, 4);
}
free(raw);
if (data == NULL) {
free(tex);
return NULL;
}
tex->data = data;
return tex;
}
void texture_free(texture *tex)
void texture_free(JSRuntime *rt, texture *tex)
{
if (!tex) return;
if (tex->data)
@@ -498,3 +441,35 @@ void texture_load_gpu(texture *tex)
sg_update_image(tex->id, &img_data);
}
}
sapp_icon_desc texture2icon(texture *tex)
{
sapp_icon_desc desc = {0};
if (!tex->data) return desc;
struct isize {
int size;
unsigned char *data;
};
struct isize sizes[4];
sizes[0].size = 16;
sizes[1].size = 32;
sizes[2].size = 64;
sizes[3].size = 128;
for (int i = 0; i < 4; i++) {
sizes[i].data = malloc(4*sizes[i].size*sizes[i].size);
stbir_resize_uint8_linear(tex->data, tex->width, tex->height, 0, sizes[i].data, sizes[i].size, sizes[i].size, 0, 4);
}
desc = (sapp_icon_desc){
.images = {
{ .width = sizes[0].size, .height = sizes[0].size, .pixels = { .ptr=sizes[0].data, .size=4*sizes[0].size*sizes[0].size } },
{ .width = sizes[1].size, .height = sizes[1].size, .pixels = { .ptr=sizes[1].data, .size=4*sizes[1].size*sizes[1].size } },
{ .width = sizes[2].size, .height = sizes[2].size, .pixels = { .ptr=sizes[2].data, .size=4*sizes[2].size*sizes[2].size } },
{ .width = sizes[3].size, .height = sizes[3].size, .pixels = { .ptr=sizes[3].data, .size=4*sizes[3].size*sizes[3].size } },
}
};
return desc;
}

View File

@@ -4,6 +4,7 @@
#include "sokol/sokol_gfx.h"
#include "HandmadeMath.h"
#include "render.h"
#include <quickjs.h>
#include "stb_rect_pack.h"
@@ -42,13 +43,12 @@ typedef struct img_sampler{
int mip_filter;
} img_sampler;
texture *texture_from_file(const char *path);
texture *texture_fromdata(void *raw, long size);
texture *texture_empty(int width, int height); // Make an empty texture
texture *texture_dup(texture *tex); // return an identical texture
texture *texture_scale(texture *tex, int width, int height); // dup and scale the texture
void texture_free(texture *tex);
void texture_free(JSRuntime *rt,texture *tex);
void texture_offload(texture *tex); // Remove the data from this texture
void texture_load_gpu(texture *tex); // Upload this data to the GPU if it isn't already there. Replace it if it is.
@@ -58,6 +58,8 @@ int texture_fill_rect(texture *tex, struct rect rect, struct rgba color);
int texture_blit(texture *dst, texture *src, struct rect dstrect, struct rect srcrect, int tile); // copies src into dst, using their respective squares, scaling if necessary
int texture_flip(texture *tex, int y);
sapp_icon_desc texture2icon(texture *tex);
void texture_save(texture *tex, const char *file); // save the texture data to the given file
#endif

View File

@@ -4,7 +4,7 @@
timer **timers;
timer *timer_make(JSValue fn)
timer *timer_make(JSContext *js, JSValue fn)
{
timer *t = calloc(sizeof(*t),1);
t->fn = JS_DupValue(js,fn);
@@ -12,7 +12,7 @@ timer *timer_make(JSValue fn)
return t;
}
void timer_free(timer *t)
void timer_free(JSRuntime *rt, timer *t)
{
for (int i = 0; i < arrlen(timers); i++) {
if (timers[i] == t) {
@@ -21,12 +21,12 @@ void timer_free(timer *t)
}
}
JS_FreeValue(js, t->fn);
JS_FreeValueRT(rt, t->fn);
free(t);
}
void timer_update(double dt)
void timer_update(JSContext *js, double dt)
{
for (int i = 0; i < arrlen(timers); i++) {
if (timers[i]->remain <= 0) continue;

View File

@@ -7,8 +7,8 @@ typedef struct timer {
JSValue fn;
} timer;
timer *timer_make(JSValue fn);
void timer_free(timer *t);
void timer_update(double dt);
timer *timer_make(JSContext *js, JSValue fn);
void timer_free(JSRuntime *rt, timer *t);
void timer_update(JSContext *js, double dt);
#endif

View File

@@ -12,10 +12,8 @@ transform *make_transform()
return t;
}
void transform_free(transform *t) { free(t); }
void transform_free(JSRuntime *rt, transform *t) { free(t); }
void transform_apply(transform *t) { t->dirty = 1; }
void transform_move(transform *t, HMM_Vec3 v)
{
t->pos = HMM_AddV3(t->pos, v);

View File

@@ -2,6 +2,7 @@
#define TRANSFORM_H
#include "HandmadeMath.h"
#include <quickjs.h>
typedef struct transform {
HMM_Vec3 pos;
@@ -13,7 +14,7 @@ typedef struct transform {
transform *make_transform();
void transform_apply(transform *t);
void transform_free(transform *t);
void transform_free(JSRuntime *rt,transform *t);
#define VEC2_FMT "[%g,%g]"
#define VEC2_MEMS(s) (s).x, (s).y

View File

@@ -1,6 +1,5 @@
#include "warp.h"
#include "stb_ds.h"
#include "log.h"
static warp_gravity **warps = NULL;

View File

@@ -1,97 +0,0 @@
#include "window.h"
#include "input.h"
#include "log.h"
#include "script.h"
#include "texture.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jsffi.h"
#include "render.h"
#include "stb_ds.h"
#include "sokol/sokol_app.h"
#include "stb_image_resize2.h"
struct window mainwin = {
.sample_count = 1,
.vsync = 1,
.enable_clipboard = 0,
.enable_dragndrop = 0,
};
static struct window *windows = NULL;
struct texture *icon = NULL;
void window_resize(int width, int height)
{
script_evalf("prosperon.resize([%d,%d]);", width,height);
}
void window_focused(int focus)
{
mainwin.focus = focus;
script_evalf("prosperon.focus(%d);", focus);
}
void window_iconified(int s)
{
mainwin.iconified = s;
script_evalf("prosperon.iconified(%d);", s);
}
void window_suspended(int s)
{
script_evalf("prosperon.suspended(%d);", s);
}
void window_setfullscreen(window *w, int f)
{
if (w->fullscreen == f) return;
w->fullscreen = f;
if (!w->start) return;
if (sapp_is_fullscreen() == f) return;
sapp_toggle_fullscreen();
}
void window_seticon(struct window *w, struct texture *tex)
{
if (!tex->data) return;
struct isize {
int size;
unsigned char *data;
};
struct isize sizes[4];
sizes[0].size = 16;
sizes[1].size = 32;
sizes[2].size = 64;
sizes[3].size = 128;
for (int i = 0; i < 4; i++) {
sizes[i].data = malloc(4*sizes[i].size*sizes[i].size);
stbir_resize_uint8_linear(tex->data, tex->width, tex->height, 0, sizes[i].data, sizes[i].size, sizes[i].size, 0, 4);
}
sapp_icon_desc idsc = {
.images = {
{ .width = sizes[0].size, .height = sizes[0].size, .pixels = { .ptr=sizes[0].data, .size=4*sizes[0].size*sizes[0].size } },
{ .width = sizes[1].size, .height = sizes[1].size, .pixels = { .ptr=sizes[1].data, .size=4*sizes[1].size*sizes[1].size } },
{ .width = sizes[2].size, .height = sizes[2].size, .pixels = { .ptr=sizes[2].data, .size=4*sizes[2].size*sizes[2].size } },
{ .width = sizes[3].size, .height = sizes[3].size, .pixels = { .ptr=sizes[3].data, .size=4*sizes[3].size*sizes[3].size } },
}
};
sapp_set_icon(&idsc);
for (int i = 0; i < 4; i++)
free(sizes[i].data);
}
void window_free(window *w)
{
}

View File

@@ -1,39 +0,0 @@
#ifndef WINDOW_H
#define WINDOW_H
#include <HandmadeMath.h>
struct window {
double dpi;
int render;
int mouseFocus;
int keyboardFocus;
int fullscreen;
int minimized;
int iconified;
int focus;
int shown;
char *title;
int vsync;
int enable_clipboard;
int enable_dragndrop;
int high_dpi;
int sample_count;
int start;
};
typedef struct window window;
struct texture;
extern struct window mainwin;
void window_resize(int width, int height);
void window_focused(int focus);
void window_iconified(int s);
void window_suspended(int s);
void window_apply(window *w);
void window_free(window *w);
void window_setfullscreen(window *w, int f);
void window_seticon(struct window *w, struct texture *icon);
#endif

View File

@@ -1,200 +1,10 @@
#include "yugine.h"
#include "input.h"
#include "render.h"
#include "window.h"
#include <stdio.h>
#include <wctype.h>
#include "script.h"
#include <string.h>
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
script_startup(); // runs engine.js
#include <signal.h>
#include <time.h>
#include "string.h"
#include "render.h"
#include "sokol/sokol_app.h"
#include "sokol/sokol_audio.h"
#include "sokol/sokol_time.h"
#include "sokol/sokol_args.h"
#include <stb_ds.h>
#include <stb_truetype.h>
#include "stb_image.h"
#include "stb_image_write.h"
static int argc;
static char **args;
static JSValue c_start;
static JSValue c_process_fn;
static int PLAYSTART = 0;
void c_init() {
mainwin.start = 1;
window_resize(sapp_width(), sapp_height());
render_init();
if (!JS_IsUndefined(c_start)) {
script_call_sym(c_start,0,NULL);
JS_FreeValue(js, c_start);
}
}
void c_frame() {
script_call_sym(c_process_fn,0,NULL);
}
void cleanup()
{
out_memusage(".prosperon/jsmem.txt");
script_stop();
}
void seghandle()
{
js_stacktrace();
cleanup();
exit(1);
}
void c_clean() {
JS_FreeValue(js, c_process_fn);
cleanup();
sg_shutdown();
};
void gui_input(sapp_event *e);
void c_event(const sapp_event *e)
{
#ifndef NEDITOR
gui_input(e);
#endif
char lcfmt[5];
switch (e->type) {
case SAPP_EVENTTYPE_MOUSE_MOVE:
script_evalf("prosperon.mousemove([%g, %g], [%g, %g]);", e->mouse_x, e->mouse_y, e->mouse_dx, e->mouse_dy);
break;
case SAPP_EVENTTYPE_MOUSE_SCROLL:
script_evalf("prosperon.mousescroll([%g, %g]);", e->scroll_x, e->scroll_y);
break;
case SAPP_EVENTTYPE_KEY_DOWN:
script_evalf("prosperon.keydown(%d, %d);", e->key_code, e->key_repeat);
break;
case SAPP_EVENTTYPE_KEY_UP:
script_evalf("prosperon.keyup(%d);", e->key_code);
break;
case SAPP_EVENTTYPE_MOUSE_UP:
script_evalf("prosperon.mouseup(%d);", e->mouse_button);
break;
case SAPP_EVENTTYPE_MOUSE_DOWN:
script_evalf("prosperon.mousedown(%d);", e->mouse_button);
break;
case SAPP_EVENTTYPE_CHAR:
if (iswcntrl(e->char_code)) break;
snprintf(lcfmt, 5, "%lc", e->char_code);
script_evalf("prosperon.textinput(`%s`);", lcfmt);
break;
case SAPP_EVENTTYPE_RESIZED:
window_resize(e->window_width, e->window_height);
break;
case SAPP_EVENTTYPE_ICONIFIED:
window_iconified(1);
break;
case SAPP_EVENTTYPE_RESTORED:
window_iconified(0);
break;
case SAPP_EVENTTYPE_FOCUSED:
window_focused(1);
break;
case SAPP_EVENTTYPE_UNFOCUSED:
window_focused(0);
break;
case SAPP_EVENTTYPE_SUSPENDED:
window_suspended(1);
break;
case SAPP_EVENTTYPE_QUIT_REQUESTED:
quit();
break;
case SAPP_EVENTTYPE_FILES_DROPPED:
input_dropped_files(sapp_get_num_dropped_files());
break;
case SAPP_EVENTTYPE_MOUSE_ENTER:
script_evalf("prosperon.mouseenter();");
break;
case SAPP_EVENTTYPE_MOUSE_LEAVE:
script_evalf("prosperon.mouseleave();");
break;
case SAPP_EVENTTYPE_TOUCHES_BEGAN:
touch_start(e->touches, e->num_touches);
break;
case SAPP_EVENTTYPE_TOUCHES_MOVED:
touch_move(e->touches, e->num_touches);
break;
case SAPP_EVENTTYPE_TOUCHES_ENDED:
touch_end(e->touches, e->num_touches);
break;
case SAPP_EVENTTYPE_TOUCHES_CANCELLED:
touch_cancelled(e->touches, e->num_touches);
break;
case SAPP_EVENTTYPE_CLIPBOARD_PASTED:
input_clipboard_paste(sapp_get_clipboard_string());
break;
default:
break;
}
}
static sapp_desc start_desc = {
.width = 720,
.height = 1080,
.high_dpi = 0,
.sample_count = 1,
.swap_interval = 0,
.fullscreen = 1,
.window_title = NULL,
.enable_clipboard = false,
.clipboard_size = 0,
.enable_dragndrop = true,
.max_dropped_files = 1,
.max_dropped_file_path_length = 2048,
.init_cb = c_init,
.frame_cb = c_frame,
.cleanup_cb = c_clean,
.event_cb = c_event,
.win32_console_create = false,
.logger.func = sg_logging
};
sapp_desc sokol_main(int argc, char **argv) {
#ifndef NDEBUG
log_init();
signal(SIGSEGV, seghandle);
signal(SIGABRT, seghandle);
signal(SIGFPE, seghandle);
#endif
stm_setup(); /* time */
script_startup();
#ifndef __EMSCRIPTEN__
int argsize = 0;
for (int i = 0; i < argc; i++) {
argsize += strlen(argv[i]);
@@ -208,36 +18,8 @@ sapp_desc sokol_main(int argc, char **argv) {
strcat(cmdstr, argv[i]);
if (argc > i+1) strcat(cmdstr, " ");
}
printf("evaling: %s\n", cmdstr);
script_evalf("cmd_args('%s');", cmdstr);
#endif
return start_desc;
}
void engine_start(JSValue start, JSValue procfn, float x, float y)
{
c_start = JS_DupValue(js,start);
c_process_fn = JS_DupValue(js,procfn);
start_desc.width = x;
start_desc.height = y;
start_desc.window_title = mainwin.title;
start_desc.fullscreen = mainwin.fullscreen;
start_desc.swap_interval = mainwin.vsync;
start_desc.enable_dragndrop = mainwin.enable_dragndrop;
start_desc.enable_clipboard = mainwin.enable_clipboard;
start_desc.high_dpi = mainwin.high_dpi;
start_desc.sample_count = mainwin.sample_count;
}
double apptime() { return stm_sec(stm_now()); }
void quit() {
if (mainwin.start)
sapp_quit();
else {
cleanup();
exit(0);
}
return 0;
}

View File

@@ -3,11 +3,6 @@
#include "script.h"
double apptime();
void print_stacktrace();
void engine_start(JSValue start_fn, JSValue proc_fn, float x, float y); /* fn runs after the engine starts */
void quit();
void engine_start(JSContext *js, JSValue start_fn, JSValue proc_fn, float x, float y); /* fn runs after the engine starts */
#endif