core.zip is now bundled into prosperon executables

This commit is contained in:
2025-02-01 21:16:38 -06:00
parent 8a41899c5d
commit 14feeb0c16
9 changed files with 192 additions and 78 deletions

View File

@@ -144,18 +144,45 @@ foreach folder: zip_folders
zip_paths += meson.project_source_root() / folder
endforeach
# Now use the hash file as a dependency so that any change in the files causes a rebuild.
core = custom_target('core.zip',
output:'core.zip',
command: ['zip', '-r', '-j', '@OUTPUT@'] + zip_paths,
output : 'core.zip',
command : ['sh', '-c',
'cd ' + meson.project_source_root() +
' && echo "Rebuilding core.zip" && ' +
'zip -r ' + meson.current_build_dir() + '/core.zip scripts fonts icons shaders'
],
build_always : true,
build_by_default: true
)
prosperon = executable('prosperon', sources,
prosperon_raw = executable('prosperon_raw', sources,
dependencies: deps,
include_directories: includers,
link_args: link,
build_rpath: '$ORIGIN',
install:true,
install_dir:'bin'
install:false
)
if host_machine.system() == 'windows'
exe_ext = '.exe'
else
exe_ext = ''
endif
prosperon = custom_target('prosperon',
output: 'prosperon' + exe_ext,
input: [prosperon_raw, core],
command: [
'sh', '-c',
'cat "$1" "$2" > "$3"',
'concat',
'@INPUT0@',
'@INPUT1@',
'@OUTPUT@'
],
build_always: true,
build_by_default: true
)
prosperon_dep = declare_dependency(

View File

@@ -69,8 +69,6 @@ Cmdline.register_order(
Cmdline.register_order(
"play",
function (argv) {
if (argv[0]) io.chdir(argv[0]);
var app
if (io.exists("main.js"))
app = actor.spawn("main.js", {}, function(underling, msg) {

View File

@@ -54,13 +54,10 @@ Object.defineProperty(Function.prototype, "hashify", {
});
var io = use_embed('io')
io.mount("core/scripts")
io.mount("core/scripts/modules")
io.mount("core")
var canonical = io.realdir('resources.js') + 'resources.js'
var content = io.slurp('resources.js')
var resources = js.eval('resources.js', `(function setup_resources(){${content}})`).call({})
var canonical = io.realdir('scripts/resources.js') + 'resources.js'
var content = io.slurp('scripts/resources.js')
var resources = js.eval('scripts/resources.js', `(function setup_resources(){${content}})`).call({})
console.print(resources.canonical('resources.js'))
use_cache[resources.canonical('resources.js')] = resources
@@ -76,10 +73,31 @@ function print_api(obj) {
}
}
prosperon.PATH = [
"/",
"scripts/",
"scripts/modules/"
]
function find_in_path(filename, exts = []) {
for (var dir of prosperon.PATH) {
var candidate = dir + filename;
if (io.exists(candidate)) return candidate;
for (var ext of exts) {
candidate = dir + filename + ext;
if (io.exists(candidate)) return candidate;
}
}
return undefined;
}
// path is the path of a module or script to resolve
var script_fn = function script_fn(path) {
var parsed = {}
var file = resources.find_script(path);
var file = resources.find_script(find_in_path(path, ['.js', '.jsc']));
if (!file) {
// attempt to bare load
parsed.module_ret = bare_load(path);
@@ -177,8 +195,6 @@ console.log = function(msg)
pprint(msg, 2)
}
console.log(io.searchpath())
console.error = function(e) {
if (!e)
e = new Error();
@@ -211,10 +227,10 @@ console.doc = {
clear: "Clear console.",
};
var script = io.slurp("core/scripts/base.js")
var script = io.slurp("scripts/base.js")
var fnname = "base"
script = `(function ${fnname}() { ${script}; })`
js.eval('core/scripts/base.js', script)()
js.eval('scripts/base.js', script)()
function add_timer(obj, fn, seconds)
{
@@ -535,4 +551,3 @@ actor[UNDERLINGS] = new Set()
globalThis.mixin("color");
use('cmd')(prosperon.argv)

View File

@@ -63,6 +63,14 @@ sprite_pipeline.blend = {
op_alpha: "add"
};
sprite_pipeline.target = {
color_targets: [{
format:"rgba8",
blend:sprite_pipeline.blend
}],
depth: "d32 float s8"
};
var sprite = {
image: undefined,
@@ -251,14 +259,16 @@ sprite.inputs.kp1 = function () {
var tree = graphics.make_rtree()
sprite.tree = tree;
var IN = Symbol()
sprite.t_hook = function() {
var msp = this.sprite._sprite;
if (this.__in)
if (this[IN])
tree.delete(msp);
msp.rect = this.torect()
msp.set_affine(this)
tree.add(msp)
this.__in = true
this[IN] = true
}
Object.mixin(sprite,use("transform"))
@@ -297,3 +307,4 @@ this._sprite = msp;
msp.color = Color.white;
this.transform.sprite = this

View File

@@ -433,7 +433,7 @@ var pass;
var pass = cmds.render_pass(camera.target);
var camera = prosperon.camera;
var pipeline;
var pipeline ;
var mesh;
var img;
var modelslot;
@@ -779,7 +779,6 @@ std_sampler = render._main.make_sampler({
address_mode_w: "repeat"
});
io.mount("core");
render._main.present = gpupresent;
imgui.init(render._main, prosperon.window);
tracy.gpu_init()

View File

@@ -287,7 +287,6 @@ render.device = {
render.device.doc = `Device resolutions given as [x,y,inches diagonal].`;
var std_sampler;
render.init = function () {
io.mount("core");
// var ducky = render._main.load_gltf_model("Duck.glb");
// console.log(json.encode(ducky))
var sprite_vert = make_shader("sprite.vert", true,0,0,0,1);

View File

@@ -1762,19 +1762,19 @@ shader_globals camera_globals(JSContext *js, JSValue camera)
shader_globals data = {0};
HMM_Vec2 size;
transform *transform;
double fov;
double aspect;
double fov = 0;
double aspect = 0;
int ortho;
double near;
double far;
double near_z = 0;
double far_z = 0;
JS_GETPROP(js, size, camera, size, vec2)
JS_GETPROP(js, transform, camera, transform, transform)
JS_GETPROP(js, fov, camera, fov, number)
JS_GETPROP(js, aspect, camera, aspect, number)
JS_GETPROP(js, ortho, camera,ortho,bool)
JS_GETPROP(js,near,camera,near,number)
JS_GETPROP(js,far,camera,far,number)
JS_GETPROP(js,near_z,camera,near_z,number)
JS_GETPROP(js,far_z,camera,far_z,number)
HMM_Mat4 proj;
HMM_Mat4 view;
@@ -1788,7 +1788,7 @@ shader_globals camera_globals(JSContext *js, JSValue camera)
view = HMM_Translate((HMM_Vec3){ -transform->pos.x, -transform->pos.y, 0.0f });
}
else {
proj = HMM_Perspective_RH_NO(fov, aspect,near,far);
proj = HMM_Perspective_RH_NO(fov, aspect,near_z,far_z);
HMM_Mat4 camera_transform = HMM_Translate(transform->pos);
camera_transform = HMM_MulM4(camera_transform, HMM_QToM4(transform->rotation));
@@ -1800,8 +1800,8 @@ shader_globals camera_globals(JSContext *js, JSValue camera)
data.world_to_projection = HMM_MulM4(proj, view);
data.projection_to_world = HMM_InvGeneralM4(data.world_to_projection);
data.camera_pos_world = transform->pos;
data.viewport_min_z = near;
data.viewport_max_z = far;
data.viewport_min_z = near_z;
data.viewport_max_z = far_z;
data.render_size = size;
data.world_to_view = view;
data.view_to_projection = proj;
@@ -5835,7 +5835,7 @@ JSC_SCALL(io_slurpwrite,
)
JSC_SSCALL(io_mount,
if (!PHYSFS_mount(str,str2,0)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
if (!PHYSFS_mount(str,str2,0)) ret = JS_ThrowReferenceError(js,"Unable to mount %s at %s: %s", str, str2, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
)
JSC_SCALL(io_unmount,

View File

@@ -1,12 +1,100 @@
#include "script.h"
#include "physfs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
static unsigned char *zip_buffer_global;
void free_zip(void)
{
free(zip_buffer_global);
}
int main(int argc, char **argv) {
printf("%s\n", argv[0]);
FILE *f = fopen(argv[0], "rb");
if (!f) { perror("fopen"); return 1; }
if (fseek(f, 0, SEEK_END) != 0) { perror("fseek"); fclose(f); return 1; }
long size = ftell(f);
if (size < 0) { perror("ftell"); fclose(f); return 1; }
zip_buffer_global = malloc(size);
if (!zip_buffer_global) { perror("malloc"); fclose(f); return 1; }
rewind(f);
if (fread(zip_buffer_global, 1, size, f) != (size_t)size) {
perror("fread");
free(zip_buffer_global);
fclose(f);
return 1;
}
fclose(f);
// Search backwards for the EOCD signature "PK\x05\x06".
// The EOCD record is at most 0xFFFF (65535) bytes plus 22 bytes long.
long max_comment_len = 0xFFFF;
long eocd_search_start = (size > (max_comment_len + 22)) ? (size - (max_comment_len + 22)) : 0;
long eocd_pos = -1;
for (long i = size - 22; i >= eocd_search_start; i--) {
if (zip_buffer_global[i] == 'P' &&
zip_buffer_global[i + 1] == 'K' &&
zip_buffer_global[i + 2] == 0x05 &&
zip_buffer_global[i + 3] == 0x06) {
eocd_pos = i;
break;
}
}
if (eocd_pos < 0) {
fprintf(stderr, "EOCD not found\n");
free(zip_buffer_global);
return 1;
}
// Parse the EOCD record.
// EOCD record layout (without the comment):
// Offset 0: 4 bytes signature ("PK\x05\x06")
// Offset 4: 2 bytes disk number
// Offset 6: 2 bytes disk with central directory
// Offset 8: 2 bytes number of central dir records on this disk
// Offset 10:2 bytes total number of central dir records
// Offset 12:4 bytes size of central directory (cd_size)
// Offset 16:4 bytes offset of start of central directory (cd_offset_rel, relative to zip start)
// Offset 20:2 bytes comment length
uint16_t comment_length = zip_buffer_global[eocd_pos + 20] |
(zip_buffer_global[eocd_pos + 21] << 8);
int eocd_size = 22 + comment_length;
uint32_t cd_size = zip_buffer_global[eocd_pos + 12] |
(zip_buffer_global[eocd_pos + 13] << 8) |
(zip_buffer_global[eocd_pos + 14] << 16) |
(zip_buffer_global[eocd_pos + 15] << 24);
uint32_t cd_offset_rel = zip_buffer_global[eocd_pos + 16] |
(zip_buffer_global[eocd_pos + 17] << 8) |
(zip_buffer_global[eocd_pos + 18] << 16) |
(zip_buffer_global[eocd_pos + 19] << 24);
// The size of the appended zip archive is given by:
// appended_zip_size = (offset of central directory + size of central directory + EOCD record size)
// Since the EOCD record is the last part of the zip archive,
// we can compute the start of the zip archive (zip_offset) as:
uint32_t appended_zip_size = cd_offset_rel + cd_size + eocd_size;
long zip_offset = size - appended_zip_size;
if (zip_offset < 0 || zip_offset >= size) {
fprintf(stderr, "Invalid zip offset computed: %ld\n", zip_offset);
free(zip_buffer_global);
return 1;
}
printf("Zip data found at offset %ld, appended zip size %u bytes\n",
zip_offset, appended_zip_size);
PHYSFS_init(argv[0]);
char *base = PHYSFS_getBaseDir();
PHYSFS_setWriteDir(base);
PHYSFS_mount(base,NULL,0);
PHYSFS_mount(base,"/",0);
PHYSFS_mount(base, NULL, 0);
PHYSFS_mount(base, "/", 0);
int ret = PHYSFS_mountMemory(zip_buffer_global + zip_offset, appended_zip_size, free_zip,
"core.zip", "/", 0);
if (!ret) printf("COULD NOT MOUNT! Reason: %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
script_startup(argc, argv); // runs engine.js
return 0;
}

View File

@@ -10,6 +10,8 @@
#include <stdlib.h>
#include <assert.h>
#include "physfs.h"
static JSContext *js = NULL;
static JSRuntime *rt = NULL;
@@ -23,44 +25,6 @@ JSValue on_exception = JS_UNDEFINED;
#define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT | JS_EVAL_FLAG_STRIP
#endif
static JSValue report_gc;
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;
}
// 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;
}
// 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;
}
int js_interrupt(JSRuntime *rt, void *data)
{
// printf("INTERRUPT\n");
}
void script_startup(int argc, char **argv) {
rt = JS_NewRuntime();
js = JS_NewContextRaw(rt);
@@ -78,9 +42,19 @@ void script_startup(int argc, char **argv) {
JS_AddIntrinsicOperators(js);
ffi_load(js, argc, argv);
char *eng = read_file("core/scripts/engine.js");
JSValue v = script_eval(js, "core/scripts/engine.js", eng);
PHYSFS_File *eng = PHYSFS_openRead("scripts/engine.js");
if (!eng) {
printf("Could not open file! %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
return;
}
PHYSFS_Stat stat;
PHYSFS_stat("scripts/engine.js", &stat);
void *data = malloc(stat.filesize);
PHYSFS_readBytes(eng,data,stat.filesize);
PHYSFS_close(eng);
JSValue v = script_eval(js, "scripts/engine.js", data);
uncaught_exception(js,v);
free(eng);
}
@@ -109,11 +83,14 @@ void uncaught_exception(JSContext *js, JSValue v)
JS_FreeValue(js,ex);
} else {
JSValue ex = JS_GetException(js);
const char *strex = JS_ToCString(js,ex);
JSValue stack = JS_GetPropertyStr(js,ex,"stack");
const char *st = JS_ToCString(js,stack);
printf("Unhandled exception:\n%s\n", st);
printf("Unhandled exception: %s\n%s\n", strex, st);
JS_FreeValue(js,stack);
JS_FreeValue(js,ex);
JS_FreeCString(js,st);
JS_FreeCString(js,strex);
}
JS_FreeValue(js,v);