From 09f48d08b908d7c3f89e7db119c8bfa1f833b281 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Wed, 28 May 2025 17:49:37 -0500 Subject: [PATCH] update chess to use moth --- examples/chess/main.js | 103 ++++++++++++++++-------------- scripts/core/engine.js | 3 + scripts/modules/cmd.js | 21 ++++++ scripts/modules/moth.js | 138 ---------------------------------------- scripts/moth.js | 18 +++--- source/prosperon.c | 2 - source/qjs_os.c | 12 ---- source/qjs_sdl.c | 5 -- 8 files changed, 88 insertions(+), 214 deletions(-) delete mode 100644 scripts/modules/moth.js diff --git a/examples/chess/main.js b/examples/chess/main.js index 1621c8ba..13a8fe8c 100644 --- a/examples/chess/main.js +++ b/examples/chess/main.js @@ -1,22 +1,18 @@ /* main.js – runs the demo with your prototype-based grid */ -var moth = use('moth', $_.delay) var json = use('json') +var os = use('os') +var draw2d = use('draw2d') -var res = 160 -var internal_res = 480 +var input = use('input') -moth.initialize({ width:res, height:res, resolution_x:internal_res, resolution_y:internal_res, mode:'letterbox' }); - -var os = use('os'); -var draw2d = use('draw2d'); -var gfx = use('graphics'); +input.watch($_) /*──── import our pieces + systems ───────────────────────────────────*/ -var Grid = use('grid'); // your new ctor -var MovementSystem = use('movement').MovementSystem; -var startingPos = use('pieces').startingPosition; -var rules = use('rules'); +var Grid = use('examples/chess/grid'); // your new ctor +var MovementSystem = use('examples/chess/movement').MovementSystem; +var startingPos = use('examples/chess/pieces').startingPosition; +var rules = use('examples/chess/rules'); /*──── build board ───────────────────────────────────────────────────*/ var grid = new Grid(8, 8); @@ -55,7 +51,7 @@ function updateTitle() { break; } - prosperon.window.title = title + console.log(title) } // Initialize title @@ -70,7 +66,7 @@ var opponentMousePos = null; var opponentHoldingPiece = false; var opponentSelectPos = null; -prosperon.on('mouse_button_down', function(e) { +function handleMouseButtonDown(e) { if (e.which !== 0) return; // Don't allow piece selection unless we have an opponent @@ -96,9 +92,9 @@ prosperon.on('mouse_button_down', function(e) { } else { selectPos = null; } -}) +} -prosperon.on('mouse_button_up', function(e) { +function handleMouseButtonUp(e) { if (e.which !== 0 || !holdingPiece || !selectPos) return; // Don't allow moves unless we have an opponent and it's our turn @@ -139,9 +135,9 @@ prosperon.on('mouse_button_up', function(e) { type: 'piece_drop' }); } -}) +} -prosperon.on('mouse_motion', function(e) { +function handleMouseMotion(e) { var mx = e.pos.x; var my = e.pos.y; @@ -162,7 +158,18 @@ prosperon.on('mouse_motion', function(e) { selectPos: selectPos }); } -}) +} + +function handleKeyDown(e) { + // S key - start server + if (e.scancode === 22 && gameState === 'waiting') { // S key + startServer(); + } + // J key - join server + else if (e.scancode === 13 && gameState === 'waiting') { // J key + joinServer(); + } +} /*──── drawing helpers ───────────────────────────────────────────────*/ /* ── constants ─────────────────────────────────────────────────── */ @@ -193,7 +200,8 @@ function drawBoard() { draw2d.rectangle( { x: x*S, y: y*S, width: S, height: S }, - { thickness: 0, color: color } + { thickness: 0 }, + { color: color } ); } } @@ -235,7 +243,7 @@ function drawPieces() { var r = { x: piece.coord[0]*S, y: piece.coord[1]*S, width:S, height:S }; - draw2d.image(piece.sprite, r, 0, [0,0], [0,0], {mode:"nearest"}); + draw2d.image(piece.sprite, r); }); // Draw the held piece at the mouse position if we're holding one @@ -245,7 +253,7 @@ function drawPieces() { var r = { x: hoverPos[0]*S, y: hoverPos[1]*S, width:S, height:S }; - draw2d.image(piece.sprite, r, 0, [0,0], [0,0], {mode:"nearest"}); + draw2d.image(piece.sprite, r); } } @@ -257,29 +265,25 @@ function drawPieces() { width:S, height:S }; // Draw with slight transparency to show it's the opponent's piece - draw2d.image(opponentPiece.sprite, r, 0, [0,0], [0,0], {mode:"nearest", color: [1, 1, 1, 0.7]}); + draw2d.image(opponentPiece.sprite, r); } } } -var graphics = use('graphics') +function update(dt) +{ + return {} +} -prosperon.on('draw', function() { +function draw() +{ + draw2d.clear() drawBoard() drawPieces() - draw2d.text("HELL", [100,100]) -}) + draw2d.text("HELL", {x: 100, y: 100}, 'fonts/c64.ttf', 16, [1,1,1,1]) + return draw2d.get_commands() +} -prosperon.on('key_down', function(e) { - // S key - start server - if (e.scancode === 22 && gameState === 'waiting') { // S key - startServer(); - } - // J key - join server - else if (e.scancode === 13 && gameState === 'waiting') { // J key - joinServer(); - } -}) function startServer() { gameState = 'server_waiting'; @@ -327,17 +331,12 @@ function joinServer() { var os = use('os') -var sdl = use('sdl') - -var ioguy = sdl.ioguy() - -send(ioguy, { - type: "subscribe", - actor: $_ -}); - $_.receiver(e => { - if (e.type === 'game_start' || e.type === 'move' || e.type === 'greet') + if (e.kind == 'update') + send(e, update(e.dt)) + else if (e.kind == 'draw') + send(e, draw()) + else if (e.type === 'game_start' || e.type === 'move' || e.type === 'greet') console.log("Receiver got message:", e.type, e); if (e.type === 'quit') os.exit() @@ -392,7 +391,13 @@ $_.receiver(e => { // Opponent dropped their piece opponentHoldingPiece = false; opponentSelectPos = null; + } else if (e.type === 'mouse_button_down') { + handleMouseButtonDown(e) + } else if (e.type === 'mouse_button_up') { + handleMouseButtonUp(e) + } else if (e.type === 'mouse_motion') { + handleMouseMotion(e) + } else if (e.type === 'key_down') { + handleKeyDown(e) } - - prosperon.dispatch(e.type, e) }) \ No newline at end of file diff --git a/scripts/core/engine.js b/scripts/core/engine.js index a5926653..417598c3 100644 --- a/scripts/core/engine.js +++ b/scripts/core/engine.js @@ -572,6 +572,9 @@ cmd.process(prosperon.argv.slice()) if (!prosperon.args.id) prosperon.id = util.guid() else prosperon.id = prosperon.args.id +// Make remaining arguments available as global 'args' variable +globalThis.args = prosperon.args.remaining || [] + $_.__ACTORDATA__.id = prosperon.id function turn(msg) diff --git a/scripts/modules/cmd.js b/scripts/modules/cmd.js index f8c1a0cc..41e4d4e8 100644 --- a/scripts/modules/cmd.js +++ b/scripts/modules/cmd.js @@ -162,6 +162,27 @@ Cmdline.register_order( prosperon.args = parse_args(argv) if (!prosperon.args.cwd) prosperon.args.cwd = '.' io.mount(prosperon.args.cwd) + + // Store all remaining non-flag arguments + var remaining_args = [] + var skip_next = false + for (var i = 0; i < argv.length; i++) { + if (skip_next) { + skip_next = false + continue + } + if (argv[i].startsWith("--")) { + // Check if this flag has a value + if (i + 1 < argv.length && !argv[i + 1].startsWith("--")) { + skip_next = true + } + continue + } + remaining_args.push(argv[i]) + } + + // Add remaining arguments to prosperon.args + prosperon.args.remaining = remaining_args if (!prosperon.args.program) os.exit() diff --git a/scripts/modules/moth.js b/scripts/modules/moth.js deleted file mode 100644 index 8df19cb7..00000000 --- a/scripts/modules/moth.js +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Moth Game Framework - * Higher-level game development framework built on top of Prosperon - */ - -// Check if we received the required delay function -if (!arg || arg.length === 0 || typeof arg[0] !== 'function') { - throw new Error("moth module requires $_.delay function as first argument. Usage: use('moth', $_.delay)"); -} - -// Verify it's actually a delay function by checking if it has the expected behavior -var delay = arg[0]; -if (!delay.name || (delay.name !== 'delay' && !delay.name.includes('delay'))) { - console.warn("Warning: The function passed to moth module may not be $_.delay"); -} - -var os = use('os'); -var io = use('io'); -var transform = use('transform'); - -var draw2d -var graphics - -var video_actor = use('sdl_video') - -var window -var render - -var gameConfig = arg[1] || {}; - -send(video_actor, { - kind: "window", - op:"create", - data: gameConfig -}, e => { - if (e.error) { - console.error(e.error) - os.exit(1) - } - - window = e.id - - send(video_actor,{ - kind:"window", - op:"makeRenderer", - id:window - }, e => { - if (e.error) { - console.error(e.error) - os.exit(1) - } - - render = e.id - draw2d = use('draw2d', video_actor, render) - graphics = use('graphics', video_actor, render) - }) -}) - -function loop() -{ - -} - -$_.delay(loop, 1/60) - - -// Initialize render system -render.initialize({ - width: gameConfig.resolution.width, - height: gameConfig.resolution.height, - resolution_x: gameConfig.internal_resolution.width, - resolution_y: gameConfig.internal_resolution.height, - mode: gameConfig.mode || 'letterbox' -}); - -// Set up default camera -gameConfig.camera = gameConfig.camera || { - size: [gameConfig.internal_resolution.width, gameConfig.internal_resolution.height], - transform: new transform, - fov: 50, - near_z: 0, - far_z: 1000, - surface: undefined, - viewport: {x: 0, y: 0, width: 1, height: 1}, - ortho: true, - anchor: [0, 0] -}; - -// Set window title -prosperon.window.title = gameConfig.title; - -startGameLoop(); - -// Main game loop -function startGameLoop() { - var last = os.now(); - var fpsTimer = 0; - var fpsCount = 0; - var targetFrameTime = 1 / gameConfig.fps; - - function loop() { - var now = os.now(); - var dt = now - last; - last = now; - - // Dispatch update event - prosperon.dispatch('update', dt); - - // Clear and set up rendering - render.clear(gameConfig.clearColor); - render.camera(gameConfig.camera); - - // Dispatch draw event - prosperon.dispatch('draw'); - - // Present the frame - render.present(); - - // FPS counter - fpsTimer += dt; - fpsCount++; - if (fpsTimer >= 0.5) { - // Only update if the title wasn't changed by the game - if (prosperon.window.title === gameConfig.title) { - prosperon.window.title = `${gameConfig.title} - FPS ${(fpsCount / fpsTimer).toFixed(1)}`; - } - fpsTimer = fpsCount = 0; - } - - // Schedule next frame - delay(loop, Math.max(0, targetFrameTime - (os.now() - now))); - } - - loop(); -} - -// Public API -return {} \ No newline at end of file diff --git a/scripts/moth.js b/scripts/moth.js index 049a1b5d..166ec349 100644 --- a/scripts/moth.js +++ b/scripts/moth.js @@ -55,11 +55,6 @@ var camera = { var util = use('util') var cammy = util.camera_globals(camera) -console.log(cammy) - -var sq = {x:50,y:30,height:300,width:100} -console.log(json.encode(sq)) -console.log(json.encode(worldToScreenRect(sq, camera, 500, 500))) var graphics @@ -68,11 +63,20 @@ var render var gameactor +var dir = args[0] + +if (!io.exists(args[0] + '/main.js')) + throw Error(`No main.js found in ${args[0]}`) + +console.log('starting game in ' + dir) + +io.mount(dir) + $_.start(e => { if (gameactor) return gameactor = e.actor loop() -}, 'tests/prosperon.js') +}, args[0] + "/main.js") send(video_actor, { kind: "window", @@ -254,8 +258,6 @@ function loop() var dt = now - last last = now -// camera.pos = camera.pos.map(x => x += 5*dt) - // Update the game send(gameactor, {kind:'update', dt:dt}, e => { // Get draw commands from game diff --git a/source/prosperon.c b/source/prosperon.c index 3fffd651..c0395476 100644 --- a/source/prosperon.c +++ b/source/prosperon.c @@ -667,8 +667,6 @@ void script_startup(prosperon_rt *prt, void (*hook)(JSContext*)) JS_AddIntrinsicRegExp(js); JS_AddIntrinsicJSON(js); JS_AddIntrinsicMapSet(js); - JS_AddIntrinsicTypedArrays(js); - JS_AddIntrinsicWeakRef(js); JS_AddIntrinsicProxy(js); JS_SetContextOpaque(js, prt); diff --git a/source/qjs_os.c b/source/qjs_os.c index 7589cc73..cf8de024 100644 --- a/source/qjs_os.c +++ b/source/qjs_os.c @@ -170,17 +170,6 @@ static JSValue js_os_version(JSContext *js, JSValue self, int argc, JSValue *arg return ret; } -JSValue js_os_get_trace(JSContext *js, JSValue self) -{ - return JS_NewBool(js, trace); -} - -JSValue js_os_set_trace(JSContext *js, JSValue self, JSValue value) -{ - trace = JS_ToBool(js, value); - return JS_UNDEFINED; -} - JSC_CCALL(os_on, prosperon_rt *rt = JS_GetContextOpaque(js); JS_FreeValue(js, rt->on_exception); @@ -301,7 +290,6 @@ static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, freemem, 0), MIST_FUNC_DEF(os, hostname, 0), MIST_FUNC_DEF(os, version, 0), - JS_CGETSET_DEF("trace", js_os_get_trace, js_os_set_trace), MIST_FUNC_DEF(os, exit, 1), MIST_FUNC_DEF(os, now, 0), MIST_FUNC_DEF(os, power_state, 0), diff --git a/source/qjs_sdl.c b/source/qjs_sdl.c index 20a46b11..02aacb36 100644 --- a/source/qjs_sdl.c +++ b/source/qjs_sdl.c @@ -115,11 +115,6 @@ static const JSCFunctionListEntry js_input_funcs[] = { JSValue js_input_use(JSContext *js) { JSValue mod = JS_NewObject(js); JS_SetPropertyFunctionList(js,mod,js_input_funcs,countof(js_input_funcs)); - - // Initialize SDL cursor class (no functions) - JSValue c_types = JS_GetPropertyStr(js, JS_GetGlobalObject(js), "c_types"); - JS_FreeValue(js, c_types); - return mod; }