refactor; remove many unnecessary files and normalize data ingestion as buffer arrays
This commit is contained in:
@@ -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']
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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.",
|
||||
};
|
||||
|
||||
|
||||
@@ -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}`);
|
||||
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.",
|
||||
);
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "anim.h"
|
||||
#include "log.h"
|
||||
#include "stb_ds.h"
|
||||
|
||||
void animation_run(struct animation *anim, float now)
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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
|
||||
1723
source/jsffi.c
1723
source/jsffi.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
117
source/log.c
117
source/log.c
@@ -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);
|
||||
}
|
||||
46
source/log.h
46
source/log.h
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]))
|
||||
|
||||
132
source/render.c
132
source/render.c
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
118
source/script.c
118
source/script.c
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "spline.h"
|
||||
#include "stb_ds.h"
|
||||
#include "log.h"
|
||||
#include "transform.h"
|
||||
#include "math.h"
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "warp.h"
|
||||
#include "stb_ds.h"
|
||||
#include "log.h"
|
||||
|
||||
static warp_gravity **warps = NULL;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -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
|
||||
232
source/yugine.c
232
source/yugine.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user