10 REM === THE DARK MESH GAUNTLET: IMMORTAL SERVER ===
20 PRINT ">>> Kaynnistetaan Gauntlet (Headless mode)..."
22 JS DEFINE "headless" "function() { state.host.draw = null;
state.host.initDisplay = null; return 'OK'; }"
24 JS CALL "headless" INTO DUMMY
30 WEBSERVE PORT 9090 INTO HTTP_SERVER
40 WEBSERVE ADD "/" TO HTTP_SERVER FROM FS "/mnt/mesh_root/src/x-mesh-basic/vfb
_client.html"
50 WEBSERVE LINK VFB TO HTTP_SERVER ON "/stream"
60 WEBSERVE LINK OMEGA TO HTTP_SERVER ON "/input" INTO "ch_input"
70 SCREEN 176, 184
80 SETGRAVITY 0
90 REM --- TASKULASKIN: Pelaajan liikelogiikka ---
100 JS DEFINE "calc_move" "function(px, py, key, speed) { if(key==='W')
py-=speed; if(key==='S') py+=speed; if(key==='A') px-=speed; if(key==='D')
px+=speed; return {x:px, y:py}; }"
102 JS DEFINE "check_hit" "function(x1,y1,x2,y2,d) { return (x2>0 &&
Math.abs(x1-x2)<d && Math.abs(y1-y2)<d) ? 1 : 0; }"
104 JS DEFINE "calc_ai" "function(ex,ey,px,py,s) { if(ex<px) ex+=s; else
if(ex>px) ex-=s; if(ey<py) ey+=s; else if(ey>py) ey-=s; return {x:ex, y:ey};
}"
110 REM --- KARTTA & HAHMO ---
120 RESTORE 1000
130 MAPGEN "ASCII", ROWS 23
140 SPRITE 1, "WARRIOR"
150 LET PX = 102 : LET PY = 44
160 MOVE SPRITE 1, PX, PY
162 SPRITE 2, "GHOST"
164 LET EX = 152 : LET EY = 152
166 MOVE SPRITE 2, EX, EY
170 LET SPEED = 4
172 LET SCORE = 0
174 LET HP = 100
176 LET GOLD_X = 136 : LET GOLD_Y = 24
178 LET DID_MOVE = 0 : LET FORCE_DRAW = 1
180 REM --- HOT-SWAP ANKKURI ---
190 JS DEFINE "getpid" "function() { return process.pid; }"
200 JS CALL "getpid" INTO PID
210 PRINT ">>> Gauntlet on LIVE! Pelaa: http://localhost:9090"
215 BUFFER BLIT SCREEN
220 PRINT ">>> PID lennosta-paivittamista varten: " + PID
230 ON SIGNAL "SIGHUP" GOTO 9000
300 REM --- GAME LOOP ---
310 REM Liikkumisen tila sC$ilyy ylempC$nC$ render-on-demandiC$ varten
320 OMEGA POLL "ch_input" INTO REQ WITH TIMEOUT 0
330 IF REQ == "" THEN GOTO 500
340 IF REQ["action"] != "DOWN" THEN GOTO 500
350 LET KEY = REQ["code"]
360 REM 1. Lasketaan uusi sijainti JS-taskulaskimessa
370 JS CALL "calc_move" WITH PX, PY, KEY, SPEED INTO NEW_POS
380 MOVE SPRITE 1, NEW_POS["x"], NEW_POS["y"]
390 LET DID_MOVE = 1
500 REM 2. Paivitetaan fysiikat
502 WAIT VBLANK
504 IF DID_MOVE != 0 THEN GOTO 512
506 IF FORCE_DRAW != 0 THEN GOTO 512
508 GOTO 300
512 DRAWTEXT 4, 175, "SCORE " + SCORE, 2
513 DRAWTEXT 120, 175, "HP " + HP, 255
514 IF GOLD_X > 0 THEN FILLRECT GOLD_X, GOLD_Y, 6, 6, 2
515 REM -- Ohitetaan liikkeiden tormaystarkistukset jos vain piirrettiin --
516 IF DID_MOVE == 0 THEN GOTO 570
530 REM 3. Tarkistetaan tormays
540 CHECKCOLLISION 1 INTO COL
550 IF COL == -1 THEN MOVE SPRITE 1, PX, PY : GOTO 570
560 LET PX = NEW_POS["x"] : LET PY = NEW_POS["y"]
562 REM --- 3.1 Tarkistetaan osuttiinko kultaan ---
566 JS CALL "check_hit" WITH PX, PY, GOLD_X, GOLD_Y, 8 INTO HIT
568 IF HIT == 1 THEN LET SCORE = SCORE + 100 : LET GOLD_X = -100
569 REM --- 3.2 Vihollisen vuoro ---
570 JS CALL "calc_ai" WITH EX, EY, PX, PY, 4 INTO ENEMY_POS
571 LET EX = ENEMY_POS["x"] : LET EY = ENEMY_POS["y"]
572 MOVE SPRITE 2, EX, EY
573 JS CALL "check_hit" WITH PX, PY, EX, EY, 8 INTO DMG_HIT
574 IF DMG_HIT == 1 THEN LET HP = HP - 10 : LET SCORE = SCORE - 10
575 IF HP <= 0 THEN PRINT ">>> Pelaaja kuoli! GAME OVER! <<<" : HALT
576 REM 4. Piirretaan ruutu ja jatketaan
580 BUFFER BLIT SCREEN
585 LET DID_MOVE = 0 : LET FORCE_DRAW = 0
590 GOTO 300
1000 REM --- LEVEL 1 ASCII MAP (22 Saraketta x 23 Rivia) ---
1010 DATA "######################"
1020 DATA "#....................#"
1030 DATA "#..####........####..#"
1040 DATA "#..#..#........#..#..#"
1050 DATA "#..#..#........#..#..#"
1060 DATA "#..####...##...####..#"
1070 DATA "#.........##.........#"
1080 DATA "#######........#######"
1090 DATA "#....................#"
1100 DATA "#....................#"
1110 DATA "#######........#######"
1120 DATA "#.........##.........#"
1130 DATA "#..####...##...####..#"
1140 DATA "#..#..#........#..#..#"
1150 DATA "#..#..#........#..#..#"
1160 DATA "#..####........####..#"
1170 DATA "#....................#"
1180 DATA "#....................#"
1190 DATA "#..################..#"
1200 DATA "#..#..............#..#"
1210 DATA "#..#..............#..#"
1220 DATA "#....................#"
1230 DATA "######################"
9000 REM --- HOT-SWAP KASITTELIJA ---
9010 PRINT ">>> [HOT-SWAP] Taikajuoma juotu (Speed 8) & Uusi kulta spawnaa!
<<<"
9020 LET SPEED = 8
9030 LET GOLD_X = 24 : LET GOLD_Y = 136
9040 LET FORCE_DRAW = 1
9050 GOTO 300
[+] COMMIT VALMIS: /mnt/mesh_root/src/x-mesh-basic/demos/gauntlet.bas
user@hauki-obs:/mnt/mesh_root/src/x-mesh-basic$ x-mesh-basic demos/gauntlet.bas
B &
[2] 3244089
user@hauki-obs:/mnt/mesh_root/src/x-mesh-basic$ [MOD] Ladataan: M-BUS
(Technology-Agnostic Message Bus) & SUSPEND
[MOD] Ladataan: Asynchronous SLEEP
[MOD] Ladataan: VIC-20 Emulator / Hardware Hooks (64KB)
>>> Kaynnistetaan Gauntlet (Headless mode)...
[JS] Rutiini asennettu muistiin: headless
[HOST-AGNOSTIC] SCREEN alustettu muistiin: 176x184
[JS] Rutiini asennettu muistiin: calc_move
[JS] Rutiini asennettu muistiin: check_hit
[JS] Rutiini asennettu muistiin: calc_ai
[DATA] RESTORE: Siirretty riville 1000
[JS] Rutiini asennettu muistiin: getpid
>>> Gauntlet on LIVE! Pelaa: http://localhost:9090
>>> PID lennosta-paivittamista varten: 3244089
[*] SIGNAL HANDLER rekisteroity: SIGHUP -> GOTO 9000
kill -HUP 3244089
user@hauki-obs:/mnt/mesh_root/src/x-mesh-basic$B
[!] SIGNAL SIGHUP VASTAANOTETTU! Keskeytetaan ja hypataan riville 9000
>>> [HOT-SWAP] Taikajuoma juotu (Speed 8) & Uusi kulta spawnaa! <<<
kill -HUP 3244089
user@hauki-obs:/mnt/mesh_root/src/x-mesh-basic$B
[!] SIGNAL SIGHUP VASTAANOTETTU! Keskeytetaan ja hypataan riville 9000
>>> [HOT-SWAP] Taikajuoma juotu (Speed 8) & Uusi kulta spawnaa! <<<