├── .editorconfig
├── .gitignore
├── Gulpfile.js
├── Gulpfile.json
├── README.md
├── compile
├── minify.bat
└── minify.sh
├── data
├── congrat.png
├── control_left.png
├── control_right.png
├── control_sleft.png
├── control_sright.png
├── haf.png
├── sprites.png
├── tiles.png
└── title.png
├── include
├── control.js
├── draw.js
├── e_bomb.js
├── e_bullet.js
├── e_rick.js
├── ents.js
├── game.js
├── maps.js
├── rects.js
├── screens.js
├── scroller.js
├── sprites.js
├── system.js
└── tiles.js
├── index.html
├── package-lock.json
├── package.json
├── sound
├── bombshht.mp3
├── bombshht.ogg
├── bombshht.wav
├── bonus.mp3
├── bonus.ogg
├── bonus.wav
├── box.mp3
├── box.ogg
├── box.wav
├── bullet.mp3
├── bullet.ogg
├── bullet.wav
├── crawl.mp3
├── crawl.ogg
├── crawl.wav
├── die.mp3
├── die.ogg
├── die.wav
├── ent0.mp3
├── ent0.ogg
├── ent0.wav
├── ent1.mp3
├── ent1.ogg
├── ent1.wav
├── ent2.mp3
├── ent2.ogg
├── ent2.wav
├── ent3.mp3
├── ent3.ogg
├── ent3.wav
├── ent4.mp3
├── ent4.ogg
├── ent4.wav
├── ent5.mp3
├── ent5.ogg
├── ent5.wav
├── ent6.mp3
├── ent6.ogg
├── ent6.wav
├── ent7.mp3
├── ent7.ogg
├── ent7.wav
├── ent8.mp3
├── ent8.ogg
├── ent8.wav
├── explode.mp3
├── explode.ogg
├── explode.wav
├── gameover.mp3
├── gameover.ogg
├── gameover.wav
├── jump.mp3
├── jump.ogg
├── jump.wav
├── pad.mp3
├── pad.ogg
├── pad.wav
├── sbonus1.mp3
├── sbonus1.ogg
├── sbonus1.wav
├── sbonus2.mp3
├── sbonus2.ogg
├── sbonus2.wav
├── stick.mp3
├── stick.ogg
├── stick.wav
├── tune0.mp3
├── tune0.ogg
├── tune0.wav
├── tune1.mp3
├── tune1.ogg
├── tune1.wav
├── tune2.mp3
├── tune2.ogg
├── tune2.wav
├── tune3.mp3
├── tune3.ogg
├── tune3.wav
├── tune4.mp3
├── tune4.ogg
├── tune4.wav
├── tune5.mp3
├── tune5.ogg
├── tune5.wav
├── walk.mp3
├── walk.ogg
└── walk.wav
├── source
├── control.js
├── dat_ents.js
├── dat_maps.js
├── dat_screens.js
├── dat_spritesST.js
├── draw.js
├── e_bomb.js
├── e_bonus.js
├── e_box.js
├── e_bullet.js
├── e_rick.js
├── e_sbonus.js
├── e_them.js
├── ents.js
├── game.js
├── maps.js
├── rects.js
├── scr_gameover.js
├── scr_getname.js
├── scr_imain.js
├── scr_imap.js
├── scr_pause.js
├── scr_xrick.js
├── screens.js
├── scroller.js
├── sysarg.js
├── sysevt.js
├── syssnd.js
├── system.js
├── sysvid.js
├── template.js
├── tiles.js
├── util.js
├── xrick.debug.js
└── xrick.js
├── src
├── c.js
├── control.js
├── dat_ents.js
├── dat_loader.js
├── dat_maps.js
├── dat_picST.js
├── dat_screens.js
├── dat_snd.js
├── dat_spritesST.js
├── dat_tilesST.js
├── draw.js
├── e_bomb.js
├── e_bonus.js
├── e_box.js
├── e_bullet.js
├── e_rick.js
├── e_sbonus.js
├── e_them.js
├── ents.js
├── game.js
├── maps.js
├── rects.js
├── scr_gameover.js
├── scr_getname.js
├── scr_imain.js
├── scr_imap.js
├── scr_pause.js
├── scr_xrick.js
├── scroller.js
├── sysarg.js
├── sysevt.js
├── syssnd.js
├── system.js
├── sysvid.js
├── util.js
└── xrick.js
└── xrick.html
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | indent_style = tab
3 | indent_size = 2
4 | end_of_line = lf
5 | charset = utf-8
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 |
9 | [{*.json,.babelrc,.tern-project}]
10 | indent_style = space
11 | indent_size = 2
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | *sublime*
3 | *.min.*
4 | *.jar
5 | .DS_Store
6 | temp/
7 | tools/
8 | compile/old/
9 | compile/*.js
10 | compile/*.jar
11 | test/
12 | build/
13 | TODO.TXT
14 |
--------------------------------------------------------------------------------
/Gulpfile.js:
--------------------------------------------------------------------------------
1 | const config = require("./Gulpfile.json");
2 |
3 | const gulp = require("gulp");
4 | const webpack = require('webpack-stream');
5 | var del = require('del');
6 |
7 | // Tasks
8 | gulp.task("webpack", () => {
9 | return gulp.src("src/xrick.js")
10 | .pipe(webpack({
11 | mode: "development",
12 | output: {
13 | library: "RickJS",
14 | filename: "xrick.debug.js"
15 | }
16 | }))
17 | .pipe(gulp.dest(config.dir.build));
18 | });
19 |
20 | gulp.task('clean', () => {
21 | return del(config.dir.clean);
22 | });
23 |
24 | gulp.task("build-web", gulp.series("clean", "webpack"));
25 |
--------------------------------------------------------------------------------
/Gulpfile.json:
--------------------------------------------------------------------------------
1 | {
2 | "dir": {
3 | "build": "build/",
4 | "clean": [
5 | "build/"
6 | ]
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | RickJS
2 | ======
3 |
4 | A JavaScript port of XRick
5 |
6 | Based on xrick - version #021212
7 |
8 | Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net)
9 | Copyright (C) 2012 Chrilith (me@chrilith.com)
10 |
11 | http://www.bigorno.net/xrick/
12 | http://www.gamalto.com/games/rickjs/
13 |
14 |
15 | LICENSE AGREEMENT & LEGAL BABLE
16 | ===============================
17 |
18 | From the original author of xrick:
19 |
20 | I have written the xrick code. However, graphics and maps and sounds
21 | are by the authors of the original Rick Dangerous game, and "Rick
22 | Dangerous" remains a trademark of its owner(s) -- maybe Core Design
23 | (who wrote the game) or FireBird (who published it). As of today, I
24 | have not been successful at contacting Core Design.
25 |
26 | This makes it a bit difficult to formally release the whole code,
27 | including data for graphics and maps and sounds, under the terms of
28 | licences such as the GNU General Public Licence. So the code is
29 | released "in the spirit" of the GNU GPL. Whatever that means.
30 |
31 | This program is distributed in the hope that it will be useful, but
32 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33 | or FITNESS FOR A PARTICULAR PURPOSE.
34 |
35 |
36 | HOWTO
37 | =====
38 |
39 | Controls:
40 |
41 | - left, right, up (jump) or down (crawl): arrow keys.
42 | - fire: SPACE, pause: P.
43 | - use left, right, up, down + fire to poke something with your stick,
44 | lay a stick of dynamite, or fire a bullet.
45 |
46 | More details at http://www.bigorno.net/xrick/ and http://www.gamalto.com/
47 |
48 | Report problems, or ask questions, to me@chrilith.com.
49 |
50 | Enjoy!
51 |
--------------------------------------------------------------------------------
/compile/minify.bat:
--------------------------------------------------------------------------------
1 | REM DOS Btach script
2 |
3 | REM Minify using Google Closure Compiler
4 | REM https://developers.google.com/closure/compiler/
5 |
6 | java -jar compiler.jar ^
7 | --js=../source/Gamalto.js ^
8 | --js=../source/Compat.js ^
9 | --js=../source/GObject.js ^
10 | --js=../source/Extensions.js ^
11 | --js=../source/Missing.js ^
12 | ^
13 | --js=../source/GSectionList.js ^
14 | --js=../source/GSpriteSheet.js ^
15 | --js=../source/GAnimation.js ^
16 | --js=../source/GTileSet.js ^
17 | --js=../source/GFont.js ^
18 | --js=../source/GTiming.js ^
19 | --js=../source/GTimer.js ^
20 | --js=../source/GVector.js ^
21 | --js=../source/GRect.js ^
22 | --js=../source/GSize.js ^
23 | --js=../source/GSurface.js ^
24 | --js=../source/GRenderer.js ^
25 | --js=../source/GScreen.js ^
26 | --js=../source/GBitmap.js ^
27 | --js=../source/GBaseLibrary.js ^
28 | --js=../source/GBitmapLibrary.js ^
29 | --js=../source/GXMLLibrary.js ^
30 | --js=../source/GDataLibrary.js ^
31 | --js=../source/GSequence.js ^
32 | --js=../source/GState.js ^
33 | --js=../source/GColor.js ^
34 | --js=../source/GPattern.js ^
35 | --js=../source/GEvent.js ^
36 | --js=../source/GEventManager.js ^
37 | --js=../source/GKeyboardEvent.js ^
38 | --js=../source/GEventManager_Keyboard.js ^
39 | ^
40 | --js_output_file=gamalto.min.js REM ^
41 | REM --summary_detail_level=3 ^
42 | REM --warning_level=VERBOSE
43 |
--------------------------------------------------------------------------------
/compile/minify.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Minify using Google Closure Compiler
4 | # https://developers.google.com/closure/compiler/
5 |
6 | java -jar compiler.jar \
7 | --js=../source/xrick.js \
8 | --js=../source/system.js \
9 | --js=../source/sysarg.js \
10 | --js=../source/sysvid.js \
11 | --js=../source/sysevt.js \
12 | --js=../source/syssnd.js \
13 | --js=../source/game.js \
14 | --js=../source/draw.js \
15 | --js=../source/maps.js \
16 | --js=../source/control.js \
17 | --js=../source/screens.js \
18 | --js=../source/scr_gameover.js \
19 | --js=../source/scr_getname.js \
20 | --js=../source/scr_xrick.js \
21 | --js=../source/scr_imain.js \
22 | --js=../source/scr_imap.js \
23 | --js=../source/scr_pause.js \
24 | --js=../source/dat_maps.js \
25 | --js=../source/dat_screens.js \
26 | --js=../source/dat_spritesST.js \
27 | --js=../source/dat_ents.js \
28 | --js=../source/e_rick.js \
29 | --js=../source/e_sbonus.js \
30 | --js=../source/e_bomb.js \
31 | --js=../source/e_bonus.js \
32 | --js=../source/e_box.js \
33 | --js=../source/e_them.js \
34 | --js=../source/e_bullet.js \
35 | --js=../source/ents.js \
36 | --js=../source/rects.js \
37 | --js=../source/scroller.js \
38 | --js=../source/tiles.js \
39 | --js=../source/util.js \
40 | \
41 | --language_in=ECMASCRIPT5 \
42 | --js_output_file=xrick.min.js #\
43 |
44 | # --summary_detail_level=3 \
45 | # --warning_level=VERBOSE
46 |
--------------------------------------------------------------------------------
/data/congrat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/congrat.png
--------------------------------------------------------------------------------
/data/control_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/control_left.png
--------------------------------------------------------------------------------
/data/control_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/control_right.png
--------------------------------------------------------------------------------
/data/control_sleft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/control_sleft.png
--------------------------------------------------------------------------------
/data/control_sright.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/control_sright.png
--------------------------------------------------------------------------------
/data/haf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/haf.png
--------------------------------------------------------------------------------
/data/sprites.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/sprites.png
--------------------------------------------------------------------------------
/data/tiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/tiles.png
--------------------------------------------------------------------------------
/data/title.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/data/title.png
--------------------------------------------------------------------------------
/include/control.js:
--------------------------------------------------------------------------------
1 | export const CONTROL_UP = 0x08;
2 | export const CONTROL_DOWN = 0x04;
3 | export const CONTROL_LEFT = 0x02;
4 | export const CONTROL_RIGHT = 0x01;
5 | export const CONTROL_PAUSE = 0x80;
6 | export const CONTROL_END = 0x40;
7 | export const CONTROL_EXIT = 0x20;
8 | export const CONTROL_FIRE = 0x10;
9 |
10 |
--------------------------------------------------------------------------------
/include/draw.js:
--------------------------------------------------------------------------------
1 | /* map coordinates of the screen */
2 | export const DRAW_XYMAP_SCRLEFT = (-0x0020);
3 | export const DRAW_XYMAP_SCRTOP = (0x0040);
4 | /* map coordinates of the top of the hidden bottom of the map */
5 | export const DRAW_XYMAP_HBTOP = (0x0100);
6 |
--------------------------------------------------------------------------------
/include/e_bomb.js:
--------------------------------------------------------------------------------
1 | import { ent } from "./ents";
2 |
3 | const E_BOMB_NO = 3;
4 | export function E_BOMB_ENT() { return ent.ents[E_BOMB_NO]; }
5 | export const E_BOMB_TICKER = (0x2D);
6 |
--------------------------------------------------------------------------------
/include/e_bullet.js:
--------------------------------------------------------------------------------
1 | import { ent } from "./ents";
2 |
3 | export const E_BULLET_NO = 2;
4 | export function E_BULLET_ENT() { return ent.ents[E_BULLET_NO]; }
5 |
--------------------------------------------------------------------------------
/include/e_rick.js:
--------------------------------------------------------------------------------
1 | import { ent } from "./ents";
2 |
3 | export const E_RICK_NO = 1;
4 | export function E_RICK_ENT() { return ent.ents[E_RICK_NO]; }
5 |
6 | export const e_rick = {
7 | state: 0,
8 | stop_x: 0, stop_y: 0
9 | };
10 |
11 | export const E_RICK_STSTOP = 0x01;
12 | export const E_RICK_STSHOOT = 0x02;
13 | export const E_RICK_STCLIMB = 0x04;
14 | export const E_RICK_STJUMP = 0x08;
15 | export const E_RICK_STZOMBIE = 0x10;
16 | export const E_RICK_STDEAD = 0x20;
17 | export const E_RICK_STCRAWL = 0x40;
18 |
19 | export function E_RICK_STSET(X) { e_rick.state |= (X) }
20 | export function E_RICK_STRST(X) { e_rick.state &= ~(X) }
21 | export function E_RICK_STTST(X) { return (e_rick.state & (X)) }
22 |
--------------------------------------------------------------------------------
/include/ents.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/include/ents.h
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012-2022 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | import { create_struct } from "../src/c";
19 |
20 | export function ENT_XRICK() { return ent.ents[1]; }
21 |
22 | export const ENT_ENTSNUM = 0x0c;
23 |
24 | /*
25 | * flags for ent_ents[e].n ("yes" when set)
26 | *
27 | * ENT_LETHAL: is entity lethal?
28 | */
29 | export const ENT_LETHAL = 0x80;
30 |
31 | /*
32 | * flags for ent_ents[e].flag ("yes" when set)
33 | *
34 | * ENT_FLG_ONCE: should the entity run once only?
35 | * ENT_FLG_STOPRICK: does the entity stops rick (and goes to slot zero)?
36 | * ENT_FLG_LETHALR: is entity lethal when restarting?
37 | * ENT_FLG_LETHALI: is entity initially lethal?
38 | * ENT_FLG_TRIGBOMB: can entity be triggered by a bomb?
39 | * ENT_FLG_TRIGBULLET: can entity be triggered by a bullet?
40 | * ENT_FLG_TRIGSTOP: can entity be triggered by rick stop?
41 | * ENT_FLG_TRIGRICK: can entity be triggered by rick?
42 | */
43 | export const ENT_FLG_ONCE = 0x01;
44 | export const ENT_FLG_STOPRICK = 0x02;
45 | export const ENT_FLG_LETHALR = 0x04;
46 | export const ENT_FLG_LETHALI = 0x08;
47 | export const ENT_FLG_TRIGBOMB = 0x10;
48 | export const ENT_FLG_TRIGBULLET = 0x20;
49 | export const ENT_FLG_TRIGSTOP = 0x40;
50 | export const ENT_FLG_TRIGRICK = 0x80;
51 |
52 | const struct_ent_t = [
53 | "n", /* b00 */
54 | /*U8 b01;*/ /* b01 in ASM code but never used */
55 | "x", /* b02 - position */
56 | "y", /* w04 - position */
57 | "sprite", /* b08 - sprite number */
58 | /*U16 w0C;*/ /* w0C in ASM code but never used */
59 | "w", /* b0E - width */
60 | "h", /* b10 - height */
61 | "mark", /* w12 - number of the mark that created the entity */
62 | "flags", /* b14 */
63 | "trig_x", /* b16 - position of trigger box */
64 | "trig_y", /* w18 - position of trigger box */
65 | "xsave", /* b1C */
66 | "ysave", /* w1E */
67 | "sprbase", /* w20 */
68 | "step_no_i", /* w22 */
69 | "step_no", /* w24 */
70 | "c1", /* b26 */
71 | "c2", /* b28 */
72 | "ylow", /* b2A */
73 | "offsy", /* w2C */
74 | "latency", /* b2E */
75 | "prev_n", /* new */
76 | "prev_x", /* new */
77 | "prev_y", /* new */
78 | "prev_s", /* new */
79 | "front", /* new */
80 | "trigsnd" /* new */
81 | ];
82 | export function ent_t(...values) {
83 | const base = {
84 | get seq() { return this.c1; }, // e_bonus.c
85 | set seq(x) { this.c1 = x; },
86 | get cnt() { return this.c1; }, // e_box.c
87 | set cnt(x) { this.c1 = x; },
88 | get flgclmb() { return this.c1; }, // e_them.c
89 | set flgclmb(x) { this.c1 = x; },
90 | get offsx() { return this.c1; }, // e_them.c
91 | set offsx(x) { this.c1 = x; },
92 | get sproffs() { return this.c1; }, // e_them.c
93 | set sproffs(x) { this.c1 = x; },
94 | get step_count() { return this.c2; }, // e_them.c
95 | set step_count(x) { this.c2 = x; },
96 | get offsx2() { return this.c2; }, // e_them.c
97 | set offsx2(x) { this.c2 = x; }
98 | };
99 | return create_struct(struct_ent_t, values, base);
100 | }
101 | export function ent_t_array(size) {
102 | const values = Array(struct_ent_t.length).fill(0);
103 | const result = Array(size)
104 | for (let i = 0; i < size; i++) {
105 | result[i] = ent_t(...values);
106 | }
107 | return result;
108 | }
109 |
110 |
111 | const struct_entdata_t = [
112 | "w", "h",
113 | "spr", "sni",
114 | "trig_w", "trig_h",
115 | "snd"
116 | ];
117 | export function entdata_t(...values) {
118 | return create_struct(struct_entdata_t, values);
119 | }
120 |
121 | const struct_mvstep_t = [
122 | "count",
123 | "dx", "dy"
124 | ];
125 | export function mvstep_t(...values) {
126 | return create_struct(struct_mvstep_t, values);
127 | }
128 |
129 | export const ent = {
130 | ents: ent_t_array(ENT_ENTSNUM + 1),
131 | rects: null
132 | };
133 |
--------------------------------------------------------------------------------
/include/game.js:
--------------------------------------------------------------------------------
1 | import { create_struct } from "../src/c";
2 |
3 | export const LEFT = 1;
4 | export const RIGHT = 0;
5 |
6 | export const GAME_PERIOD = 75
7 |
8 | export const GAME_BOMBS_INIT = 6;
9 | export const GAME_BULLETS_INIT = 6;
10 |
11 | const struct_hscore_t = [
12 | "score",
13 | "name"
14 | ];
15 | export function hscore_t(...values) {
16 | return create_struct(struct_hscore_t, values);
17 | }
18 |
19 | //#ifdef ENABLE_SOUND
20 | export const WAV_GAMEOVER = "WAV_GAMEOVER";
21 | export const WAV_SBONUS2 = "WAV_SBONUS2";
22 | export const WAV_BULLET = "WAV_BULLET";
23 | export const WAV_BOMBSHHT = "WAV_BOMBSHHT";
24 | export const WAV_EXPLODE = "WAV_EXPLODE";
25 | export const WAV_STICK = "WAV_STICK";
26 | export const WAV_WALK = "WAV_WALK";
27 | export const WAV_CRAWL = "WAV_CRAWL";
28 | export const WAV_JUMP = "WAV_JUMP";
29 | export const WAV_PAD = "WAV_PAD";
30 | export const WAV_BOX = "WAV_BOX";
31 | export const WAV_BONUS = "WAV_BONUS";
32 | export const WAV_SBONUS1 = "WAV_SBONUS1";
33 | export const WAV_DIE = "WAV_DIE";
34 | export const WAV_ENTITY = [0, 1, 2, 3, 4, 5, 6, 7, 8];
35 | //#endif
36 |
--------------------------------------------------------------------------------
/include/maps.js:
--------------------------------------------------------------------------------
1 | import { create_struct } from "../src/c";
2 |
3 | export const MAP_NBR_MARKS = 0x020B;
4 |
5 | /*
6 | * map row definitions, for three zones : hidden top, screen, hidden bottom
7 | * the three zones compose map_map, which contains the definition of the
8 | * current portion of the submap.
9 | */
10 | export const MAP_ROW_HTTOP = 0x00;
11 | export const MAP_ROW_HTBOT = 0x07;
12 | export const MAP_ROW_SCRTOP = 0x08;
13 | export const MAP_ROW_SCRBOT = 0x1F;
14 | export const MAP_ROW_HBTOP = 0x20;
15 | export const MAP_ROW_HBBOT = 0x27;
16 |
17 | /*
18 | * main maps
19 | */
20 | const struct_map_t = [
21 | "x", "y", /* initial position for rick */
22 | "row", /* initial map_map top row within the submap */
23 | "submap", /* initial submap */
24 | "tune" /* map tune */
25 | ];
26 | export function map_t(...values) {
27 | return create_struct(struct_map_t, values);
28 | }
29 |
30 | /*
31 | * sub maps
32 | */
33 | const struct_submap_t = [
34 | "page", /* tiles page */
35 | "bnum", /* first block number */
36 | "connect", /* first connection */
37 | "mark" /* first entity mark */
38 | ];
39 | export function submap_t(...values) {
40 | return create_struct(struct_submap_t, values);
41 | }
42 |
43 | /*
44 | * connections
45 | */
46 | const struct_connect_t = [
47 | "dir",
48 | "rowout",
49 | "submap",
50 | "rowin"
51 | ];
52 | export function connect_t(...values) {
53 | return create_struct(struct_connect_t, values);
54 | }
55 |
56 | /*
57 | * blocks - one block is 4 by 4 tiles.
58 | */
59 | // typedef U8 block_t[0x10];
60 | export function block_t(...values) {
61 | return values;
62 | }
63 |
64 | /*
65 | * flags for map_marks[].ent ("yes" when set)
66 | *
67 | * MAP_MARK_NACT: this mark is not active anymore.
68 | */
69 | export const MAP_MARK_NACT = (0x80);
70 |
71 | /*
72 | * mark structure
73 | */
74 | const struct_mark_t = [
75 | "row",
76 | "ent",
77 | "flags",
78 | "xy", /* bits XXXX XYYY (from b03) with X->x, Y->y */
79 | "lt" /* bits XXXX XNNN (from b04) with X->trig_x, NNN->lat & trig_y */
80 | ];
81 | export function mark_t(...values) {
82 | return create_struct(struct_mark_t, values);
83 | }
84 |
85 | /*
86 | * flags for map_eflg[map_map[row][col]] ("yes" when set)
87 | *
88 | * MAP_EFLG_VERT: vertical move only (usually on top of _CLIMB).
89 | * MAP_EFLG_SOLID: solid block, can't go through.
90 | * MAP_EFLG_SPAD: super pad. can't go through, but sends entities to the sky.
91 | * MAP_EFLG_WAYUP: solid block, can't go through except when going up.
92 | * MAP_EFLG_FGND: foreground (hides entities).
93 | * MAP_EFLG_LETHAL: lethal (kill entities).
94 | * MAP_EFLG_CLIMB: entities can climb here.
95 | * MAP_EFLG_01:
96 | */
97 | export const MAP_EFLG_VERT = (0x80);
98 | export const MAP_EFLG_SOLID = (0x40);
99 | export const MAP_EFLG_SPAD = (0x20);
100 | export const MAP_EFLG_WAYUP = (0x10);
101 | export const MAP_EFLG_FGND = (0x08);
102 | export const MAP_EFLG_LETHAL = (0x04);
103 | export const MAP_EFLG_CLIMB = (0x02);
104 | export const MAP_EFLG_01 = (0x01);
105 |
--------------------------------------------------------------------------------
/include/rects.js:
--------------------------------------------------------------------------------
1 |
2 | import { create_struct } from "../src/c";
3 |
4 | const struct_rect_t = [
5 | "x", "y",
6 | "width", "height",
7 | "next"
8 | ];
9 | export function rect_t(...values) {
10 | return create_struct(struct_rect_t, values);
11 | }
12 |
--------------------------------------------------------------------------------
/include/screens.js:
--------------------------------------------------------------------------------
1 | import { create_struct } from "../src/c";
2 |
3 | export const SCREEN_TIMEOUT = 4000;
4 | export const SCREEN_RUNNING = 0;
5 | export const SCREEN_DONE = 1;
6 | export const SCREEN_EXIT = 2;
7 |
8 | const struct_screen_imapsteps_t = [
9 | "count", /* number of loops */
10 | "dx", "dy", /* sprite x and y deltas */
11 | "base" /* base for sprite numbers table */
12 | ]; /* description of one step */
13 | export function screen_imapsteps_t(...values) {
14 | return create_struct(struct_screen_imapsteps_t, values);
15 | }
16 |
--------------------------------------------------------------------------------
/include/scroller.js:
--------------------------------------------------------------------------------
1 | export const SCROLL_RUNNING = 1;
2 | export const SCROLL_DONE = 0;
3 |
4 | export const SCROLL_PERIOD = 24;
5 |
--------------------------------------------------------------------------------
/include/sprites.js:
--------------------------------------------------------------------------------
1 | //#ifdef GFXST
2 |
3 | export const SPRITES_NBR_SPRITES = (0xD5);
4 |
5 | //#endif
6 |
--------------------------------------------------------------------------------
/include/system.js:
--------------------------------------------------------------------------------
1 | /*
2 | * video section
3 | */
4 | export const SYSVID_WIDTH = 320;
5 | export const SYSVID_HEIGHT = 200;
6 |
7 | /*
8 | * args section
9 | */
10 |
--------------------------------------------------------------------------------
/include/tiles.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * three special tile numbers
4 | */
5 | export const TILES_BULLET = 0x01;
6 | export const TILES_BOMB = 0x02;
7 | export const TILES_RICK = 0x03;
8 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | RickJS, a JavaScript port of XRick using HTML5
7 |
28 |
29 |
54 |
55 |
56 |
57 |
58 |
RickJS, based on
xrick by BigOrno
59 | Powered by
Gamalto
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "del": "^6.1.1",
4 | "gulp": "^4.0.2",
5 | "webpack-stream": "^7.0.0"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/sound/bombshht.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bombshht.mp3
--------------------------------------------------------------------------------
/sound/bombshht.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bombshht.ogg
--------------------------------------------------------------------------------
/sound/bombshht.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bombshht.wav
--------------------------------------------------------------------------------
/sound/bonus.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bonus.mp3
--------------------------------------------------------------------------------
/sound/bonus.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bonus.ogg
--------------------------------------------------------------------------------
/sound/bonus.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bonus.wav
--------------------------------------------------------------------------------
/sound/box.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/box.mp3
--------------------------------------------------------------------------------
/sound/box.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/box.ogg
--------------------------------------------------------------------------------
/sound/box.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/box.wav
--------------------------------------------------------------------------------
/sound/bullet.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bullet.mp3
--------------------------------------------------------------------------------
/sound/bullet.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bullet.ogg
--------------------------------------------------------------------------------
/sound/bullet.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/bullet.wav
--------------------------------------------------------------------------------
/sound/crawl.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/crawl.mp3
--------------------------------------------------------------------------------
/sound/crawl.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/crawl.ogg
--------------------------------------------------------------------------------
/sound/crawl.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/crawl.wav
--------------------------------------------------------------------------------
/sound/die.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/die.mp3
--------------------------------------------------------------------------------
/sound/die.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/die.ogg
--------------------------------------------------------------------------------
/sound/die.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/die.wav
--------------------------------------------------------------------------------
/sound/ent0.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent0.mp3
--------------------------------------------------------------------------------
/sound/ent0.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent0.ogg
--------------------------------------------------------------------------------
/sound/ent0.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent0.wav
--------------------------------------------------------------------------------
/sound/ent1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent1.mp3
--------------------------------------------------------------------------------
/sound/ent1.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent1.ogg
--------------------------------------------------------------------------------
/sound/ent1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent1.wav
--------------------------------------------------------------------------------
/sound/ent2.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent2.mp3
--------------------------------------------------------------------------------
/sound/ent2.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent2.ogg
--------------------------------------------------------------------------------
/sound/ent2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent2.wav
--------------------------------------------------------------------------------
/sound/ent3.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent3.mp3
--------------------------------------------------------------------------------
/sound/ent3.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent3.ogg
--------------------------------------------------------------------------------
/sound/ent3.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent3.wav
--------------------------------------------------------------------------------
/sound/ent4.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent4.mp3
--------------------------------------------------------------------------------
/sound/ent4.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent4.ogg
--------------------------------------------------------------------------------
/sound/ent4.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent4.wav
--------------------------------------------------------------------------------
/sound/ent5.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent5.mp3
--------------------------------------------------------------------------------
/sound/ent5.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent5.ogg
--------------------------------------------------------------------------------
/sound/ent5.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent5.wav
--------------------------------------------------------------------------------
/sound/ent6.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent6.mp3
--------------------------------------------------------------------------------
/sound/ent6.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent6.ogg
--------------------------------------------------------------------------------
/sound/ent6.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent6.wav
--------------------------------------------------------------------------------
/sound/ent7.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent7.mp3
--------------------------------------------------------------------------------
/sound/ent7.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent7.ogg
--------------------------------------------------------------------------------
/sound/ent7.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent7.wav
--------------------------------------------------------------------------------
/sound/ent8.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent8.mp3
--------------------------------------------------------------------------------
/sound/ent8.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent8.ogg
--------------------------------------------------------------------------------
/sound/ent8.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/ent8.wav
--------------------------------------------------------------------------------
/sound/explode.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/explode.mp3
--------------------------------------------------------------------------------
/sound/explode.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/explode.ogg
--------------------------------------------------------------------------------
/sound/explode.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/explode.wav
--------------------------------------------------------------------------------
/sound/gameover.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/gameover.mp3
--------------------------------------------------------------------------------
/sound/gameover.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/gameover.ogg
--------------------------------------------------------------------------------
/sound/gameover.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/gameover.wav
--------------------------------------------------------------------------------
/sound/jump.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/jump.mp3
--------------------------------------------------------------------------------
/sound/jump.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/jump.ogg
--------------------------------------------------------------------------------
/sound/jump.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/jump.wav
--------------------------------------------------------------------------------
/sound/pad.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/pad.mp3
--------------------------------------------------------------------------------
/sound/pad.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/pad.ogg
--------------------------------------------------------------------------------
/sound/pad.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/pad.wav
--------------------------------------------------------------------------------
/sound/sbonus1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/sbonus1.mp3
--------------------------------------------------------------------------------
/sound/sbonus1.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/sbonus1.ogg
--------------------------------------------------------------------------------
/sound/sbonus1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/sbonus1.wav
--------------------------------------------------------------------------------
/sound/sbonus2.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/sbonus2.mp3
--------------------------------------------------------------------------------
/sound/sbonus2.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/sbonus2.ogg
--------------------------------------------------------------------------------
/sound/sbonus2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/sbonus2.wav
--------------------------------------------------------------------------------
/sound/stick.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/stick.mp3
--------------------------------------------------------------------------------
/sound/stick.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/stick.ogg
--------------------------------------------------------------------------------
/sound/stick.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/stick.wav
--------------------------------------------------------------------------------
/sound/tune0.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune0.mp3
--------------------------------------------------------------------------------
/sound/tune0.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune0.ogg
--------------------------------------------------------------------------------
/sound/tune0.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune0.wav
--------------------------------------------------------------------------------
/sound/tune1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune1.mp3
--------------------------------------------------------------------------------
/sound/tune1.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune1.ogg
--------------------------------------------------------------------------------
/sound/tune1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune1.wav
--------------------------------------------------------------------------------
/sound/tune2.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune2.mp3
--------------------------------------------------------------------------------
/sound/tune2.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune2.ogg
--------------------------------------------------------------------------------
/sound/tune2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune2.wav
--------------------------------------------------------------------------------
/sound/tune3.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune3.mp3
--------------------------------------------------------------------------------
/sound/tune3.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune3.ogg
--------------------------------------------------------------------------------
/sound/tune3.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune3.wav
--------------------------------------------------------------------------------
/sound/tune4.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune4.mp3
--------------------------------------------------------------------------------
/sound/tune4.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune4.ogg
--------------------------------------------------------------------------------
/sound/tune4.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune4.wav
--------------------------------------------------------------------------------
/sound/tune5.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune5.mp3
--------------------------------------------------------------------------------
/sound/tune5.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune5.ogg
--------------------------------------------------------------------------------
/sound/tune5.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/tune5.wav
--------------------------------------------------------------------------------
/sound/walk.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/walk.mp3
--------------------------------------------------------------------------------
/sound/walk.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/walk.ogg
--------------------------------------------------------------------------------
/sound/walk.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chrilith/RickJS/79172693588a93946b2843f838fa49c7723eb854/sound/walk.wav
--------------------------------------------------------------------------------
/source/control.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/control.c
6 | * - xrick/src/control.h
7 | *
8 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
9 | * Copyright (C) 2012 Chrilith (me@chrilith.com). All rights reserved.
10 | *
11 | * The use and distribution terms for this software are contained in the file
12 | * named README, which can be found in the root of this distribution. By
13 | * using this software in any fashion, you are agreeing to be bound by the
14 | * terms of this license.
15 | *
16 | * You must not remove this notice, or any other, from this software.
17 | */
18 |
19 | /*
20 | * constants
21 | */
22 | var CONTROL_UP = 0x08,
23 | CONTROL_DOWN = 0x04,
24 | CONTROL_LEFT = 0x02,
25 | CONTROL_RIGHT = 0x01,
26 | CONTROL_PAUSE = 0x80,
27 | CONTROL_END = 0x40,
28 | CONTROL_EXIT = 0x20,
29 | CONTROL_FIRE = 0x10;
30 |
31 | (function() {
32 |
33 | Control.status = 0;
34 | Control.last = 0;
35 | Control.active = true;
36 |
37 | /* EOF */
38 | })();
39 |
--------------------------------------------------------------------------------
/source/dat_screens.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/control.c
6 | * - xrick/src/control.h
7 | *
8 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
9 | * Copyright (C) 2012 Chrilith (me@chrilith.com). All rights reserved.
10 | *
11 | * The use and distribution terms for this software are contained in the file
12 | * named README, which can be found in the root of this distribution. By
13 | * using this software in any fashion, you are agreeing to be bound by the
14 | * terms of this license.
15 | *
16 | * You must not remove this notice, or any other, from this software.
17 | */
18 |
19 | (function() {
20 | /*
21 | * map intro, sprites lists
22 | */
23 | Screen.imapsl = [
24 | 0x1b, 0x00,
25 | 0x1c, 0x1d, 0x00,
26 | 0x01, 0x00,
27 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x00,
28 | 0x1e, 0x00,
29 | 0x0d, 0x00,
30 | 0x13, 0x14, 0x00,
31 | 0x1f, 0x00
32 | ];
33 |
34 | /*
35 | * map intro, steps
36 | */
37 | /*
38 | typedef struct {
39 | U16 count; // number of loops
40 | U16 dx, dy; // sprite x and y deltas
41 | U16 base; // base for sprite numbers table
42 | } screen_imapsteps_t; // description of one step
43 | */
44 | Screen.imapsteps = [
45 | { count: 0x0000, dx: 0x0002, dy: 0x0002, base: 0x0000 },
46 |
47 | { count: 0x000b, dx: 0x0000, dy: 0x0001, base: 0x0000 },
48 | { count: 0x0008, dx: 0x0001, dy: 0x0000, base: 0x0002 },
49 |
50 | { count: 0x0000, dx: 0x0000, dy: 0x000c, base: 0x0000 },
51 |
52 | { count: 0x000a, dx: 0x0000, dy: 0x0000, base: 0x0005 },
53 | { count: 0x0006, dx: 0x0002, dy: 0x0000, base: 0x0007 },
54 | { count: 0x0005, dx: 0x0000, dy: 0x0000, base: 0x0005 },
55 |
56 | { count: 0x0000, dx: 0x0006, dy: 0x0000, base: 0x0000 },
57 |
58 | { count: 0x000c, dx: 0x0000, dy: 0x0001, base: 0x0000 },
59 | { count: 0x0005, dx: 0x0000, dy: 0x0000, base: 0x000d },
60 |
61 | { count: 0x0000, dx: 0x000c, dy: 0x000c, base: 0x0000 },
62 |
63 | { count: 0x0005, dx: 0x0000, dy: 0x0000, base: 0x0005 },
64 | { count: 0x000a, dx: 0x0000, dy: 0x0000, base: 0x000f },
65 | { count: 0x000c, dx: 0xffff, dy: 0x0000, base: 0x0011 },
66 | { count: 0x0005, dx: 0x0000, dy: 0x0000, base: 0x000f },
67 |
68 | { count: 0x0000, dx: 0x0006, dy: 0x0001, base: 0x0000 },
69 |
70 | { count: 0x000a, dx: 0x0000, dy: 0x0000, base: 0x0014 },
71 | { count: 0x0006, dx: 0x0000, dy: 0x0001, base: 0x0014 },
72 | { count: 0x0005, dx: 0x0000, dy: 0x0000, base: 0x0014 },
73 | { count: 0x0003, dx: 0x0001, dy: 0x0000, base: 0x0014 },
74 | { count: 0x0006, dx: 0xffff, dy: 0x0000, base: 0x0014 },
75 | { count: 0x0003, dx: 0x0000, dy: 0xffff, base: 0x0014 },
76 |
77 | { count: 0x0000, dx: 0x0000, dy: 0x0000, base: 0x0000 }
78 | ];
79 |
80 | /*
81 | * map intro, step offset per map
82 | */
83 | Screen.imapsofs = [
84 | 0x00, 0x03, 0x07, 0x0a, 0x0f
85 | ];
86 |
87 | /*
88 | * map intro, text
89 | * (from ds + 0x8810 + 0x2000, 0x2138, 0x2251, 0x236a, 0x2464)
90 | *
91 | * \376=0xfe \377=0xff
92 | */
93 | var screen_imaptext_amazon = "\
94 | @@@@@SOUTH@AMERICA,@1945@@@@@@\xFF\
95 | RICK@DANGEROUS@CRASH@LANDS@HIS\xFF\
96 | @PLANE@OVER@THE@AMAZON@WHILE@@\xFF\
97 | @SEARCHING@FOR@THE@LOST@GOOLU@\xFF\
98 | @@@@@@@@@@@@TRIBE.@@@@@@@@@@@@\xFF\xFF\
99 | @BUT,@BY@A@TERRIBLE@TWIST@OF@@\xFF\
100 | FATE@HE@LANDS@IN@THE@MIDDLE@OF\xFF\
101 | @@@A@BUNCH@OF@WILD@GOOLUS.@@@@\xFF\xFF\
102 | @@CAN@RICK@ESCAPE@THESE@ANGRY@\xFF\
103 | @@@AMAZONIAN@ANTAGONISTS?@@@@@\xFE".replace(/\s+/g, "");
104 |
105 | screen_imaptext_egypt = "\
106 | @@@@EGYPT,@SOMETIME@LATER@@@@@\xFF\
107 | RICK@HEADS@FOR@THE@PYRAMIDS@AT\xFF\
108 | @@@@THE@REQUEST@OF@LONDON.@@@@\xFF\xFF\
109 | HE@IS@TO@RECOVER@THE@JEWEL@OF@\xFF\
110 | ANKHEL@THAT@HAS@BEEN@STOLEN@BY\xFF\
111 | FANATICS@WHO@THREATEN@TO@SMASH\xFF\
112 | @IT,@IF@A@RANSOM@IS@NOT@PAID.@\xFF\xFF\
113 | CAN@RICK@SAVE@THE@GEM,@OR@WILL\xFF\
114 | HE@JUST@GET@A@BROKEN@ANKHEL@?@\xFE".replace(/\s+/g, ""),
115 |
116 | screen_imaptext_castle = "\
117 | @@@@EUROPE,@LATER@THAT@WEEK@@@\xFF\
118 | @@RICK@RECEIVES@A@COMMUNIQUE@@\xFF\
119 | @@FROM@BRITISH@INTELLIGENCE@@@\xFF\
120 | @@ASKING@HIM@TO@RESCUE@ALLIED@\xFF\
121 | @PRISONERS@FROM@THE@NOTORIOUS@\xFF\
122 | @@@@SCHWARZENDUMPF@CASTLE.@@@@\xFF\xFF\
123 | @@RICK@ACCEPTS@THE@MISSION.@@@\xFF\xFF\
124 | @@@BUT@CAN@HE@LIBERATE@THE@@@@\xFF\
125 | @CRUELLY@CAPTURED@COOMANDOS@?@\xFE".replace(/\s+/g, ""),
126 |
127 | screen_imaptext_missile = "\
128 | @@@@@@EUROPE,@EVEN@LATER@@@@@@\xFF\
129 | RICK@LEARNS@FROM@THE@PRISONERS\xFF\
130 | @THAT@THE@ENEMY@ARE@TO@LAUNCH@\xFF\
131 | AN@ATTACK@ON@LONDON@FROM@THEIR\xFF\
132 | @@@@@SECRET@MISSILE@BASE.@@@@@\xFF\xFF\
133 | WITHOUT@HESITATION,@HE@DECIDES\xFF\
134 | @@@TO@INFILTRATE@THE@BASE.@@@@\xFF\xFF\
135 | CAN@RICK@SAVE@LONDON@IN@TIME@?\xFE".replace(/\s+/g, ""),
136 |
137 | screen_imaptext_muchlater = "\
138 | @@@LONDON,@MUCH,@MUCH@LATER@@@\xFF\
139 | @RICK@RETURNS@TO@A@TRIUMPHANT@\xFF\
140 | @@WELCOME@HOME@HAVING@HELPED@@\xFF\
141 | @@@@SECURE@ALLIED@VICTORY.@@@@\xFF\xFF\
142 | BUT,@MEANWHILE,@IN@SPACE,@THE@\xFF\
143 | @@@MASSED@STARSHIPS@OF@THE@@@@\xFF\
144 | @@@BARFIAN@EMPIRE@ARE@POISED@@\xFF\
145 | @@@@@TO@INVADE@THE@EARTH.@@@@@\xFF\xFF\
146 | @WHAT@WILL@RICK@DO@NEXT@...@?@\xFE".replace(/\s+/g, "");
147 |
148 | Screen.imaptext = [
149 | screen_imaptext_amazon,
150 | screen_imaptext_egypt,
151 | screen_imaptext_castle,
152 | screen_imaptext_missile,
153 | screen_imaptext_muchlater
154 | ];
155 |
156 | /*
157 | * main intro, hall of fame title
158 | * (from ds + 0x8810 + 0x2642)
159 | */
160 | Screen.imainhoft = [
161 | 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0xd4, 0xb7, 0xb1,
162 | 0xac, 0xc6, 0x2f, 0xc6, 0x2f, 0x2f, 0xa4, 0xac,
163 | 0x9b, 0xc1, 0x2f, 0x9b, 0xc1, 0xb1, 0xac, 0xb6,
164 | 0xbd, 0x9b, 0xc1, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
165 | 0xff,
166 | 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0xb2, 0xb3, 0xb2,
167 | 0xb3, 0xad, 0x2f, 0xad, 0x2f, 0x2f, 0xa6, 0xae,
168 | 0xc2, 0xc3, 0x2f, 0xc2, 0xc3, 0xb2, 0xb3, 0xbe,
169 | 0xbf, 0xc2, 0xc3, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
170 | 0xff,
171 | 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x9f, 0xc0, 0xb4,
172 | 0xb5, 0xaf, 0xc4, 0xaf, 0xc4, 0x2f, 0xa7, 0xb0,
173 | 0xb4, 0x2f, 0x2f, 0xb4, 0x2f, 0xb4, 0xb5, 0xb4,
174 | 0xb5, 0xaf, 0xc4, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
175 | 0xfe
176 | ];
177 |
178 | /*
179 | * main intro, Rick Dangerous title
180 | * (from ds + 0x8810 + 0x27a1)
181 | */
182 | Screen.imainrdt = [
183 | 0x2f, 0x2f, 0x2f, 0x9b, 0x9c, 0xa1, 0xa4, 0xa5,
184 | 0xa9, 0xaa, 0x2f, 0x9b, 0xac, 0xb1, 0xac, 0xb6,
185 | 0xb7, 0xa4, 0xa5, 0x9b, 0xc1, 0x9b, 0x9c, 0xa4,
186 | 0xac, 0xc6, 0xc7, 0xc8, 0xc9, 0x2f, 0x2f, 0x2f,
187 | 0xff,
188 | 0x2f, 0x2f, 0x2f, 0x9d, 0x9e, 0xa2, 0xa6, 0x2f,
189 | 0x9d, 0xab, 0x2f, 0xad, 0xae, 0xb2, 0xb3, 0xb8,
190 | 0xb9, 0xa6, 0xbb, 0xc2, 0xc3, 0x9d, 0x9e, 0xa6,
191 | 0xae, 0xad, 0xae, 0xca, 0xcb, 0x2f, 0x2f, 0x2f,
192 | 0xff,
193 | 0x2f, 0x2f, 0x2f, 0x9f, 0xa0, 0xa3, 0xa7, 0xa8,
194 | 0x9f, 0xa0, 0x2f, 0xaf, 0xb0, 0xb4, 0xb5, 0x9f,
195 | 0xba, 0xa7, 0xbc, 0xaf, 0xc4, 0x9f, 0xa0, 0xa7,
196 | 0xb0, 0xc5, 0xb0, 0xcc, 0xb0, 0x2f, 0x2f, 0x2f,
197 | 0xfe
198 | ];
199 |
200 | /*
201 | * congratulations
202 | * (from ds + 0x8810 + 0x257d)
203 | */
204 | Screen.congrats = [
205 | 0xa4, 0xa5, 0xa4, 0xac, 0xb6, 0xb7, 0xa4, 0xa5,
206 | 0x9b, 0x9c, 0xb1, 0xac, 0xcd, 0xce, 0xc6, 0xc7,
207 | 0xd3, 0x2f, 0xb1, 0xac, 0xcd, 0xce, 0xa1, 0xa4,
208 | 0xac, 0xb6, 0xb7, 0xc8, 0xc9, 0x2f, 0xd5, 0xd6,
209 | 0xff,
210 | 0xa6, 0x2f, 0xa6, 0xae, 0xb8, 0xb9, 0xa6, 0xbb,
211 | 0x9d, 0x9e, 0xb2, 0xb3, 0xcf, 0xd0, 0xad, 0xae,
212 | 0xad, 0x2f, 0xb2, 0xb3, 0xcf, 0xd0, 0xa2, 0xa6,
213 | 0xae, 0xb8, 0xb9, 0xca, 0xcb, 0x2f, 0xd7, 0xd8,
214 | 0xff,
215 | 0xa7, 0xa8, 0xa7, 0xb0, 0x9f, 0xba, 0xa7, 0xbc,
216 | 0x9f, 0xa0, 0xb4, 0xb5, 0xd1, 0xd2, 0xc5, 0xb0,
217 | 0xaf, 0xc4, 0xb4, 0xb5, 0xd1, 0xd2, 0xa3, 0xa7,
218 | 0xb0, 0x9f, 0xba, 0xcc, 0xb0, 0x2f, 0xd9, 0xda,
219 | 0xfe
220 | ];
221 |
222 | /*
223 | * main intro, Core Design copyright text
224 | * (from ds + 0x8810 + 0x2288)
225 | *
226 | * \376=0xfe \377=0xff
227 | */
228 | Screen.imaincdc = "\
229 | @@@@@@@@@@@@@@@@@@@\xFF\xFF\
230 | (C)@1989@CORE@DESIGN\xFF\xFF\xFF\
231 | @PRESS@SPACE@TO@START\xFE".replace(/\s+/g, "");
232 |
233 | /*
234 | * gameover
235 | * (from ds + 0x8810 + 0x2864)
236 | *
237 | * \376=0xfe \377=0xff
238 | */
239 | Screen.gameovertxt = "\
240 | @@@@@@@@@@@\xFF\
241 | @GAME@OVER@\xFF\
242 | @@@@@@@@@@@\xFE".replace(/\s+/g, "");
243 |
244 | /*
245 | * paused
246 | *
247 | * \376=0xfe \377=0xff
248 | */
249 | Screen.pausedtxt = "\
250 | @@@@@@@@@@\xFF\
251 | @@PAUSED@@\xFF\
252 | @@@@@@@@@@\xFE".replace(/\s+/g, "");
253 |
254 | /* EOF */
255 | })();
256 |
--------------------------------------------------------------------------------
/source/dat_spritesST.js:
--------------------------------------------------------------------------------
1 | var SPRITES_NBR_SPRITES = (0xD5);
2 |
3 | //sprite_t sprites_data[SPRITES_NBR_SPRITES] = {...} => image file
4 |
--------------------------------------------------------------------------------
/source/draw.js:
--------------------------------------------------------------------------------
1 | /*
2 | * counters positions (pixels, screen)
3 | */
4 | var DRAW_STATUS_BULLETS_X = 0x68,
5 | DRAW_STATUS_BOMBS_X = 0xA8,
6 |
7 | DRAW_STATUS_SCORE_X = 0x20,
8 | DRAW_STATUS_LIVES_X = 0xF0,
9 | DRAW_STATUS_Y = 0,
10 |
11 | /* map coordinates of the screen */
12 | DRAW_XYMAP_SCRLEFT = (-0x0020),
13 | DRAW_XYMAP_SCRTOP = (0x0040),
14 |
15 | /* map coordinates of the top of the hidden bottom of the map */
16 | DRAW_XYMAP_HBTOP = (0x0100);
17 |
18 | (function() {
19 | /*
20 | * public vars
21 | */
22 | Draw.tllst = 0; /* pointer to tiles list */
23 | Draw.tilesBank = 0; /* tile number offset */
24 |
25 | Draw.STATUSRECT = new G.Rect(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y,
26 | DRAW_STATUS_LIVES_X + 6 * 8 - DRAW_STATUS_SCORE_X, 8);
27 |
28 | Draw.SCREENRECT = new G.Rect(0, 0, SYSVID_WIDTH, SYSVID_HEIGHT);
29 |
30 | /*
31 | * private vars
32 | */
33 | var fb = new G.Vector();
34 |
35 | /*
36 | * Set the frame buffer pointer
37 | *
38 | * x, y: position (pixels, screen)
39 | */
40 | Draw.setfb = function(x, y) {
41 | fb.x = x;
42 | fb.y = y;
43 | }
44 |
45 | /*
46 | * Clip to map screen
47 | *
48 | * x, y: position (pixels, map) CHANGED clipped
49 | * width, height: dimension CHANGED clipped
50 | * return: TRUE if fully clipped, FALSE if still (at least partly) visible
51 | */
52 | Draw.clipms = function(x, y, width, height) {
53 | if (x < 0) {
54 | if (x + width < 0) {
55 | return { returns: true, x: x, y: y, width: width, height: height };
56 | } else {
57 | width += x;
58 | x = 0;
59 | }
60 | } else {
61 | if (x > 0x0100) {
62 | return { returns: true, x: x, y: y, width: width, height: height };
63 | } else if (x + width > 0x0100) {
64 | width = 0x0100 - x;
65 | }
66 | }
67 |
68 | if (y < DRAW_XYMAP_SCRTOP) {
69 | if ((y + height) < DRAW_XYMAP_SCRTOP) {
70 | return { returns: true, x: x, y: y, width: width, height: height };
71 | } else {
72 | height += y - DRAW_XYMAP_SCRTOP;
73 | y = DRAW_XYMAP_SCRTOP;
74 | }
75 | } else {
76 | if (y >= DRAW_XYMAP_HBTOP) {
77 | return { returns: true, x: x, y: y, width: width, height: height };
78 | } else if (y + height > DRAW_XYMAP_HBTOP) {
79 | height = DRAW_XYMAP_HBTOP - y;
80 | }
81 | }
82 |
83 | return { returns: false, x: x, y: y, width: width, height: height };
84 | }
85 |
86 | /*
87 | * Draw a list of tiles onto the frame buffer
88 | * start at position indicated by fb ; at the end of each (sub)list,
89 | * perform a "carriage return + line feed" i.e. go back to the initial
90 | * position then go down one tile row (8 pixels)
91 | *
92 | * ASM 1e33
93 | * fb: CHANGED (see above)
94 | * draw_tllst: CHANGED points to the element following 0xfe/0xff end code
95 | */
96 | Draw.tilesList = function() {
97 | var t = fb.clone();
98 | while (Draw.tilesSubList() != 0xFE) { /* draw sub-list */
99 | t.y += 8; /* go down one tile i.e. 8 lines */
100 | fb = t.clone();
101 | }
102 | }
103 |
104 | /*
105 | * Draw a list of tiles onto the frame buffer -- same as draw_tilesList,
106 | * but accept an immediate string as parameter. Note that the string needs
107 | * to be properly terminated with 0xfe (\376) and 0xff (\377) chars.
108 | */
109 | Draw.tilesListImm = function(list) {
110 | Draw.tllst = (typeof list == "array") ? list : list.split(""); // FIXME?
111 | Draw.tilesList();
112 | }
113 |
114 | /*
115 | * Draw a sub-list of tiles onto the frame buffer
116 | * start at position indicated by fb ; leave fb pointing to the next
117 | * tile to the right of the last tile drawn
118 | *
119 | * ASM 1e41
120 | * fpb: CHANGED (see above)
121 | * draw_tllst: CHANGED points to the element following 0xfe/0xff end code
122 | * returns: end code (0xfe : end of list ; 0xff : end of sub-list)
123 | */
124 | Draw.tilesSubList = function() {
125 | var i = Draw.tllst.shift().charCodeAt(0);
126 |
127 | while (i != 0xFF && i != 0xFE) { /* while not end */
128 | Draw.tile(i); /* draw tile */
129 | i = Draw.tllst.shift().charCodeAt(0);
130 | }
131 |
132 | return i;
133 | }
134 |
135 | /*
136 | * Draw a tile
137 | * at position indicated by fb ; leave fb pointing to the next tile
138 | * to the right of the tile drawn
139 | *
140 | * ASM 1e6c
141 | * tlnbr: tile number
142 | * draw_filter: CGA colors filter
143 | * fb: CHANGED (see above)
144 | */
145 | Draw.tile = function(tileNumber) {
146 | Tiles.data[Draw.tilesBank].draw(Sysvid.fb.renderer, fb.x, fb.y, tileNumber);
147 | // Sysvid.fb.renderer.fillRect(new G.Rect(fb.x, fb.y, 8, 8), new G.Color(Math.random() * 255 | 0, 0, 0));
148 | fb.x += 8; /* next tile */
149 | }
150 |
151 | /*
152 | * Draw a sprite
153 | *
154 | * ASM 1a09
155 | * nbr: sprite number
156 | * x, y: sprite position (pixels, screen)
157 | * fb: CHANGED
158 | */
159 | Draw.sprite = function(number, x, y) {
160 | Draw.setfb(x, y);
161 | Sprites.data.draw(Sysvid.fb.renderer, fb.x, fb.y, number);
162 | }
163 |
164 | /*
165 | * Draw a sprite
166 | *
167 | * NOTE re-using original ST graphics format
168 | */
169 | Draw.sprite2 = function(number, x, y, front) {
170 | var d = 0; /* sprite data */
171 | var x0, y0; /* clipped x, y */
172 | var w, h; /* width, height */
173 | var g, /* sprite data offset*/
174 | r, c, /* row, column */
175 | i, /* frame buffer shifter */
176 | im; /* tile flag shifter */
177 | var flg, tmp;/* tile flag */
178 |
179 | x0 = x;
180 | y0 = y;
181 | w = 0x20;
182 | h = 0x15;
183 |
184 | tmp = Draw.clipms(x0, y0, w, h);
185 | if (tmp.returns) { /* return if not visible */
186 | return;
187 | }
188 | x0 = tmp.x;
189 | y0 = tmp.y;
190 | w = tmp.width;
191 | h = tmp.height;
192 |
193 | g = 0;
194 |
195 | Sysvid.fb.enableClipping(new G.Rect(x0 - DRAW_XYMAP_SCRLEFT, y0 - DRAW_XYMAP_SCRTOP + 8, w, h));
196 | Draw.setfb(x - DRAW_XYMAP_SCRLEFT, y - DRAW_XYMAP_SCRTOP + 8);
197 | Draw.sprite(number, fb.x, fb.y);
198 | Sysvid.fb.disableClipping();
199 | /*
200 | for (r = 0; r < 0x15; r++) {
201 | if (r >= h || y + r < y0) continue;
202 |
203 | i = 0x1f;
204 | im = x - (x & 0xfff8);
205 | flg = World.eflg[World.map[(y + r) >> 3][(x + 0x1f)>> 3]];
206 |
207 | #define LOOP(N, C0, C1) \
208 | d = sprites_data[number][g + N]; \
209 | for (c = C0; c >= C1; c--, i--, d >>= 4, im--) { \
210 | if (im == 0) { \
211 | flg = map_eflg[map_map[(y + r) >> 3][(x + c) >> 3]]; \
212 | im = 8; \
213 | } \
214 | if (!front && (flg & MAP_EFLG_FGND)) continue; \
215 | if (c >= w || x + c < x0) continue; \
216 | if (d & 0x0F) fb[i] = (fb[i] & 0xF0) | (d & 0x0F); \
217 | }
218 |
219 | LOOP(3, 0x1f, 0x18);
220 | LOOP(2, 0x17, 0x10);
221 | LOOP(1, 0x0f, 0x08);
222 | LOOP(0, 0x07, 0x00);
223 |
224 | #undef LOOP
225 | fb += SYSVID_WIDTH;
226 | g += 4;
227 | }
228 | */
229 | }
230 |
231 | /*
232 | * Redraw the map behind a sprite
233 | * align to tile column and row, and clip
234 | *
235 | * x, y: sprite position (pixels, map).
236 | */
237 | Draw.spriteBackground = function(x, y) {
238 | var r, c;
239 | var rmax, cmax;
240 | var xmap, ymap; // S16
241 | var xs, ys, tmp;
242 |
243 | /* aligne to column and row, prepare map coordinate, and clip */
244 | xmap = G.Convert.toInt16(x & 0xFFF8);
245 | ymap = G.Convert.toInt16(y & 0xFFF8);
246 | cmax = (x - xmap == 0 ? 0x20 : 0x28); /* width, 4 tl cols, 8 pix each */
247 | rmax = (y & 0x04) ? 0x20 : 0x18; /* height, 3 or 4 tile rows */
248 |
249 | tmp = Draw.clipms(xmap, ymap, cmax, rmax);
250 | if (tmp.returns) { /* don't draw if fully clipped */
251 | return;
252 | }
253 | xmap = tmp.x;
254 | ymap = tmp.y;
255 | cmax = tmp.width;
256 | rmax = tmp.height;
257 |
258 | /* get back to screen */
259 | xs = xmap - DRAW_XYMAP_SCRLEFT;
260 | ys = ymap - DRAW_XYMAP_SCRTOP;
261 | xmap >>= 3;
262 | ymap >>= 3;
263 | cmax >>= 3;
264 | rmax >>= 3;
265 |
266 | /* draw */
267 | for (r = 0; r < rmax; r++) { /* for each row */
268 | Draw.setfb(xs, 8 + ys + r * 8);
269 | for (c = 0; c < cmax; c++) { /* for each column */
270 | Draw.tile(World.map[ymap + r][xmap + c]);
271 | }
272 | }
273 | }
274 |
275 | /*
276 | * Draw entire map screen background tiles onto frame buffer.
277 | *
278 | * ASM 0af5, 0a54
279 | */
280 | Draw.map = function() {
281 | var i, j;
282 |
283 | Draw.tilesBank = World.tilesBank;
284 |
285 | for (i = 0; i < 0x18; i++) { /* 0x18 rows */
286 | Draw.setfb(0x20, 8 + (i * 8));
287 | for (j = 0; j < 0x20; j++) /* 0x20 tiles per row */
288 | Draw.tile(World.map[i + 8][j]);
289 | }
290 | }
291 | /*
292 | * Draw status indicators
293 | *
294 | * ASM 0309
295 | */
296 | Draw.drawStatus = function() {
297 | var i;
298 | // var sv;
299 | // var s = [0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfe];
300 |
301 | Draw.tilesBank = 0;
302 |
303 | // for (i = 5, sv = Game.score; i >= 0; i--) {
304 | // s[i] = 0x30 + (sv % 10 | 0);
305 | // sv /= 10;
306 | // }
307 | Draw.tllst = ("00000" + Game.score + "\xFE").substr(-7).split("");
308 |
309 | Draw.setfb(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y);
310 | Draw.tilesList();
311 |
312 | Draw.setfb(DRAW_STATUS_BULLETS_X, DRAW_STATUS_Y);
313 | for (i = 0; i < Game.bullets; i++) {
314 | Draw.tile(TILES_BULLET);
315 | }
316 |
317 | Draw.setfb(DRAW_STATUS_BOMBS_X, DRAW_STATUS_Y);
318 | for (i = 0; i < Game.bombs; i++) {
319 | Draw.tile(TILES_BOMB);
320 | }
321 |
322 | Draw.setfb(DRAW_STATUS_LIVES_X, DRAW_STATUS_Y);
323 | for (i = 0; i < Game.lives; i++) {
324 | Draw.tile(TILES_RICK);
325 | }
326 | }
327 |
328 | /*
329 | * Clear status indicators
330 | */
331 | Draw.clearStatus = function() {
332 | var i;
333 |
334 | Draw.tilesBank = 0;
335 | Draw.setfb(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y);
336 | for (i = 0; i < DRAW_STATUS_LIVES_X/8 + 6 - DRAW_STATUS_SCORE_X/8; i++) {
337 | Draw.tile('@');
338 | }
339 | }
340 |
341 | /*
342 | * Draw a picture
343 | */
344 | Draw.pic = function(x, y, w, h, pic) {
345 | Sysvid.fb.renderer.drawBitmapSection(pic, x, y, new G.Rect(0, 0, w, h));
346 | }
347 |
348 | /* EOF */
349 | })();
350 |
--------------------------------------------------------------------------------
/source/e_bomb.js:
--------------------------------------------------------------------------------
1 | var E_BOMB_NO = 3,
2 | E_BOMB_ENT, // Defined later in ents.js
3 | E_BOMB_TICKER = (0x2D);
4 |
5 | (function() {
6 |
7 | /*
8 | * public vars (for performance reasons)
9 | */
10 | EBomb.lethal = 0;
11 | EBomb.xc = 0;
12 | EBomb.yc = 0;
13 |
14 | /*
15 | * private vars
16 | */
17 | var e_bomb_ticker;
18 |
19 | /*
20 | * Bomb hit test
21 | *
22 | * ASM 11CD
23 | * returns: TRUE/hit, FALSE/not
24 | */
25 | EBomb.hit = function(e) {
26 | if (Ent.ents[e].x > (E_BOMB_ENT.x >= 0xE0 ? 0xFF : E_BOMB_ENT.x + 0x20)) {
27 | return false;
28 | }
29 | if (Ent.ents[e].x + Ent.ents[e].w < (E_BOMB_ENT.x > 0x04 ? E_BOMB_ENT.x - 0x04 : 0)) {
30 | return false;
31 | }
32 | if (Ent.ents[e].y > (E_BOMB_ENT.y + 0x1D)) {
33 | return false;
34 | }
35 | if (Ent.ents[e].y + Ent.ents[e].h < (E_BOMB_ENT.y > 0x0004 ? E_BOMB_ENT.y - 0x0004 : 0)) {
36 | return false;
37 | }
38 | return true;
39 | }
40 |
41 | /*
42 | * Initialize bomb
43 | */
44 | EBomb.init = function(x, y) {
45 | E_BOMB_ENT.n = 0x03;
46 | E_BOMB_ENT.x = x;
47 | E_BOMB_ENT.y = y;
48 | e_bomb_ticker = E_BOMB_TICKER;
49 | EBomb.lethal = false;
50 |
51 | /*
52 | * Atari ST dynamite sprites are not centered the
53 | * way IBM PC sprites were ... need to adjust things a little bit
54 | */
55 | E_BOMB_ENT.x += 4;
56 | E_BOMB_ENT.y += 5;
57 |
58 | }
59 |
60 | /*
61 | * Entity action
62 | *
63 | * ASM 18CA
64 | */
65 | EBomb.action = function(/*UNUSED(U8 e)*/) {
66 | /* tick */
67 | e_bomb_ticker--;
68 |
69 | if (e_bomb_ticker == 0) {
70 | /*
71 | * end: deactivate
72 | */
73 | E_BOMB_ENT.n = 0;
74 | EBomb.lethal = false;
75 |
76 | } else if (e_bomb_ticker >= 0x0A) {
77 | /*
78 | * ticking
79 | */
80 | if ((e_bomb_ticker & 0x03) == 0x02) {
81 | Syssnd.play("WAV_BOMBSHHT", 1);
82 | }
83 |
84 | /* ST bomb sprites sequence is longer */
85 | if (e_bomb_ticker < 40)
86 | E_BOMB_ENT.sprite = 0x99 + 19 - (e_bomb_ticker >> 1);
87 | else
88 |
89 | E_BOMB_ENT.sprite = (e_bomb_ticker & 0x01) ? 0x23 : 0x22;
90 |
91 | } else if (e_bomb_ticker == 0x09) {
92 | /*
93 | * explode
94 | */
95 | Syssnd.play("WAV_EXPLODE", 1);
96 | /* See above: fixing alignment */
97 | E_BOMB_ENT.x -= 4;
98 | E_BOMB_ENT.y -= 5;
99 | E_BOMB_ENT.sprite = 0xa8 + 4 - (e_bomb_ticker >> 1);
100 |
101 | EBomb.xc = E_BOMB_ENT.x + 0x0C;
102 | EBomb.yc = E_BOMB_ENT.y + 0x000A;
103 | EBomb.lethal = true;
104 | if (EBomb.hit(E_RICK_NO)) {
105 | ERick.gozombie();
106 | }
107 | } else {
108 | /*
109 | * exploding
110 | */
111 | E_BOMB_ENT.sprite = 0xa8 + 4 - (e_bomb_ticker >> 1);
112 |
113 | /* exploding, hence lethal */
114 | if (EBomb.hit(E_RICK_NO)) {
115 | ERick.gozombie();
116 | }
117 | }
118 | }
119 |
120 | /* EOF */
121 | })();
122 |
--------------------------------------------------------------------------------
/source/e_bonus.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | /*
4 | * Entity action
5 | *
6 | * ASM 242C
7 | */
8 | EBonus.action = function(e) {
9 | //#define seq c1
10 |
11 | if (Ent.ents[e].seq == 0) {
12 | if (ERick.boxtest(e)) {
13 | Game.score += 500;
14 | Syssnd.play("WAV_BONUS", 1);
15 | World.marks[Ent.ents[e].mark].ent |= MAP_MARK_NACT;
16 | Ent.ents[e].seq = 1;
17 | Ent.ents[e].sprite = 0xad;
18 | Ent.ents[e].front = true;
19 | Ent.ents[e].y -= 0x08;
20 | }
21 |
22 | } else if (Ent.ents[e].seq > 0 && Ent.ents[e].seq < 10) {
23 | Ent.ents[e].seq++;
24 | Ent.ents[e].y -= 2;
25 |
26 | } else {
27 | Ent.ents[e].n = 0;
28 | }
29 | }
30 |
31 | /* EOF */
32 | })();
33 |
--------------------------------------------------------------------------------
/source/e_box.js:
--------------------------------------------------------------------------------
1 | /*
2 | * FIXME this is because the same structure is used
3 | * for all entities. Need to replace this w/ an inheritance
4 | * solution.
5 | */
6 | //#define cnt c1
7 |
8 | /*
9 | * Constants
10 | */
11 | var SEQ_INIT = 0x0A;
12 |
13 | (function() {
14 |
15 | var sp = [ 0x24, 0x25, 0x26, 0x27, 0x28 ]; /* explosion sprites sequence */
16 |
17 | /*
18 | * Entity action
19 | *
20 | * ASM 245A
21 | */
22 | EBox.action = function(e) {
23 |
24 | if (Ent.ents[e].n & ENT_LETHAL) {
25 | /*
26 | * box is lethal i.e. exploding
27 | * play sprites sequence then stop
28 | */
29 | Ent.ents[e].sprite = sp[Ent.ents[e].cnt >> 1];
30 | if (--Ent.ents[e].cnt == 0) {
31 | Ent.ents[e].n = 0;
32 | World.marks[Ent.ents[e].mark].ent |= MAP_MARK_NACT;
33 | }
34 | } else {
35 | /*
36 | * not lethal: check to see if triggered
37 | */
38 | if (ERick.boxtest(e)) {
39 | /* rick: collect bombs or bullets and stop */
40 | Syssnd.play("WAV_BOX", 1);
41 |
42 | if (Ent.ents[e].n == 0x10) {
43 | Game.bombs = GAME_BOMBS_INIT;
44 | } else { /* 0x11 */
45 | Game.bullets = GAME_BULLETS_INIT;
46 | }
47 | Ent.ents[e].n = 0;
48 | World.marks[Ent.ents[e].mark].ent |= MAP_MARK_NACT;
49 |
50 | } else if (E_RICK_STTST(E_RICK_STSTOP) &&
51 | U.fboxtest(e, ERick.stop_x, ERick.stop_y)) {
52 | /* rick's stick: explode */
53 | explode(e);
54 |
55 | } else if (E_BULLET_ENT.n && U.fboxtest(e, EBullet.xc, EBullet.yc)) {
56 | /* bullet: explode (and stop bullet) */
57 | E_BULLET_ENT.n = 0;
58 | explode(e);
59 |
60 | } else if (EBomb.lethal && EBomb.hit(e)) {
61 | /* bomb: explode */
62 | explode(e);
63 | }
64 | }
65 | }
66 |
67 | /*
68 | * Explode when
69 | */
70 | function explode(e) {
71 | Ent.ents[e].cnt = SEQ_INIT;
72 | Ent.ents[e].n |= ENT_LETHAL;
73 | Syssnd.play("WAV_EXPLODE", 1);
74 | }
75 |
76 |
77 | /* EOF */
78 | })();
79 |
--------------------------------------------------------------------------------
/source/e_bullet.js:
--------------------------------------------------------------------------------
1 | /* const
2 | ********/
3 | var E_BULLET_NO = 2,
4 | E_BULLET_ENT // defined later;
5 |
6 | (function() {
7 |
8 | /*
9 | * public vars (for performance reasons)
10 | */
11 | EBullet.offsx = 0;
12 | EBullet.xc = EBullet.yc = 0;
13 |
14 | /*
15 | * Initialize bullet
16 | */
17 | EBullet.init = function(x, y) {
18 | E_BULLET_ENT.n = 0x02;
19 | E_BULLET_ENT.x = x;
20 | E_BULLET_ENT.y = y + 0x0006;
21 | if (Game.dir == LEFT) {
22 | EBullet.offsx = -0x08;
23 | E_BULLET_ENT.sprite = 0x21;
24 | } else {
25 | EBullet.offsx = 0x08;
26 | E_BULLET_ENT.sprite = 0x20;
27 | }
28 | Syssnd.play("WAV_BULLET", 1);
29 | }
30 |
31 | /*
32 | * Entity action
33 | *
34 | * ASM 1883, 0F97
35 | */
36 | EBullet.action = function(/*UNUSED(U8 e)*/) {
37 | /* move bullet */
38 | E_BULLET_ENT.x += EBullet.offsx;
39 |
40 | if (E_BULLET_ENT.x <= -0x10 || E_BULLET_ENT.x > 0xe8) {
41 | /* out: deactivate */
42 | E_BULLET_ENT.n = 0;
43 |
44 | } else {
45 | /* update bullet center coordinates */
46 | EBullet.xc = E_BULLET_ENT.x + 0x0c;
47 | EBullet.yc = E_BULLET_ENT.y + 0x05;
48 | if (World.eflg[World.map[EBullet.yc >> 3][EBullet.xc >> 3]] &
49 | MAP_EFLG_SOLID) {
50 | /* hit something: deactivate */
51 | E_BULLET_ENT.n = 0;
52 | }
53 | }
54 | }
55 |
56 | /* EOF */
57 | })();
58 |
--------------------------------------------------------------------------------
/source/e_sbonus.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | /*
3 | * public vars
4 | */
5 | ESbonus.counting = false;
6 | ESbonus.counter = 0;
7 | ESbonus.bonus = 0;
8 |
9 | /*
10 | * Entity action / start counting
11 | *
12 | * ASM 2182
13 | */
14 | ESbonus.start = function(e) {
15 | Ent.ents[e].sprite = 0; /* invisible */
16 | if (U.trigbox(e, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) {
17 | /* rick is within trigger box */
18 | Ent.ents[e].n = 0;
19 | ESbonus.counting = true; /* 6DD5 */
20 | ESbonus.counter = 0x1e; /* 6DDB */
21 | ESbonus.bonus = 2000; /* 291A-291D */
22 | Syssnd.play("WAV_SBONUS1", 1);
23 | }
24 | }
25 |
26 | /*
27 | * Entity action / stop counting
28 | *
29 | * ASM 2143
30 | */
31 | ESbonus.stop = function(e) {
32 | Ent.ents[e].sprite = 0; /* invisible */
33 |
34 | if (!ESbonus.counting) {
35 | return;
36 | }
37 |
38 | if (U.trigbox(e, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) {
39 | /* rick is within trigger box */
40 | ESbonus.counting = false; /* stop counting */
41 | Ent.ents[e].n = 0; /* deactivate entity */
42 | Game.score += ESbonus.bonus; /* add bonus to score */
43 | Syssnd.play("WAV_SBONUS2", 1);
44 | /* make sure the entity won't be activated again */
45 | World.marks[Ent.ents[e].mark].ent |= MAP_MARK_NACT;
46 | } else {
47 | /* keep counting */
48 | if (--ESbonus.counter == 0) {
49 | ESbonus.counter = 0x1e;
50 | if (ESbonus.bonus) ESbonus.bonus--;
51 | }
52 | }
53 | }
54 |
55 | /* EOF */
56 | })();
57 |
--------------------------------------------------------------------------------
/source/maps.js:
--------------------------------------------------------------------------------
1 | var MAP_NBR_MAPS = 0x05,
2 | MAP_NBR_SUBMAPS = 0x2F,
3 | MAP_NBR_CONNECT = 0x99,
4 | MAP_NBR_BNUMS = 0x1FD8,
5 | MAP_NBR_BLOCKS = 0x0100,
6 | MAP_NBR_MARKS = 0x020B,
7 | MAP_NBR_EFLGC = 0x0020,
8 |
9 | /*
10 | * map row definitions, for three zones : hidden top, screen, hidden bottom
11 | * the three zones compose map_map, which contains the definition of the
12 | * current portion of the submap.
13 | */
14 | MAP_ROW_HTTOP = 0x00,
15 | MAP_ROW_HTBOT = 0x07,
16 | MAP_ROW_SCRTOP = 0x08,
17 | MAP_ROW_SCRBOT = 0x1F,
18 | MAP_ROW_HBTOP = 0x20,
19 | MAP_ROW_HBBOT = 0x27,
20 |
21 | /*
22 | * flags for map_marks[].ent ("yes" when set)
23 | *
24 | * MAP_MARK_NACT: this mark is not active anymore.
25 | */
26 | MAP_MARK_NACT = (0x80),
27 |
28 | /*
29 | * flags for map_eflg[map_map[row][col]] ("yes" when set)
30 | *
31 | * MAP_EFLG_VERT: vertical move only (usually on top of _CLIMB).
32 | * MAP_EFLG_SOLID: solid block, can't go through.
33 | * MAP_EFLG_SPAD: super pad. can't go through, but sends entities to the sky.
34 | * MAP_EFLG_WAYUP: solid block, can't go through except when going up.
35 | * MAP_EFLG_FGND: foreground (hides entities).
36 | * MAP_EFLG_LETHAL: lethal (kill entities).
37 | * MAP_EFLG_CLIMB: entities can climb here.
38 | * MAP_EFLG_01:
39 | */
40 | MAP_EFLG_VERT = (0x80),
41 | MAP_EFLG_SOLID = (0x40),
42 | MAP_EFLG_SPAD = (0x20),
43 | MAP_EFLG_WAYUP = (0x10),
44 | MAP_EFLG_FGND = (0x08),
45 | MAP_EFLG_LETHAL = (0x04),
46 | MAP_EFLG_CLIMB = (0x02),
47 | MAP_EFLG_01 = (0x01);
48 |
49 | (function() {
50 | /*
51 | * global vars
52 | */
53 | World.map = []; // [0x2C][0x20];
54 | World.eflg = []; // [0x100];
55 | World.frow = 0;
56 | World.tilesBank = 0;
57 |
58 | for (var n = 0; n < 0x2C; n++) {
59 | World.map[n] = [];
60 | for (var m = 0; m < 0x20; m++) {
61 | World.map[n][m] = 0;
62 | }
63 | }
64 |
65 | /*
66 | * Fill in map_map with tile numbers by expanding blocks.
67 | *
68 | * add map_submaps[].bnum to map_frow to find out where to start from.
69 | * We need to /4 map_frow to convert from tile rows to block rows, then
70 | * we need to *8 to convert from block rows to block numbers (there
71 | * are 8 blocks per block row). This is achieved by *2 then &0xfff8.
72 | */
73 | World.expand = function() {
74 | var i, j, k, l;
75 | var row = 0, col = 0;
76 | var pbnum = 0;
77 |
78 | pbnum = World.submaps[Game.submap].bnum + ((2 * World.frow) & 0xfff8);
79 | row = col = 0;
80 |
81 | for (i = 0; i < 0x0b; i++) { /* 0x0b rows of blocks */
82 | for (j = 0; j < 0x08; j++) { /* 0x08 blocks per row */
83 | for (k = 0, l = 0; k < 0x04; k++) { /* expand one block */
84 | World.map[row][col++] = World.blocks[World.bnums[pbnum]][l++];
85 | World.map[row][col++] = World.blocks[World.bnums[pbnum]][l++];
86 | World.map[row][col++] = World.blocks[World.bnums[pbnum]][l++];
87 | World.map[row][col] = World.blocks[World.bnums[pbnum]][l++];
88 | row += 1; col -= 3;
89 | }
90 | row -= 4; col += 4;
91 | pbnum++;
92 | }
93 | row += 4; col = 0;
94 | }
95 | }
96 |
97 | /*
98 | * Initialize a new submap
99 | *
100 | * ASM 0cc3
101 | */
102 | World.init = function() {
103 | /*sys_printf("xrick/map_init: map=%#04x submap=%#04x\n", g_map, game_submap);*/
104 | World.tilesBank = (World.submaps[Game.submap].page == 1) ? 2 : 1;
105 |
106 | World.eflg_expand((World.submaps[Game.submap].page == 1) ? 0x10 : 0x00);
107 | World.expand();
108 | Ent.reset();
109 | Ent.actvis(World.frow + MAP_ROW_SCRTOP, World.frow + MAP_ROW_SCRBOT);
110 | Ent.actvis(World.frow + MAP_ROW_HTTOP, World.frow + MAP_ROW_HTBOT);
111 | Ent.actvis(World.frow + MAP_ROW_HBTOP, World.frow + MAP_ROW_HBBOT);
112 | }
113 |
114 | /*
115 | * Expand entity flags for this map
116 | *
117 | * ASM 1117
118 | */
119 | World.eflg_expand = function(offs) {
120 | var i, j, k;
121 |
122 | for (i = 0, k = 0; i < 0x10; i++) {
123 | j = World.eflg_c[offs + i++];
124 | while (j--) World.eflg[k++] = World.eflg_c[offs + i];
125 | }
126 | }
127 |
128 | /*
129 | * Chain (sub)maps
130 | *
131 | * ASM 0c08
132 | * return: TRUE/next submap OK, FALSE/map finished
133 | */
134 | World.chain = function() {
135 | var c, t;
136 |
137 | Game.chsm = 0;
138 | ESbonus.counting = false;
139 |
140 | /* find connection */
141 | c = World.submaps[Game.submap].connect;
142 | t = 3;
143 | /*
144 | IFDEBUG_MAPS(
145 | sys_printf("xrick/maps: chain submap=%#04x frow=%#04x .connect=%#04x %s\n",
146 | game_submap, map_frow, c,
147 | (game_dir == LEFT ? "-> left" : "-> right"));
148 | );
149 | */
150 | /*
151 | * look for the first connector with compatible row number. if none
152 | * found, then panic
153 | */
154 | for (c = World.submaps[Game.submap].connect; ; c++) {
155 | if (World.connect[c].dir == 0xff) {
156 | sys_panic("(map_chain) can not find connector\n");
157 | }
158 | if (World.connect[c].dir != Game.dir) { continue; }
159 | t = (Ent.ents[1].y >> 3) + World.frow - World.connect[c].rowout;
160 | if (t < 3) { break; }
161 | }
162 |
163 | /* got it */
164 | /* IFDEBUG_MAPS(
165 | sys_printf("xrick/maps: chain frow=%#04x y=%#06x\n",
166 | map_frow, ent_ents[1].y);
167 | sys_printf("xrick/maps: chain connect=%#04x rowout=%#04x - ",
168 | c, map_connect[c].rowout);
169 | );
170 | */
171 |
172 | if (World.connect[c].submap == 0xff) {
173 | /* no next submap - request next map */
174 | /* IFDEBUG_MAPS(
175 | sys_printf("chain to next map\n");
176 | );*/
177 | return false;
178 |
179 | } else {
180 | /* next submap */
181 | /* IFDEBUG_MAPS(
182 | sys_printf("chain to submap=%#04x rowin=%#04x\n",
183 | map_connect[c].submap, map_connect[c].rowin);
184 | );*/
185 | World.frow = World.frow - World.connect[c].rowout + World.connect[c].rowin;
186 | Game.submap = World.connect[c].submap;
187 | /* IFDEBUG_MAPS(
188 | sys_printf("xrick/maps: chain frow=%#04x\n",
189 | map_frow);
190 | );*/
191 | return true;
192 | }
193 | }
194 |
195 | /*
196 | * Reset all marks, i.e. make them all active again.
197 | *
198 | * ASM 0025
199 | *
200 | */
201 | World.resetMarks = function() {
202 | var i;
203 |
204 | for (i = 0; i < MAP_NBR_MARKS; i++) {
205 | World.marks[i].ent &= ~MAP_MARK_NACT;
206 | }
207 | }
208 |
209 | /* EOF */
210 | })();
211 |
--------------------------------------------------------------------------------
/source/rects.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | /*
4 | * Free a list of rectangles and set the pointer to NULL.
5 | *
6 | * p: rectangle list CHANGED to NULL
7 | */
8 | Rects.free = function(r) {
9 | if (r) {
10 | r.splice(0, r.length);
11 | }
12 | }
13 |
14 | /*
15 | * Add a rectangle to a list of rectangles
16 | */
17 | Rects.create = function(x, y, width, height, next) { // was new()
18 | var r;
19 |
20 | r = new G.Rect(x, y, width, height);
21 | next = next || [];
22 | next.unshift(r);
23 | return next;
24 | }
25 |
26 | /* EOF */
27 | })();
28 |
--------------------------------------------------------------------------------
/source/scr_gameover.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | /*
4 | * Display the game over screen
5 | *
6 | * return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
7 | */
8 | var seq = 0; /* static */
9 | var period = 0; /* static */
10 | var tm = 0; /* static */
11 |
12 | Screen.gameover = function() {
13 |
14 | if (seq == 0) {
15 | Draw.tilesBank = 0;
16 | seq = 1;
17 | period = Game.period; /* save period, */
18 | Game.period = 50; /* and use our own */
19 | Game.setmusic("WAV_GAMEOVER", 1);
20 | }
21 |
22 | switch (seq) {
23 | case 1: /* display banner */
24 | Sysvid.clear();
25 | tm = Date.now();
26 |
27 | Draw.tllst = Screen.gameovertxt.split("");
28 | Draw.setfb(120, 80);
29 | Draw.tilesList();
30 | Draw.drawStatus();
31 |
32 | Game.rects = [Draw.SCREENRECT];
33 | seq = 2;
34 | break;
35 |
36 | case 2: /* wait for key pressed */
37 | if (Control.status & CONTROL_FIRE) {
38 | seq = 3;
39 | } else if (Date.now() - tm > SCREEN_TIMEOUT) {
40 | seq = 4;
41 | }
42 | // else {
43 | // sys_sleep(50);
44 | // }
45 | break;
46 |
47 | case 3: /* wait for key released */
48 | if (!(Control.status & CONTROL_FIRE)) {
49 | seq = 4;
50 | }
51 | // else {
52 | // sys_sleep(50);
53 | // }
54 | break;
55 | }
56 |
57 | if (Control.status & CONTROL_EXIT) /* check for exit request */
58 | return SCREEN_EXIT;
59 |
60 | if (seq == 4) { /* we're done */
61 | Sysvid.clear();
62 | seq = 0;
63 | Game.period = period;
64 | return SCREEN_DONE;
65 | }
66 |
67 | return SCREEN_RUNNING;
68 | }
69 |
70 | /* EOF */
71 | })();
72 |
--------------------------------------------------------------------------------
/source/scr_getname.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/scr_getname.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | /*
19 | * constants
20 | */
21 | var TILE_POINTER = 0x3A, // \072
22 | TILE_CURSOR = 0x3B, // \073
23 | TOPLEFT_X = 116,
24 | TOPLEFT_Y = 64,
25 | NAMEPOS_X = 120,
26 | NAMEPOS_Y = 160,
27 | AUTOREPEAT_TMOUT = 100;
28 |
29 | (function() {
30 | /*
31 | * local vars
32 | */
33 | var seq = 0,
34 | x, y, p,
35 | name = [];
36 |
37 | /*
38 | * Get name
39 | *
40 | * return: 0 while running, 1 when finished.
41 | */
42 | var tm = 0; // static
43 | Screen.getname = function() {
44 | var i, j;
45 |
46 | if (seq == 0) {
47 | /* figure out if this is a high score */
48 | if (Game.score < Game.hscores[7].score) {
49 | return SCREEN_DONE;
50 | }
51 |
52 | /* prepare */
53 | Draw.tilesBank = 0;
54 | for (i = 0; i < 10; i++) {
55 | name[i] = '@'.charCodeAt(0);
56 | }
57 | x = 5;
58 | y = 4;
59 | p = 0;
60 | Game.rects = [Draw.SCREENRECT];
61 | seq = 1;
62 | }
63 |
64 | switch (seq) {
65 |
66 | case 1: /* prepare screen */
67 | Sysvid.clear();
68 |
69 | Draw.pic(36, 4, 244, 22, Data.getItem("pic_congrat"));
70 |
71 | Draw.setfb(72, 40);
72 | Draw.tilesListImm("PLEASE@ENTER@YOUR@NAME\xFE");
73 | for (i = 0; i < 6; i++) {
74 | for (j = 0; j < 4; j++) {
75 | Draw.setfb(TOPLEFT_X + i * 8 * 2, TOPLEFT_Y + j * 8 * 2);
76 | Draw.tile('A'.charCodeAt(0) + i + j * 6);
77 | }
78 | }
79 | Draw.setfb(TOPLEFT_X, TOPLEFT_Y + 64);
80 | Draw.tilesListImm("Y@Z@.@@@\x3C\xFB\xFC\xFD\xFE");
81 | name_draw();
82 | pointer_show(true);
83 | seq = 2;
84 | break;
85 |
86 | case 2: /* wait for key pressed */
87 | if (Control.status & CONTROL_FIRE) {
88 | seq = 3;
89 | }
90 | if (Control.status & CONTROL_UP) {
91 | if (y > 0) {
92 | pointer_show(false);
93 | y--;
94 | pointer_show(true);
95 | tm = Sys.gettime();
96 | }
97 | seq = 4;
98 | }
99 | if (Control.status & CONTROL_DOWN) {
100 | if (y < 4) {
101 | pointer_show(false);
102 | y++;
103 | pointer_show(true);
104 | tm = Sys.gettime();
105 | }
106 | seq = 5;
107 | }
108 | if (Control.status & CONTROL_LEFT) {
109 | if (x > 0) {
110 | pointer_show(false);
111 | x--;
112 | pointer_show(true);
113 | tm = Sys.gettime();
114 | }
115 | seq = 6;
116 | }
117 | if (Control.status & CONTROL_RIGHT) {
118 | if (x < 5) {
119 | pointer_show(false);
120 | x++;
121 | pointer_show(true);
122 | tm = Sys.gettime();
123 | }
124 | seq = 7;
125 | }
126 | if (seq == 2) {
127 | //sys_sleep(50);
128 | }
129 | break;
130 |
131 | case 3: /* wait for FIRE released */
132 | if (!(Control.status & CONTROL_FIRE)) {
133 | if (x == 5 && y == 4) { /* end */
134 | i = 0;
135 | while (Game.score < Game.hscores[i].score) {
136 | i++;
137 | }
138 | j = 7;
139 | while (j > i) {
140 | Game.hscores[j].score = Game.hscores[j - 1].score;
141 | // for (x = 0; x < 10; x++) {
142 | Game.hscores[j].name = Game.hscores[j - 1].name;
143 | // }
144 | j--;
145 | }
146 | Game.hscores[i].score = Game.score;
147 | var tmp = "";
148 | for (x = 0; x < 10; x++) {
149 | tmp += String.fromCharCode(name[x]);
150 | }
151 | Game.hscores[i].name = tmp;
152 | seq = 99;
153 | } else {
154 | name_update();
155 | name_draw();
156 | seq = 2;
157 | }
158 | } else {
159 | // sys_sleep(50);
160 | }
161 | break;
162 |
163 | case 4: /* wait for UP released */
164 | if (!(Control.status & CONTROL_UP) ||
165 | Sys.gettime() - tm > AUTOREPEAT_TMOUT) {
166 | seq = 2;
167 | } else {
168 | // sys_sleep(50);
169 | }
170 | break;
171 |
172 | case 5: /* wait for DOWN released */
173 | if (!(Control.status & CONTROL_DOWN) ||
174 | Sys.gettime() - tm > AUTOREPEAT_TMOUT) {
175 | seq = 2;
176 | } else {
177 | // sys_sleep(50);
178 | }
179 | break;
180 |
181 | case 6: /* wait for LEFT released */
182 | if (!(Control.status & CONTROL_LEFT) ||
183 | Sys.gettime() - tm > AUTOREPEAT_TMOUT) {
184 | seq = 2;
185 | } else {
186 | // sys_sleep(50);
187 | }
188 | break;
189 |
190 | case 7: /* wait for RIGHT released */
191 | if (!(Control.status & CONTROL_RIGHT) ||
192 | Sys.gettime() - tm > AUTOREPEAT_TMOUT) {
193 | seq = 2;
194 | } else {
195 | // sys_sleep(50);
196 | }
197 | break;
198 | }
199 |
200 | if (Control.status & CONTROL_EXIT) { /* check for exit request */
201 | return SCREEN_EXIT;
202 | }
203 |
204 | if (seq == 99) { /* seq 99, we're done */
205 | Sysvid.clear();
206 | seq = 0;
207 | return SCREEN_DONE;
208 | } else {
209 | return SCREEN_RUNNING;
210 | }
211 | }
212 |
213 |
214 | function pointer_show(show) {
215 | Draw.setfb(TOPLEFT_X + x * 8 * 2, TOPLEFT_Y + y * 8 * 2 + 8);
216 | Draw.tile((show == true)?TILE_POINTER:'@'.charCodeAt(0));
217 | }
218 |
219 | function name_update() {
220 | var i;
221 |
222 | i = x + y * 6;
223 | if (i < 26 && p < 10) {
224 | name[p++] = 'A'.charCodeAt(0) + i;
225 | }
226 | if (i == 26 && p < 10) {
227 | name[p++] = '.'.charCodeAt(0);
228 | }
229 | if (i == 27 && p < 10) {
230 | name[p++] = '@'.charCodeAt(0);
231 | }
232 | if (i == 28 && p > 0) {
233 | p--;
234 | }
235 | }
236 |
237 |
238 | function name_draw() {
239 | var i;
240 |
241 | Draw.setfb(NAMEPOS_X, NAMEPOS_Y);
242 |
243 | for (i = 0; i < p; i++) {
244 | Draw.tile(name[i]);
245 | }
246 | for (i = p; i < 10; i++) {
247 | Draw.tile(TILE_CURSOR);
248 | }
249 |
250 | Draw.setfb(NAMEPOS_X, NAMEPOS_Y + 8);
251 | for (i = 0; i < 10; i++) {
252 | Draw.tile('@'.charCodeAt(0));
253 | }
254 | Draw.setfb(NAMEPOS_X + 8 * (p < 9 ? p : 9), NAMEPOS_Y + 8);
255 | Draw.tile(TILE_POINTER);
256 | }
257 |
258 | /* EOF */
259 | })();
260 |
--------------------------------------------------------------------------------
/source/scr_imain.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/scr_imain.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | (function() {
19 | /*
20 | * static
21 | */
22 | var seq = 0,
23 | seen = 0,
24 | first = true,
25 | period = 0,
26 | tm = 0,
27 | i , s = [],
28 | fading;
29 |
30 | /*
31 | * Main introduction
32 | *
33 | * return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
34 | */
35 | Screen.introMain = function(timer) {
36 | if (seq == 0) {
37 | Draw.tilesBank = 0;
38 | if (first == true) {
39 | seq = 1;
40 | } else {
41 | seq = 4;
42 | }
43 | period = Game.period;
44 | Game.period = 50;
45 | Game.rects = [Draw.SCREENRECT];
46 | Game.setmusic("WAV_TUNE5", -1);
47 | }
48 |
49 | switch (seq) {
50 | case 1: /* display Rick Dangerous title and Core Design copyright */
51 | if (fading) {
52 | break;
53 | }
54 | Sysvid.clear();
55 | tm = Sys.gettime();
56 | Draw.pic(0, 0, 0x140, 0xc8, Data.getItem("pic_splash"));
57 | seq = 2;
58 |
59 | fading = GE.Fader.IN;
60 | Sysvid.fade_start();
61 | break;
62 |
63 | case 2: /* wait for key pressed or timeout */
64 | if (Control.status & CONTROL_FIRE) {
65 | seq = 3;
66 | } else if (Sys.gettime() - tm > SCREEN_TIMEOUT) {
67 | seen++;
68 | seq = 4;
69 |
70 | fading = GE.Fader.OUT;
71 | Sysvid.fade_start();
72 | }
73 | break;
74 |
75 | case 3: /* wait for key released */
76 |
77 | if (!(Control.status & CONTROL_FIRE)) {
78 | if (seen++ == 0) {
79 | seq = 4;
80 | } else {
81 | seq = 7;
82 |
83 | fading = GE.Fader.OUT;
84 | Sysvid.fade_start();
85 | }
86 | }
87 | break;
88 |
89 | case 4: /* dispay hall of fame */
90 | if (fading) {
91 | break;
92 | }
93 | Sysvid.clear();
94 | tm = Sys.gettime();
95 |
96 | /* hall of fame title */
97 | Draw.pic(64, 4, 190, 22, Data.getItem("pic_haf"));
98 |
99 | /* hall of fame content */
100 | Draw.setfb(56, 48);
101 |
102 | for (i = 0; i < 8; i++) {
103 | var score = ("00" + Game.hscores[i].score).substr(-6);
104 | Draw.tllst = (score +
105 | "@@@====@@@" +
106 | Game.hscores[i].name +
107 | "\xFF\xFF\xFE").split(""); // \377\377\376
108 | Draw.tilesList();
109 | }
110 |
111 | seq = 5;
112 |
113 | fading = GE.Fader.IN;
114 | Sysvid.fade_start();
115 | break;
116 |
117 | case 5: /* wait for key pressed or timeout */
118 |
119 | if (Control.status & CONTROL_FIRE) {
120 | seq = 6;
121 | } else if (Sys.gettime() - tm > SCREEN_TIMEOUT) {
122 | seen++;
123 | seq = 1;
124 |
125 | fading = GE.Fader.OUT;
126 | Sysvid.fade_start();
127 | }
128 | break;
129 |
130 | case 6: /* wait for key released */
131 | if (!(Control.status & CONTROL_FIRE)) {
132 | if (seen++ == 0) {
133 | seq = 1;
134 | } else {
135 | seq = 7;
136 |
137 | fading = GE.Fader.OUT;
138 | Sysvid.fade_start();
139 | }
140 | }
141 | break;
142 | }
143 |
144 | if (fading) {
145 | Game.rects = [Draw.SCREENRECT];
146 | if (!Sysvid.fader.update(timer, fading)) {
147 | fading = Sysvid.fade_end();
148 | // Loop directly to prevent flipping
149 | if (seq !=7) {
150 | Screen.introMain(timer);
151 | }
152 | }
153 | }
154 |
155 | if (Control.status & CONTROL_EXIT) { /* check for exit request */
156 | return SCREEN_EXIT;
157 | }
158 |
159 | if (seq == 7 && !fading) { /* we're done */
160 | Sysvid.clear();
161 | seq = 0;
162 | seen = 0;
163 | first = false;
164 | Game.period = period;
165 | return SCREEN_DONE;
166 | } else {
167 | return SCREEN_RUNNING;
168 | }
169 | }
170 |
171 | /* EOF */
172 | })();
173 |
--------------------------------------------------------------------------------
/source/scr_imap.js:
--------------------------------------------------------------------------------
1 | /* const
2 | ********/
3 | // ...
4 | var SCREEN_TIMEOUT = 4000;
5 |
6 | (function() {
7 | /* local
8 | ********/
9 | var step, /* current step */
10 | count, /* number of loops for current step */
11 | run, /* 1 = run, 0 = no more step */
12 | flipflop = 0, /* flipflop for top, bottom, left, right */
13 | spnum, /* sprite number */
14 | spx, spdx, /* sprite x position and delta */
15 | spy, spdy, /* sprite y position and delta */
16 | spbase, spoffs, /* base, offset for sprite numbers table */
17 | seq = 0, /* anim sequence */
18 | fading;
19 |
20 | var anim_rect = new G.Rect(128, 16 + 16, 64, 64); /* anim rectangle */
21 |
22 | /* global
23 | *********/
24 | Screen.introMap = function(timer) {
25 | switch (seq) {
26 | case 0:
27 | Sysvid.clear();
28 | Draw.tilesBank = 0;
29 | Draw.tllst = Screen.imaptext[Game.map].split("");
30 |
31 | Draw.setfb(40, 16);
32 | Draw.tilesSubList();
33 |
34 | Draw.setfb(40, 104);
35 | Draw.tilesList();
36 |
37 | Game.rects = null;
38 |
39 | init();
40 |
41 | nextstep();
42 | drawcenter();
43 | drawtb();
44 | drawlr();
45 | drawsprite();
46 | Draw.drawStatus();
47 | Control.last = 0;
48 |
49 | Game.rects = [Draw.SCREENRECT];
50 |
51 | Game.setmusic(World.maps[Game.map].tune, 1);
52 |
53 | seq = 1;
54 | fading = GE.Fader.IN;
55 | Sysvid.fade_start();
56 | break;
57 |
58 | case 1: /* top and bottom borders */
59 | drawtb();
60 | Game.rects = [anim_rect];
61 | seq = 2;
62 | break;
63 |
64 | case 2: /* background and sprite */
65 | anim();
66 | drawcenter();
67 | drawsprite();
68 | Game.rects = [anim_rect];
69 | seq = 3;
70 | break;
71 |
72 | case 3: /* all borders */
73 | drawtb();
74 | drawlr();
75 | Game.rects = [anim_rect];
76 | seq = 1;
77 | break;
78 |
79 | case 4: /* wait for key release */
80 | if (!(Control.status & CONTROL_FIRE)) {
81 | seq = 5;
82 | } else {
83 | Sys.sleep(50); /* .5s */
84 | }
85 | break;
86 | }
87 |
88 | if (Control.status & CONTROL_FIRE) { /* end as soon as key pressed */
89 | seq = 4;
90 | fading = GE.Fader.OUT;
91 | Sysvid.fade_start();
92 | }
93 |
94 | if (fading) {
95 | Game.rects = [Draw.SCREENRECT];
96 | if (!Sysvid.fader.update(timer, fading)) {
97 | fading = Sysvid.fade_end();
98 | }
99 | }
100 |
101 | if (Control.status & CONTROL_EXIT) /* check for exit request */
102 | return SCREEN_EXIT;
103 |
104 | if (seq == 5 && !fading) { /* end as soon as key pressed */
105 | Sysvid.clear();
106 | seq = 0;
107 | return SCREEN_DONE;
108 | } else {
109 | return SCREEN_RUNNING;
110 | }
111 | }
112 |
113 | /* local
114 | ********/
115 |
116 | /*
117 | * Display top and bottom borders (0x1B1F)
118 | *
119 | */
120 | function drawtb() {
121 | var i;
122 |
123 | flipflop++;
124 | if (flipflop & 0x01) {
125 | Draw.setfb(136, 16 + 16);
126 | for (i = 0; i < 6; i++) {
127 | Draw.tile(0x40);
128 | }
129 | Draw.setfb(136, 72 + 16);
130 | for (i = 0; i < 6; i++) {
131 | Draw.tile(0x06);
132 | }
133 | } else {
134 | Draw.setfb(136, 16 + 16);
135 | for (i = 0; i < 6; i++) {
136 | Draw.tile(0x05);
137 | }
138 | Draw.setfb(136, 72 + 16);
139 | for (i = 0; i < 6; i++) {
140 | Draw.tile(0x40);
141 | }
142 | }
143 | }
144 |
145 | /*
146 | * Display left and right borders (0x1B7C)
147 | *
148 | */
149 | function drawlr() {
150 | var i;
151 |
152 | if (flipflop & 0x02) {
153 | for (i = 0; i < 8; i++) {
154 | Draw.setfb(128, 16 + i * 8 + 16);
155 | Draw.tile(0x04);
156 | Draw.setfb(184, 16 + i * 8 + 16);
157 | Draw.tile(0x04);
158 | }
159 | } else {
160 | for (i = 0; i < 8; i++) {
161 | Draw.setfb(128, 16 + i * 8 + 16);
162 | Draw.tile(0x2B);
163 | Draw.setfb(184, 16 + i * 8 + 16);
164 | Draw.tile(0x2B);
165 | }
166 | }
167 | }
168 |
169 | /*
170 | * Draw the sprite (0x19C6)
171 | *
172 | */
173 | function drawsprite() {
174 | Draw.sprite(spnum, 136 + ((spx << 1) & 0x1C), 24 + (spy << 1) + 16);
175 | }
176 |
177 | /*
178 | * Draw the background (0x1AF1)
179 | *
180 | */
181 | function drawcenter() {
182 | var tn0 = [ 0x07, 0x5B, 0x7F, 0xA3, 0xC7 ],
183 | i, j, tn = tn0[Game.map];
184 |
185 | for (i = 0; i < 6; i++) {
186 | Draw.setfb(136, (24 + 8 * i) + 16);
187 | for (j = 0; j < 6; j++) {
188 | Draw.tile(tn++);
189 | }
190 | }
191 | }
192 |
193 | /*
194 | * Next Step (0x1A74)
195 | *
196 | */
197 | function nextstep() {
198 | if (Screen.imapsteps[step].count) {
199 | count = Screen.imapsteps[step].count;
200 | spdx = Screen.imapsteps[step].dx;
201 | spdy = Screen.imapsteps[step].dy;
202 | spbase = Screen.imapsteps[step].base;
203 | spoffs = 0;
204 | step++;
205 | } else {
206 | run = 0;
207 | }
208 | }
209 |
210 | /*
211 | * Anim (0x1AA8)
212 | *
213 | */
214 | function anim() {
215 | var i;
216 |
217 | if (run) {
218 | i = Screen.imapsl[spbase + spoffs];
219 | if (i == 0) {
220 | spoffs = 0;
221 | i = Screen.imapsl[spbase];
222 | }
223 | spnum = i;
224 | spoffs++;
225 | spx += spdx;
226 | spy += spdy;
227 | count--;
228 | if (count == 0) {
229 | nextstep();
230 | }
231 | }
232 | }
233 |
234 | function init() {
235 | run = 0; run--;
236 | step = Screen.imapsofs[Game.map];
237 | spx = Screen.imapsteps[step].dx;
238 | spy = Screen.imapsteps[step].dy;
239 | step++;
240 | spnum = 0; /* NOTE spnum in [8728] is never initialized ? */
241 | }
242 |
243 | /* EOF */
244 | })();
245 |
--------------------------------------------------------------------------------
/source/scr_pause.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | /*
4 | * Display the pause indicator
5 | */
6 | Screen.pause = function(pause) {
7 | if (pause == true) {
8 | Draw.tilesBank = 0;
9 | Draw.tllst = Screen.pausedtxt.split("");
10 | Draw.setfb(120, 80);
11 | Draw.tilesList();
12 | } else {
13 | Draw.map();
14 | Ent.draw();
15 | Draw.drawStatus();
16 | }
17 | Game.rects = [Draw.SCREENRECT];
18 | }
19 |
20 | /* EOF */
21 | })();
22 |
--------------------------------------------------------------------------------
/source/scr_xrick.js:
--------------------------------------------------------------------------------
1 | /* const
2 | ********/
3 | var SCREEN_RUNNING = 0,
4 | SCREEN_DONE = 1,
5 | SCREEN_EXIT = 2;
6 |
7 | (function() {
8 | /* local
9 | ********/
10 | var seq = 0,
11 | wait = 0;
12 |
13 | /* global
14 | *********/
15 | Screen.xrick = function(timer) {
16 |
17 | if (seq == 0) {
18 | Sysvid.clear();
19 | // draw_img(IMG_SPLASH);
20 | Game.rects = [Draw.SCREENRECT];
21 | seq = 1;
22 | }
23 |
24 | switch (seq) {
25 | case 1:
26 | if (wait++ > 0x2) {
27 | Syssnd.play("WAV_BULLET", 1);
28 | seq = 2;
29 | wait = 0;
30 | }
31 | break;
32 |
33 | case 2: /* wait */
34 | if (wait++ > 0x20) {
35 | seq = 99;
36 | wait = 0;
37 | }
38 | break;
39 | }
40 |
41 | if (Control.status & CONTROL_EXIT) { /* check for exit request */
42 | return SCREEN_EXIT;
43 | }
44 |
45 | if (seq == 99) { /* we're done */
46 | Sysvid.clear();
47 | Sysvid.setGamePalette();
48 | seq = 0;
49 | return SCREEN_DONE;
50 | }
51 |
52 | return SCREEN_RUNNING;
53 | }
54 |
55 | /* EOF */
56 | })();
57 |
--------------------------------------------------------------------------------
/source/screens.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/screens.h
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | /*
19 | * constants
20 | */
21 | var SCREEN_TIMEOUT = 4000;
22 |
--------------------------------------------------------------------------------
/source/scroller.js:
--------------------------------------------------------------------------------
1 | /* const
2 | ********/
3 | var SCROLL_RUNNING = 1,
4 | SCROLL_DONE = 0,
5 |
6 | SCROLL_PERIOD = 24;
7 |
8 |
9 | (function() {
10 | /* local
11 | ********/
12 | var period;
13 |
14 | /* global
15 | *********/
16 | /*
17 | * Scroll up
18 | *
19 | */
20 | var static_n1 = 0;
21 | Scroll.up = function() {
22 | var i, j;
23 |
24 | /* last call: restore */
25 | if (static_n1 == 8) {
26 | static_n1 = 0;
27 | Game.period = period;
28 | return SCROLL_DONE;
29 | }
30 |
31 | /* first call: prepare */
32 | if (static_n1 == 0) {
33 | period = Game.period;
34 | Game.period = SCROLL_PERIOD;
35 | }
36 |
37 | /* translate map */
38 | for (i = MAP_ROW_SCRTOP; i < MAP_ROW_HBBOT; i++) {
39 | for (j = 0x00; j < 0x20; j++) {
40 | World.map[i][j] = World.map[i + 1][j];
41 | }
42 | }
43 |
44 | /* translate entities */
45 | for (i = 0; Ent.ents[i].n != 0xFF; i++) {
46 | if (Ent.ents[i].n) {
47 | Ent.ents[i].ysave -= 8;
48 | Ent.ents[i].trig_y -= 8;
49 | Ent.ents[i].y -= 8;
50 | if (Ent.ents[i].y & 0x8000) { /* map coord. from 0x0000 to 0x0140 */
51 | /* IFDEBUG_SCROLLER(
52 | sys_printf("xrick/scroller: entity %#04X is gone\n", i);
53 | );*/
54 | Ent.ents[i].n = 0;
55 | }
56 | }
57 | }
58 |
59 | /* display */
60 | Draw.map();
61 | Ent.draw();
62 | Draw.drawStatus();
63 | World.frow++;
64 |
65 | /* loop */
66 | if (static_n1++ == 7) {
67 | /* activate visible entities */
68 | Ent.actvis(World.frow + MAP_ROW_HBTOP, World.frow + MAP_ROW_HBBOT);
69 |
70 | /* prepare map */
71 | World.expand();
72 |
73 | /* display */
74 | Draw.map();
75 | Ent.draw();
76 | Draw.drawStatus();
77 | }
78 |
79 | Game.rects = [Draw.SCREENRECT];
80 |
81 | return SCROLL_RUNNING;
82 | }
83 |
84 | /*
85 | * Scroll down
86 | *
87 | */
88 | var static_n2 = 0;
89 | Scroll.down =function() {
90 | var i, j;
91 |
92 | /* last call: restore */
93 | if (static_n2 == 8) {
94 | static_n2 = 0;
95 | Game.period = period;
96 | return SCROLL_DONE;
97 | }
98 |
99 | /* first call: prepare */
100 | if (static_n2 == 0) {
101 | period = Game.period;
102 | Game.period = SCROLL_PERIOD;
103 | }
104 |
105 | /* translate map */
106 | for (i = MAP_ROW_SCRBOT; i > MAP_ROW_HTTOP; i--) {
107 | for (j = 0x00; j < 0x20; j++) {
108 | World.map[i][j] = World.map[i - 1][j];
109 | }
110 | }
111 |
112 | /* translate entities */
113 | for (i = 0; Ent.ents[i].n != 0xFF; i++) {
114 | if (Ent.ents[i].n) {
115 | Ent.ents[i].ysave += 8;
116 | Ent.ents[i].trig_y += 8;
117 | Ent.ents[i].y += 8;
118 | if (Ent.ents[i].y > 0x0140) { /* map coord. from 0x0000 to 0x0140 */
119 | /* IFDEBUG_SCROLLER(
120 | sys_printf("xrick/scroller: entity %#04X is gone\n", i);
121 | );*/
122 | Ent.ents[i].n = 0;
123 | }
124 | }
125 | }
126 |
127 | /* display */
128 | Draw.map();
129 | Ent.draw();
130 | Draw.drawStatus();
131 | World.frow--;
132 |
133 | /* loop */
134 | if (static_n2++ == 7) {
135 | /* activate visible entities */
136 | Ent.actvis(World.frow + MAP_ROW_HTTOP, World.frow + MAP_ROW_HTBOT);
137 |
138 | /* prepare map */
139 | World.expand();
140 |
141 | /* display */
142 | Draw.map();
143 | Ent.draw();
144 | Draw.drawStatus();
145 | }
146 |
147 | Game.rects = [Draw.SCREENRECT];
148 |
149 | return SCROLL_RUNNING;
150 | }
151 |
152 | /* EOF */
153 | })();
154 |
--------------------------------------------------------------------------------
/source/sysarg.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/sysarg.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | (function() {
19 |
20 | Sysarg.args_map = 0;
21 | Sysarg.args_submap = 0;
22 |
23 | /*
24 | * Read and process arguments
25 | */
26 | Sysarg.init = function() {
27 | var argv = new G.CommandLine();
28 |
29 | if (argv.hasParam("map")) {
30 | //if (++i == argc) sysarg_fail("missing map number");
31 | Sysarg.args_map = parseInt(argv.getParam("map"), 10) - 1;
32 | // if (sysarg_args_map < 0 || sysarg_args_map >= MAP_NBR_MAPS-1)
33 | // sysarg_fail("invalid map number");
34 | }
35 |
36 | if (argv.hasParam("submap")) {
37 | // if (++i == argc) sysarg_fail("missing submap number");
38 | Sysarg.args_submap = parseInt(argv.getParam("submap"), 10) - 1;
39 | // if (sysarg_args_submap < 0 || sysarg_args_submap >= MAP_NBR_SUBMAPS)
40 | // sysarg_fail("invalid submap number");
41 | }
42 |
43 | /* this is dirty (sort of) */
44 | if (Sysarg.args_submap > 0 && Sysarg.args_submap < 9) {
45 | Sysarg.args_map = 0;
46 | }
47 |
48 | if (Sysarg.args_submap >= 9 && Sysarg.args_submap < 20) {
49 | Sysarg.args_map = 1;
50 | }
51 |
52 | if (Sysarg.args_submap >= 20 && Sysarg.args_submap < 38) {
53 | Sysarg.args_map = 2;
54 | }
55 |
56 | if (Sysarg.args_submap >= 38) {
57 | Sysarg.args_map = 3;
58 | }
59 |
60 | if (Sysarg.args_submap == 9 ||
61 | Sysarg.args_submap == 20 ||
62 | Sysarg.args_submap == 38) {
63 |
64 | Sysarg.args_submap = 0;
65 | }
66 | }
67 |
68 | /* EOF */
69 | })();
70 |
--------------------------------------------------------------------------------
/source/sysevt.js:
--------------------------------------------------------------------------------
1 |
2 | (function() {
3 | /* local
4 | ********/
5 | var gamepad, MAN = G.EventManager,
6 | eventMan = new G.EventManager(MAN.BIT_KEYBOARD/*|MAN.BIT_KBICADE*/);
7 |
8 | function TSTBIT(b) {
9 | return (Control.status && b) == b;
10 | }
11 | function SETBIT(b) {
12 | Control.status |= (b);
13 | }
14 | function CLRBIT(b) {
15 | Control.status &= ~(b);
16 | }
17 |
18 | function processGamepad() {
19 | if (!gamepad) { return; }
20 |
21 | CLRBIT(CONTROL_UP);
22 | CLRBIT(CONTROL_DOWN);
23 | CLRBIT(CONTROL_LEFT);
24 | CLRBIT(CONTROL_RIGHT);
25 | CLRBIT(CONTROL_FIRE);
26 |
27 | if (gamepad.buttons[0]) {
28 | SETBIT(CONTROL_FIRE);
29 | }
30 |
31 | if (gamepad.axes[0] || gamepad.axes[1]) {
32 | var v = new G.Vector(gamepad.axes[0], gamepad.axes[1]),
33 | a = v.getAngle() * 180 / Math.PI,
34 | s = v.getLength();
35 |
36 | a = (a + 22.5) % 360 / 45 | 0;
37 |
38 | if (a == 0) {
39 | SETBIT(CONTROL_UP);
40 | } else if (a == 1) {
41 | SETBIT(CONTROL_UP);
42 | SETBIT(CONTROL_RIGHT);
43 | } else if (a == 2) {
44 | SETBIT(CONTROL_RIGHT);
45 | } else if (a == 3) {
46 | SETBIT(CONTROL_RIGHT);
47 | SETBIT(CONTROL_DOWN);
48 | } else if (a == 4) {
49 | SETBIT(CONTROL_DOWN);
50 | } else if (a == 5) {
51 | SETBIT(CONTROL_DOWN);
52 | SETBIT(CONTROL_LEFT);
53 | } else if (a == 6) {
54 | SETBIT(CONTROL_LEFT);
55 | } else if (a == 7) {
56 | SETBIT(CONTROL_LEFT);
57 | SETBIT(CONTROL_UP);
58 | }
59 | }
60 | }
61 |
62 | function processEvent(event) {
63 | var key, E = G.Event;
64 |
65 | switch (event.type) {
66 | case E.KEYDOWN:
67 | key = event.keyCode;
68 |
69 | if (key == E.K_UP || key == E.K_ICADE_UP) {
70 | SETBIT(CONTROL_UP);
71 | Control.last = CONTROL_UP;
72 |
73 | } else if (key == E.K_DOWN || key == E.K_ICADE_DOWN) {
74 | SETBIT(CONTROL_DOWN);
75 | Control.last = CONTROL_DOWN;
76 |
77 | } else if (key == E.K_LEFT || key == E.K_ICADE_LEFT) {
78 | SETBIT(CONTROL_LEFT);
79 | Control.last = CONTROL_LEFT;
80 |
81 | } else if (key == E.K_RIGHT || key == E.K_ICADE_RIGHT) {
82 | SETBIT(CONTROL_RIGHT);
83 | Control.last = CONTROL_RIGHT;
84 |
85 | } else if (key == 'P'.charCodeAt(0) || key == E.K_ICADE_FIRE4) {
86 | SETBIT(CONTROL_PAUSE);
87 | Control.last = CONTROL_PAUSE;
88 |
89 | } else if (key == E.K_ESCAPE || key == E.K_ICADE_FIREX2) {
90 | SETBIT(CONTROL_END);
91 | Control.last = CONTROL_END;
92 | /*
93 | } else if (key == syskbd_xtra) {
94 | SETBIT(CONTROL_EXIT);
95 | Control.last = CONTROL_EXIT;
96 | */
97 | } else if (key == E.K_SPACE || key == E.K_ICADE_FIRE1) {
98 | SETBIT(CONTROL_FIRE);
99 | Control.last = CONTROL_FIRE;
100 | }
101 | break;
102 |
103 | case E.KEYUP:
104 | key = event.keyCode;
105 |
106 | if (key == E.K_UP || key == E.K_ICADE_UP) {
107 | CLRBIT(CONTROL_UP);
108 | Control.last = CONTROL_UP;
109 |
110 | } else if (key == E.K_DOWN || key == E.K_ICADE_DOWN) {
111 | CLRBIT(CONTROL_DOWN);
112 | Control.last = CONTROL_DOWN;
113 |
114 | } else if (key == E.K_LEFT || key == E.K_ICADE_LEFT) {
115 | CLRBIT(CONTROL_LEFT);
116 | Control.last = CONTROL_LEFT;
117 |
118 | } else if (key == E.K_RIGHT || key == E.K_ICADE_RIGHT) {
119 | CLRBIT(CONTROL_RIGHT);
120 | Control.last = CONTROL_RIGHT;
121 |
122 | } else if (key == 'P'.charCodeAt(0) || key == E.K_ICADE_FIRE4) {
123 | CLRBIT(CONTROL_PAUSE);
124 | Control.last = CONTROL_PAUSE;
125 |
126 | } else if (key == 'S'.charCodeAt(0) || key == E.K_ICADE_FIREX1) {
127 | Sysvid.toggle_scanlines();
128 |
129 | } else if (key == E.K_ESCAPE || key == E.K_ICADE_FIREX2) {
130 | CLRBIT(CONTROL_END);
131 | Control.last = CONTROL_END;
132 | /*
133 | } else if (key == syskbd_xtra) {
134 | CLRBIT(CONTROL_EXIT);
135 | Control.last = CONTROL_EXIT;
136 | */
137 | } else if (key == E.K_SPACE || key == E.K_ICADE_FIRE1) {
138 | CLRBIT(CONTROL_FIRE);
139 | Control.last = CONTROL_FIRE;
140 | }
141 | break;
142 | }
143 | }
144 |
145 | /* global
146 | *********/
147 | Sysevt.init = function() {
148 | /* var pad = document.getElementById("gamepad"),
149 | s1, s2, S = G.Shape;
150 |
151 | if (G.TouchGamepad.isSupported()) {
152 | pad.style.display = "block";
153 | gamepad = new G.TouchGamepad("pad", pad);
154 | if (pad.offsetHeight == 120) {
155 | s1 = new G.Circle(65, 0, 55);
156 | s2 = new G.Circle(-50, 0, 30);
157 | } else {
158 | s1 = new G.Circle(100, 0, 90);
159 | s2 = new G.Circle(-100, 0, 40);
160 | }
161 | gamepad.addAxes(s1, S.ALIGN_LEFT | S.ALIGN_MIDDLE);
162 | gamepad.addButton(s2, S.ALIGN_RIGHT | S.ALIGN_MIDDLE);
163 | gamepad.setActive(true);
164 | }
165 | */
166 | }
167 |
168 | Sysevt.poll = function() {
169 | var e;
170 |
171 | if (!gamepad || (!gamepad.connected)) {
172 | while ((e = eventMan.poll())) {
173 | processEvent(e);
174 | }
175 | } else {
176 | processGamepad();
177 | }
178 | }
179 |
180 | Sysevt.wait = function() {
181 | Sysevt.poll();
182 | }
183 |
184 | /* EOF */
185 | })();
186 |
--------------------------------------------------------------------------------
/source/syssnd.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/syssnd.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | (function() {
19 |
20 | var mixer,
21 | A = G.AudioMixer;
22 |
23 | Syssnd.init = function() {
24 | mixer = Snd.mixer;
25 | }
26 |
27 | /*
28 | * Play a sound
29 | *
30 | * loop: number of times the sound should be played, -1 to loop forever
31 | * returns: channel number, or -1 if none was available
32 | *
33 | * NOTE if sound is already playing, simply reset it (i.e. can not have
34 | * twice the same sound playing -- tends to become noisy when too many
35 | * bad guys die at the same time).
36 | */
37 | Syssnd.play = function(name, loop) {
38 | // TODO
39 | var snd = Snd.getItem(name);
40 | if (snd) {
41 | //snd.play(G.Convert.toUInt16(loop));
42 | mixer.play(snd, G.Convert.toUint16(loop) - 1);
43 | }
44 | }
45 |
46 | /*
47 | * Pause
48 | *
49 | * pause: TRUE or FALSE
50 | * clear: TRUE to cleanup all sounds and make sure we start from scratch
51 | */
52 | Syssnd.pause = function(pause, clear) {
53 | // TODO
54 | }
55 |
56 | /*
57 | * Stop a sound
58 | */
59 | Syssnd.stopsound = function(sound) {
60 | mixer.stopAll();
61 | /* if (!sound) { return; }
62 | var mus = Snd.getItem(sound);
63 | if (mus) {
64 | mus.pause();
65 | }*/
66 | }
67 |
68 | /*
69 | * Load a sound.
70 | */
71 | Syssnd.load = function(name) {
72 | return name;
73 | }
74 |
75 | /* EOF */
76 | })();
77 |
--------------------------------------------------------------------------------
/source/system.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | var timer;
4 |
5 | /*
6 | * Return number of microseconds elapsed since first call
7 | */
8 | var ticks_base = 0; // static
9 | Sys.gettime = function() {
10 | var ticks;
11 |
12 | ticks = Date.now();
13 |
14 | if (!ticks_base) {
15 | ticks_base = ticks;
16 | }
17 |
18 | return ticks - ticks_base;
19 | }
20 |
21 | /*
22 | * Sleep a number of microseconds
23 | */
24 | Sys.sleep = function(s) {
25 | // Game.timer.sleep(s);
26 | }
27 |
28 | /*
29 | * Initialize system
30 | */
31 | Sys.init = function() {
32 | Gamalto.core.setContainer("container");
33 | Sysarg.init();
34 | Sysvid.init();
35 | Sysevt.init();
36 | Syssnd.init();
37 | }
38 |
39 | /* EOF */
40 | })();
41 |
--------------------------------------------------------------------------------
/source/sysvid.js:
--------------------------------------------------------------------------------
1 | /* const
2 | ********/
3 | var SYSVID_WIDTH = 320;
4 | SYSVID_HEIGHT = 200;
5 |
6 | (function() {
7 | /* local
8 | ********/
9 | var screen, buffer, scanlines = false;
10 |
11 | /* global
12 | *********/
13 | Sysvid.SCREENRECT = new G.Rect(0, 0, SYSVID_WIDTH, SYSVID_HEIGHT);
14 |
15 | function init_screen(w, h/*, bpp, flags*/) {
16 | var s = new G.Screen(SYSVID_WIDTH, SYSVID_HEIGHT);
17 | G.Screen.setActive(s);
18 | s.enableFiltering(false);
19 | s.setStretch(s.STRETCH_UNIFORM);
20 | return s;
21 | }
22 |
23 | Sysvid.setPalette = function() {
24 | }
25 |
26 | Sysvid.restorePalette = function() {
27 | }
28 |
29 | Sysvid.setGamePalette = function() {
30 | // Sysvid.setPalette();
31 | }
32 |
33 | Sysvid.init = function() {
34 | screen = init_screen(SYSVID_WIDTH, SYSVID_HEIGHT);
35 | Sysvid.fb = new G.Surface(SYSVID_WIDTH, SYSVID_HEIGHT);
36 | buffer = Sysvid.fb;
37 | Sysvid.fader = new GE.Fader(Sysvid.fb, new G.Color(), 150);
38 | }
39 |
40 | Sysvid.fade_start = function() {
41 | Sysvid.fader.reset();
42 | buffer = Sysvid.fader.surface;
43 | }
44 |
45 | Sysvid.fade_end = function() {
46 | buffer = Sysvid.fb;
47 | }
48 |
49 | Sysvid.update = function(rects) {
50 | if (rects == null) {
51 | return;
52 | }
53 | screen.redraw(buffer, 0, 0, rects);
54 | screen.refresh();
55 | }
56 |
57 | Sysvid.toggle_scanlines = function(isOn) {
58 | scanlines = !scanlines;
59 | if (scanlines) {
60 | screen.setScanlines(50, 5);
61 | } else {
62 | screen.setScanlines();
63 | }
64 | }
65 |
66 | Sysvid.clear = function() {
67 | Sysvid.fb.renderer.fillRect(null, new G.Color(0,0,0));
68 | }
69 |
70 | /* EOF */
71 | })();
72 |
--------------------------------------------------------------------------------
/source/template.js:
--------------------------------------------------------------------------------
1 | /* const
2 | ********/
3 | // ...
4 |
5 | (function() {
6 | /* local
7 | ********/
8 | // ...
9 |
10 | /* global
11 | *********/
12 | // ...
13 |
14 |
15 | /* EOF */
16 | })();
17 |
--------------------------------------------------------------------------------
/source/tiles.js:
--------------------------------------------------------------------------------
1 | var TILES_BULLET = 0x01,
2 | TILES_BOMB = 0x02,
3 | TILES_RICK = 0x03;
4 |
--------------------------------------------------------------------------------
/source/util.js:
--------------------------------------------------------------------------------
1 |
2 | (function() {
3 |
4 | /*
5 | * Full box test.
6 | *
7 | * ASM 1199
8 | *
9 | * e: entity to test against.
10 | * x,y: coordinates to test.
11 | * ret: TRUE/(x,y) is within e's space, FALSE/not.
12 | */
13 | U.fboxtest = function(e, x, y) {
14 | if (Ent.ents[e].x >= x ||
15 | Ent.ents[e].x + Ent.ents[e].w < x ||
16 | Ent.ents[e].y >= y ||
17 | Ent.ents[e].y + Ent.ents[e].h < y) {
18 |
19 | return false;
20 | } else {
21 | return true;
22 | }
23 | }
24 |
25 | /*
26 | * Box test (then whole e2 is checked agains the center of e1).
27 | *
28 | * ASM 113E
29 | *
30 | * e1: entity to test against (corresponds to DI in asm code).
31 | * e2: entity to test (corresponds to SI in asm code).
32 | * ret: TRUE/intersect, FALSE/not.
33 | */
34 |
35 | U.boxtest = function(e1, e2) {
36 | /* rick is special (may be crawling) */
37 | if (e1 == E_RICK_NO) {
38 | return ERick.boxtest(e2);
39 | }
40 |
41 | /*
42 | * entity 1: x+0x05 to x+0x011, y to y+0x14
43 | * entity 2: x to x+ .w, y to y+ .h
44 | */
45 | if (Ent.ents[e1].x + 0x11 < Ent.ents[e2].x ||
46 | Ent.ents[e1].x + 0x05 > Ent.ents[e2].x + Ent.ents[e2].w ||
47 | Ent.ents[e1].y + 0x14 < Ent.ents[e2].y ||
48 | Ent.ents[e1].y > Ent.ents[e2].y + Ent.ents[e2].h - 1) {
49 |
50 | return false;
51 | } else {
52 | return true;
53 | }
54 | }
55 |
56 | /*
57 | * Compute the environment flag.
58 | *
59 | * ASM 0FBC if !crawl, else 103E
60 | *
61 | * x, y: coordinates where to compute the environment flag
62 | * crawl: is rick crawling?
63 | * rc0: anything CHANGED to the environment flag for crawling (6DBA)
64 | * rc1: anything CHANGED to the environment flag (6DAD)
65 | */
66 |
67 | U.envtest = function(x, y, crawl, rc0, rc1) {
68 |
69 | var i, xx;
70 |
71 | /* prepare for ent #0 test */
72 | Ent.ents[ENT_ENTSNUM].x = x;
73 | Ent.ents[ENT_ENTSNUM].y = y;
74 |
75 | i = 1;
76 | if (!crawl) i++;
77 | if (y & 0x0004) i++;
78 |
79 | x += 4;
80 | xx = x % 256; /* FIXME? */ // (U8)x
81 |
82 | x = x >> 3; /* from pixels to tiles */
83 | y = y >> 3; /* from pixels to tiles */
84 |
85 | rc0 = 0;
86 | rc1 = 0;
87 |
88 | if (xx & 0x07) { /* tiles columns alignment */
89 |
90 | if (crawl) {
91 | rc0 |= (World.eflg[World.map[y][x]] &
92 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
93 | rc0 |= (World.eflg[World.map[y][x + 1]] &
94 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
95 | rc0 |= (World.eflg[World.map[y][x + 2]] &
96 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
97 | y++;
98 | }
99 |
100 | do {
101 | rc1 |= (World.eflg[World.map[y][x]] &
102 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
103 | MAP_EFLG_LETHAL|MAP_EFLG_01));
104 | rc1 |= (World.eflg[World.map[y][x + 1]] &
105 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
106 | MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
107 | rc1 |= (World.eflg[World.map[y][x + 2]] &
108 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
109 | MAP_EFLG_LETHAL|MAP_EFLG_01));
110 | y++;
111 | } while (--i > 0);
112 |
113 | rc1 |= (World.eflg[World.map[y][x]] &
114 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP|MAP_EFLG_FGND|
115 | MAP_EFLG_LETHAL|MAP_EFLG_01));
116 | rc1 |= (World.eflg[World.map[y][x + 1]]);
117 | rc1 |= (World.eflg[World.map[y][x + 2]] &
118 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP|MAP_EFLG_FGND|
119 | MAP_EFLG_LETHAL|MAP_EFLG_01));
120 | } else {
121 |
122 | if (crawl) {
123 | rc0 |= (World.eflg[World.map[y][x]] &
124 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
125 | rc0 |= (World.eflg[World.map[y][x + 1]] &
126 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
127 | y++;
128 | }
129 |
130 | do {
131 | rc1 |= (World.eflg[World.map[y][x]] &
132 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
133 | MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
134 | rc1 |= (World.eflg[World.map[y][x + 1]] &
135 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
136 | MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
137 | y++;
138 | } while (--i > 0);
139 |
140 | rc1 |= (World.eflg[World.map[y][x]]);
141 | rc1 |= (World.eflg[World.map[y][x + 1]]);
142 | }
143 |
144 | /*
145 | * If not lethal yet, and there's an entity on slot zero, and (x,y)
146 | * boxtests this entity, then raise SOLID flag. This is how we make
147 | * sure that no entity can move over the entity that is on slot zero.
148 | *
149 | * Beware! When game_cheat2 is set, this means that a block can
150 | * move over rick without killing him -- but then rick is trapped
151 | * because the block is solid.
152 | */
153 | if (!(rc1 & MAP_EFLG_LETHAL)
154 | && Ent.ents[0].n
155 | && U.boxtest(ENT_ENTSNUM, 0)) {
156 |
157 | rc1 |= MAP_EFLG_SOLID;
158 | }
159 |
160 | return { rc0: rc0, rc1: rc1 };
161 | }
162 |
163 | /*
164 | * Check if x,y is within e trigger box.
165 | *
166 | * ASM 126F
167 | * return: FALSE if not in box, TRUE if in box.
168 | */
169 | U.trigbox = function(e, x, y) {
170 | var xmax, ymax;
171 |
172 | xmax = Ent.ents[e].trig_x + (Ent.entdata[Ent.ents[e].n & 0x7F].trig_w << 3);
173 | ymax = Ent.ents[e].trig_y + (Ent.entdata[Ent.ents[e].n & 0x7F].trig_h << 3);
174 |
175 | if (xmax > 0xFF) xmax = 0xFF;
176 |
177 | if (x <= Ent.ents[e].trig_x || x > xmax ||
178 | y <= Ent.ents[e].trig_y || y > ymax) {
179 | return false;
180 | } else {
181 | return true;
182 | }
183 | }
184 |
185 |
186 | /* EOF */
187 | })();
188 |
--------------------------------------------------------------------------------
/source/xrick.debug.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | var all = document.getElementsByTagName('script'),
4 | path = all[all.length - 1].src,
5 | dir = path.substr(0, path.indexOf("xrick.debug.js"));
6 |
7 | document.write(' \
8 | \
9 | \
10 | \
11 | \
12 | \
13 | \
14 | \
15 | \
16 | \
17 | \
18 | \
19 | \
20 | \
21 | \
22 | \
23 | \
24 | \
25 | \
26 | \
27 | \
28 | \
29 | \
30 | \
31 | \
32 | \
33 | \
34 | \
35 | \
36 | \
37 | \
38 | \
39 | \
40 | \
41 | ');
42 |
43 | })();
44 |
--------------------------------------------------------------------------------
/source/xrick.js:
--------------------------------------------------------------------------------
1 | var G = Gamalto;
2 | var GE = G.Effects;
3 | // Fix problem with use of old version of Gamalto (and some internal problems too...)
4 | G.Vector = G.Vector2;
5 |
6 | var
7 |
8 | Sys = {},
9 | Game = {},
10 | Screen = {},
11 | Sysvid = {},
12 | World = {},
13 | Draw = {},
14 | Tiles = {},
15 | Control = {},
16 | Sysevt = {},
17 | Sysarg = {},
18 | Syssnd = {} ,
19 | Sprites = {},
20 | ERick = {},
21 | Ent = {},
22 | EBullet = {},
23 | EBomb = {},
24 | EThem = {},
25 | EBox = {},
26 | EBonus = {},
27 | ESbonus = {},
28 | U = {},
29 | Rects = {},
30 | Scroll = {},
31 |
32 | Data,
33 | XRick = {
34 |
35 | main: function() {
36 | Sys.init();
37 | Game.run();
38 | },
39 |
40 | init: function() {
41 | var nb = 0;
42 |
43 | Data = new G.BitmapLibrary();
44 | var mixer = G.AudioMixer.create(4, G.AudioMixer.MIX_HTML5AUDIO);
45 | Snd = new G.SoundPool(mixer);
46 |
47 | Data.pushItem("pic_splash", "data/title.png");
48 | Data.pushItem("pic_haf", "data/haf.png");
49 | Data.pushItem("pic_congrat", "data/congrat.png");
50 | Data.pushItem("tiles_data", "data/tiles.png");
51 | Data.pushItem("sprites_data", "data/sprites.png");
52 |
53 | Data.load().then(function() {
54 | // var pool = G.SoundPool;
55 | // var ext = pool.isSupported(pool.MP3) ? ".mp3" :
56 | // pool.isSupported(pool.WAVE) ? ".wav" : ".ogg";
57 |
58 | var ext = ".mp3";
59 |
60 | Snd.pushItem("WAV_GAMEOVER", "sound/gameover" + ext);
61 | Snd.pushItem("WAV_SBONUS2", "sound/sbonus2" + ext);
62 | Snd.pushItem("WAV_BULLET", "sound/bullet" + ext);
63 | Snd.pushItem("WAV_BOMBSHHT", "sound/bombshht" + ext);
64 | Snd.pushItem("WAV_EXPLODE", "sound/explode" + ext);
65 | Snd.pushItem("WAV_STICK", "sound/stick" + ext);
66 | Snd.pushItem("WAV_WALK", "sound/walk" + ext);
67 | Snd.pushItem("WAV_CRAWL", "sound/crawl" + ext);
68 | Snd.pushItem("WAV_JUMP", "sound/jump" + ext);
69 | Snd.pushItem("WAV_PAD", "sound/pad" + ext);
70 | Snd.pushItem("WAV_BOX", "sound/box" + ext);
71 | Snd.pushItem("WAV_BONUS", "sound/bonus" + ext);
72 | Snd.pushItem("WAV_SBONUS1", "sound/sbonus1" + ext);
73 | Snd.pushItem("WAV_DIE", "sound/die" + ext);
74 | Snd.pushItem("WAV_ENTITY0", "sound/ent0" + ext);
75 | Snd.pushItem("WAV_ENTITY1", "sound/ent1" + ext);
76 | Snd.pushItem("WAV_ENTITY2", "sound/ent2" + ext);
77 | Snd.pushItem("WAV_ENTITY3", "sound/ent3" + ext);
78 | Snd.pushItem("WAV_ENTITY4", "sound/ent4" + ext);
79 | Snd.pushItem("WAV_ENTITY5", "sound/ent5" + ext);
80 | Snd.pushItem("WAV_ENTITY6", "sound/ent6" + ext);
81 | Snd.pushItem("WAV_ENTITY7", "sound/ent7" + ext);
82 | Snd.pushItem("WAV_ENTITY8", "sound/ent8" + ext);
83 |
84 | Snd.pushItem("WAV_TUNE0", "sound/tune0" + ext);
85 | Snd.pushItem("WAV_TUNE1", "sound/tune1" + ext);
86 | Snd.pushItem("WAV_TUNE2", "sound/tune2" + ext);
87 | Snd.pushItem("WAV_TUNE3", "sound/tune3" + ext);
88 | Snd.pushItem("WAV_TUNE4", "sound/tune4" + ext);
89 | Snd.pushItem("WAV_TUNE5", "sound/tune5" + ext);
90 |
91 | return Snd.load();
92 |
93 | }, function(e) {
94 | console.log("error", e);
95 | }).then(function() {
96 |
97 | Snd.getItem("WAV_STICK").priority = -1;
98 | Snd.getItem("WAV_WALK").priority = -1;
99 | Snd.getItem("WAV_CRAWL").priority = -1;
100 | Snd.getItem("WAV_JUMP").priority = -1;
101 |
102 |
103 | var size = new G.Size(8, 8);
104 | Tiles.data = [];
105 | Tiles.data[0] = new G.TileSet(Data.getItem("tiles_data"), size).addSections(256, new G.Rect(0, 0 * 8 * 256, 8, 8 * 256));
106 | Tiles.data[1] = new G.TileSet(Data.getItem("tiles_data"), size).addSections(256, new G.Rect(0, 1 * 8 * 256, 8, 8 * 256));
107 | Tiles.data[2] = new G.TileSet(Data.getItem("tiles_data"), size).addSections(256, new G.Rect(0, 2 * 8 * 256, 8, 8 * 256));
108 |
109 | Sprites.data = new G.SpriteSheet(Data.getItem("sprites_data")).addSections(new G.Size(32, 21), SPRITES_NBR_SPRITES);
110 |
111 | XRick.main();
112 | }, function(e) {
113 | console.log("error2", e);
114 | });
115 |
116 | Sysarg.args_map = 0;
117 | Sysarg.args_submap = 0;
118 | }
119 |
120 | };
121 |
122 | Gamalto.core.init(XRick.init);
123 |
--------------------------------------------------------------------------------
/src/c.js:
--------------------------------------------------------------------------------
1 | export function create_struct(props, values, base) {
2 | const struct = base || {};
3 | for (let i = 0; i < values.length; i++) {
4 | struct[props[i]] = values[i];
5 | }
6 | return struct;
7 | }
8 |
9 | export function as_const(obj) {
10 | return Object.freeze(obj);
11 | }
12 |
13 | export function create_array(...sizes) {
14 | const result = Array(sizes[0]);
15 |
16 | if (sizes.length === 2) {
17 | for (let i = 0; i < result.length; i++) {
18 | result[i] = Array(sizes[1]);
19 | }
20 | }
21 |
22 | return result;
23 | }
24 |
25 | export function sprintf(s, format, ...vargs) {
26 | const result = format.replace(/{(\d+)}/g, (match, capture) => {
27 | const index = Number(capture);
28 | return index < vargs.length ? vargs[index] : match;
29 | });
30 | for (let i = 0; i < Math.min(s.length, result.length); i++) {
31 | s[i] = result[i];
32 | }
33 | }
34 |
35 | export function plusplus(arr) {
36 | const c = arr.shift();
37 | return typeof c === "number" ? c : c.charCodeAt(0);
38 | }
39 |
40 | export function $(obj) {
41 | return {...obj};
42 | }
43 |
44 | export function _STR(arr) {
45 | return arr.reduce((r, c) => r + String.fromCharCode(c), "");
46 | }
47 |
48 | export function _U8(val) {
49 | return val & 0xff;
50 | }
51 |
52 | export function _S16(val) {
53 | return G.Convert.toInt16(val);
54 | }
55 |
56 | export function _U16(val) {
57 | return G.Convert.toUint16(val);
58 | }
59 |
--------------------------------------------------------------------------------
/src/control.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/control.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012-2022 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | export const control = {
19 | status: 0,
20 | last: 0,
21 | active: true
22 | };
23 |
24 | /* eof */
25 |
26 |
--------------------------------------------------------------------------------
/src/dat_loader.js:
--------------------------------------------------------------------------------
1 | import { pic_congrats, pic_haf, pic_splash } from "./dat_picST";
2 | import { sprites_data, sprites_init } from "./dat_spritesST";
3 | import { tiles_data, tiles_init } from "./dat_tilesST";
4 |
5 | const path = "../data";
6 | let data;
7 |
8 | export async function dat_init() {
9 | data = new G.BitmapLibrary();
10 |
11 | data.pushItem(pic_congrats, `${path}/congrat.png`);
12 | data.pushItem(pic_haf, `${path}/haf.png`);
13 | data.pushItem(pic_splash, `${path}/title.png`);
14 |
15 | data.pushItem(tiles_data, `${path}/tiles.png`);
16 | data.pushItem(sprites_data, `${path}/sprites.png`);
17 |
18 | await data.load();
19 |
20 | tiles_init(dat_get(tiles_data));
21 | sprites_init(dat_get(sprites_data));
22 | }
23 |
24 | export function dat_get(name) {
25 | return data.getItem(name);
26 | }
27 |
--------------------------------------------------------------------------------
/src/dat_picST.js:
--------------------------------------------------------------------------------
1 |
2 | export const pic_congrats = "picCongrats";
3 | export const pic_haf = "PicHoF";
4 | export const pic_splash = "splashScreen";
5 |
--------------------------------------------------------------------------------
/src/dat_screens.js:
--------------------------------------------------------------------------------
1 | import { screen_imapsteps_t } from "../include/screens";
2 |
3 | /*
4 | * map intro, sprites lists
5 | */
6 | export const screen_imapsl = [
7 | 0x1b, 0x00,
8 | 0x1c, 0x1d, 0x00,
9 | 0x01, 0x00,
10 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x00,
11 | 0x1e, 0x00,
12 | 0x0d, 0x00,
13 | 0x13, 0x14, 0x00,
14 | 0x1f, 0x00
15 | ];
16 |
17 | /*
18 | * map intro, steps
19 | */
20 | export const screen_imapsteps = [
21 | screen_imapsteps_t( 0x0000, 0x0002, 0x0002, 0x0000 ),
22 |
23 | screen_imapsteps_t( 0x000b, 0x0000, 0x0001, 0x0000 ),
24 | screen_imapsteps_t( 0x0008, 0x0001, 0x0000, 0x0002 ),
25 |
26 | screen_imapsteps_t( 0x0000, 0x0000, 0x000c, 0x0000 ),
27 |
28 | screen_imapsteps_t( 0x000a, 0x0000, 0x0000, 0x0005 ),
29 | screen_imapsteps_t( 0x0006, 0x0002, 0x0000, 0x0007 ),
30 | screen_imapsteps_t( 0x0005, 0x0000, 0x0000, 0x0005 ),
31 |
32 | screen_imapsteps_t( 0x0000, 0x0006, 0x0000, 0x0000 ),
33 |
34 | screen_imapsteps_t( 0x000c, 0x0000, 0x0001, 0x0000 ),
35 | screen_imapsteps_t( 0x0005, 0x0000, 0x0000, 0x000d ),
36 |
37 | screen_imapsteps_t( 0x0000, 0x000c, 0x000c, 0x0000 ),
38 |
39 | screen_imapsteps_t( 0x0005, 0x0000, 0x0000, 0x0005 ),
40 | screen_imapsteps_t( 0x000a, 0x0000, 0x0000, 0x000f ),
41 | screen_imapsteps_t( 0x000c, 0xffff, 0x0000, 0x0011 ),
42 | screen_imapsteps_t( 0x0005, 0x0000, 0x0000, 0x000f ),
43 |
44 | screen_imapsteps_t( 0x0000, 0x0006, 0x0001, 0x0000 ),
45 |
46 | screen_imapsteps_t( 0x000a, 0x0000, 0x0000, 0x0014 ),
47 | screen_imapsteps_t( 0x0006, 0x0000, 0x0001, 0x0014 ),
48 | screen_imapsteps_t( 0x0005, 0x0000, 0x0000, 0x0014 ),
49 | screen_imapsteps_t( 0x0003, 0x0001, 0x0000, 0x0014 ),
50 | screen_imapsteps_t( 0x0006, 0xffff, 0x0000, 0x0014 ),
51 | screen_imapsteps_t( 0x0003, 0x0000, 0xffff, 0x0014 ),
52 |
53 | screen_imapsteps_t( 0x0000, 0x0000, 0x0000, 0x0000 )
54 | ];
55 |
56 | /*
57 | * map intro, step offset per map
58 | */
59 | export const screen_imapsofs = [
60 | 0x00, 0x03, 0x07, 0x0a, 0x0f
61 | ];
62 |
63 | /*
64 | * map intro, text
65 | * (from ds + 0x8810 + 0x2000, 0x2138, 0x2251, 0x236a, 0x2464)
66 | *
67 | * \xFE=0xfe \xFF=0xff
68 | */
69 | const screen_imaptext_amazon = "\
70 | @@@@@SOUTH@AMERICA@1945@@@@@@@\xFF\
71 | RICK@DANGEROUS@CRASH@LANDS@HIS\xFF\
72 | @PLANE@OVER@THE@AMAZON@WHILE@@\xFF\
73 | @SEARCHING@FOR@THE@LOST@GOOLU@\xFF\
74 | @@@@@@@@@@@@TRIBE.@@@@@@@@@@@@\xFF\xFF\
75 | @BUT,@BY@A@TERRIBLE@TWIST@OF@@\xFF\
76 | FATE@HE@LANDS@IN@THE@MIDDLE@OF\xFF\
77 | @@@A@BUNCH@OF@WILD@GOOLUS.@@@@\xFF\xFF\
78 | @@CAN@RICK@ESCAPE@THESE@ANGRY@\xFF\
79 | @@@AMAZONIAN@ANTAGONISTS@?@@@@\xFE";
80 |
81 | const screen_imaptext_egypt = "\
82 | @@@@EGYPT,@SOMETIMES@LATER@@@@\xFF\
83 | RICK@HEADS@FOR@THE@PYRAMIDS@AT\xFF\
84 | @@@@THE@REQUEST@OF@LONDON.@@@@\xFF\xFF\
85 | HE@IS@TO@RECOVER@THE@JEWEL@OF@\xFF\
86 | ANKHEL@THAT@HAS@BEEN@STOLEN@BY\xFF\
87 | FANATICS@WHO@THREATEN@TO@SMASH\xFF\
88 | @IT,@IF@A@RANSOM@IS@NOT@PAID.@\xFF\xFF\
89 | CAN@RICK@SAVE@THE@GEM,@OR@WILL\xFF\
90 | HE@JUST@GET@A@BROKEN@ANKHEL@?@\xFE";
91 |
92 | const screen_imaptext_castle = "\
93 | @@@@EUROPE,@LATER@THAT@WEEK@@@\xFF\
94 | @@RICK@RECEIVES@A@COMMUNIQUE@@\xFF\
95 | @@FROM@BRITISH@INTELLIGENCE@@@\xFF\
96 | @@ASKING@HIM@TO@RESCUE@ALLIED@\xFF\
97 | @PRISONERS@FROM@THE@NOTORIOUS@\xFF\
98 | @@@@SCHWARZENDUMPF@CASTLE.@@@@\xFF\xFF\
99 | @@RICK@ACCEPTS@THE@MISSION.@@@\xFF\xFF\
100 | @@@BUT@CAN@HE@LIBERATE@THE@@@@\xFF\
101 | @CRUELLY@CAPTURED@COOMANDOS@?@\xFE";
102 |
103 | const screen_imaptext_missile = "\
104 | @@@@@@EUROPE,@EVEN@LATER@@@@@@\xFF\
105 | RICK@LEARNS@FROM@THE@PRISONERS\xFF\
106 | @THAT@THE@ENEMY@ARE@TO@LAUNCH@\xFF\
107 | AN@ATTACK@ON@LONDON@FROM@THEIR\xFF\
108 | @@@@@SECRET@MISSILE@BASE.@@@@@\xFF\xFF\
109 | WITHOUT@HESITATION,@HE@DECIDES\xFF\
110 | @@@TO@INFILTRATE@THE@BASE.@@@@\xFF\xFF\
111 | CAN@RICK@SAVE@LONDON@IN@TIME@?\xFE";
112 |
113 | const screen_imaptext_muchlater = "\
114 | @@@LONDON,@MUCH,@MUCH@LATER@@@\xFF\
115 | @RICK@RETURNS@TO@A@TRIUMPHANT@\xFF\
116 | @@WELCOME@HOME@HAVING@HELPED@@\xFF\
117 | @@@@SECURE@ALLIED@VICTORY.@@@@\xFF\xFF\
118 | BUT,@MEANWHILE,@IN@SPACE,@THE@\xFF\
119 | @@@MASSED@STARSHIPS@OF@THE@@@@\xFF\
120 | @@@BARFIAN@EMPIRE@ARE@POISED@@\xFF\
121 | @@@@@TO@INVADE@THE@EARTH.@@@@@\xFF\xFF\
122 | @WHAT@WILL@RICK@DO@NEXT@...@?@\xFE";
123 |
124 | export const screen_imaptext =
125 | [ screen_imaptext_amazon,
126 | screen_imaptext_egypt,
127 | screen_imaptext_castle,
128 | screen_imaptext_missile,
129 | screen_imaptext_muchlater
130 | ].map((s) => s.split(''));
131 |
132 | /*
133 | * main intro, hall of fame title
134 | * (from ds + 0x8810 + 0x2642)
135 | */
136 | export const screen_imainhoft =
137 | [ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0xd4, 0xb7, 0xb1,
138 | 0xac, 0xc6, 0x2f, 0xc6, 0x2f, 0x2f, 0xa4, 0xac,
139 | 0x9b, 0xc1, 0x2f, 0x9b, 0xc1, 0xb1, 0xac, 0xb6,
140 | 0xbd, 0x9b, 0xc1, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
141 | 0xff,
142 | 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0xb2, 0xb3, 0xb2,
143 | 0xb3, 0xad, 0x2f, 0xad, 0x2f, 0x2f, 0xa6, 0xae,
144 | 0xc2, 0xc3, 0x2f, 0xc2, 0xc3, 0xb2, 0xb3, 0xbe,
145 | 0xbf, 0xc2, 0xc3, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
146 | 0xff,
147 | 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x9f, 0xc0, 0xb4,
148 | 0xb5, 0xaf, 0xc4, 0xaf, 0xc4, 0x2f, 0xa7, 0xb0,
149 | 0xb4, 0x2f, 0x2f, 0xb4, 0x2f, 0xb4, 0xb5, 0xb4,
150 | 0xb5, 0xaf, 0xc4, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
151 | 0xfe
152 | ];
153 |
154 | /*
155 | * main intro, Rick Dangerous title
156 | * (from ds + 0x8810 + 0x27a1)
157 | */
158 | export const screen_imainrdt =
159 | [ 0x2f, 0x2f, 0x2f, 0x9b, 0x9c, 0xa1, 0xa4, 0xa5,
160 | 0xa9, 0xaa, 0x2f, 0x9b, 0xac, 0xb1, 0xac, 0xb6,
161 | 0xb7, 0xa4, 0xa5, 0x9b, 0xc1, 0x9b, 0x9c, 0xa4,
162 | 0xac, 0xc6, 0xc7, 0xc8, 0xc9, 0x2f, 0x2f, 0x2f,
163 | 0xff,
164 | 0x2f, 0x2f, 0x2f, 0x9d, 0x9e, 0xa2, 0xa6, 0x2f,
165 | 0x9d, 0xab, 0x2f, 0xad, 0xae, 0xb2, 0xb3, 0xb8,
166 | 0xb9, 0xa6, 0xbb, 0xc2, 0xc3, 0x9d, 0x9e, 0xa6,
167 | 0xae, 0xad, 0xae, 0xca, 0xcb, 0x2f, 0x2f, 0x2f,
168 | 0xff,
169 | 0x2f, 0x2f, 0x2f, 0x9f, 0xa0, 0xa3, 0xa7, 0xa8,
170 | 0x9f, 0xa0, 0x2f, 0xaf, 0xb0, 0xb4, 0xb5, 0x9f,
171 | 0xba, 0xa7, 0xbc, 0xaf, 0xc4, 0x9f, 0xa0, 0xa7,
172 | 0xb0, 0xc5, 0xb0, 0xcc, 0xb0, 0x2f, 0x2f, 0x2f,
173 | 0xfe
174 | ];
175 |
176 | /*
177 | * congratulations
178 | * (from ds + 0x8810 + 0x257d)
179 | */
180 | export const screen_congrats =
181 | [ 0xa4, 0xa5, 0xa4, 0xac, 0xb6, 0xb7, 0xa4, 0xa5,
182 | 0x9b, 0x9c, 0xb1, 0xac, 0xcd, 0xce, 0xc6, 0xc7,
183 | 0xd3, 0x2f, 0xb1, 0xac, 0xcd, 0xce, 0xa1, 0xa4,
184 | 0xac, 0xb6, 0xb7, 0xc8, 0xc9, 0x2f, 0xd5, 0xd6,
185 | 0xff,
186 | 0xa6, 0x2f, 0xa6, 0xae, 0xb8, 0xb9, 0xa6, 0xbb,
187 | 0x9d, 0x9e, 0xb2, 0xb3, 0xcf, 0xd0, 0xad, 0xae,
188 | 0xad, 0x2f, 0xb2, 0xb3, 0xcf, 0xd0, 0xa2, 0xa6,
189 | 0xae, 0xb8, 0xb9, 0xca, 0xcb, 0x2f, 0xd7, 0xd8,
190 | 0xff,
191 | 0xa7, 0xa8, 0xa7, 0xb0, 0x9f, 0xba, 0xa7, 0xbc,
192 | 0x9f, 0xa0, 0xb4, 0xb5, 0xd1, 0xd2, 0xc5, 0xb0,
193 | 0xaf, 0xc4, 0xb4, 0xb5, 0xd1, 0xd2, 0xa3, 0xa7,
194 | 0xb0, 0x9f, 0xba, 0xcc, 0xb0, 0x2f, 0xd9, 0xda,
195 | 0xfe
196 | ];
197 |
198 | /*
199 | * main intro, Core Design copyright text
200 | * (from ds + 0x8810 + 0x2288)
201 | *
202 | * \xFE=0xfe \xFF=0xff
203 | */
204 | export const screen_imaincdc = "\
205 | @@@@@@@@@@@@@@@@@@@\xFF\xFF\
206 | (C)@1989@CORE@DESIGN\xFF\xFF\xFF\
207 | @PRESS@SPACE@TO@START\xFE".split('');
208 |
209 | /*
210 | * gameover
211 | * (from ds + 0x8810 + 0x2864)
212 | *
213 | * \xFE=0xfe \xFF=0xff
214 | */
215 | export const screen_gameovertxt = "\
216 | @@@@@@@@@@@\xFF\
217 | @GAME@OVER@\xFF\
218 | @@@@@@@@@@@\xFE".split('');
219 |
220 | /*
221 | * paused
222 | *
223 | * \xFE=0xfe \xFF=0xff
224 | */
225 | export const screen_pausedtxt = "\
226 | @@@@@@@@@@\xFF\
227 | @@PAUSED@@\xFF\
228 | @@@@@@@@@@\xFE".split('');
229 |
230 | /* eof */
231 |
232 |
233 |
234 |
--------------------------------------------------------------------------------
/src/dat_snd.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | export async function snd_init() {
4 | // TODO: see loaddata()
5 | }
6 |
--------------------------------------------------------------------------------
/src/dat_spritesST.js:
--------------------------------------------------------------------------------
1 | import { SPRITES_NBR_SPRITES } from "../include/sprites";
2 |
3 | export const sprites_data = "spritesData";
4 | export const sprites = {
5 | data: null
6 | };
7 |
8 | export function sprites_init(data) {
9 | sprites.data = new G.SpriteSheet(data).addSections(new G.Size(32, 21), SPRITES_NBR_SPRITES);
10 | }
11 |
--------------------------------------------------------------------------------
/src/dat_tilesST.js:
--------------------------------------------------------------------------------
1 |
2 | export const tiles_data = "tilesData";
3 | export const tiles = {
4 | data: []
5 | };
6 |
7 | export function tiles_init(data) {
8 | const size = new G.Size(8, 8);
9 | tiles.data[0] = new G.TileSet(data, size).addSections(256, new G.Rect(0, 0 * 8 * 256, 8, 8 * 256));
10 | tiles.data[1] = new G.TileSet(data, size).addSections(256, new G.Rect(0, 1 * 8 * 256, 8, 8 * 256));
11 | tiles.data[2] = new G.TileSet(data, size).addSections(256, new G.Rect(0, 2 * 8 * 256, 8, 8 * 256));
12 | }
13 |
--------------------------------------------------------------------------------
/src/draw.js:
--------------------------------------------------------------------------------
1 | import { as_const, plusplus, _S16 } from "./c";
2 | import { rect_t } from "../include/rects";
3 | import { SYSVID_WIDTH, SYSVID_HEIGHT } from "../include/system";
4 | import { dat_get } from "./dat_loader";
5 | import { tiles } from "./dat_tilesST";
6 | import { sprites } from "./dat_spritesST";
7 | import { sysvid } from "./sysvid";
8 | import { map } from "./maps";
9 | import { TILES_BULLET, TILES_BOMB, TILES_RICK } from "../include/tiles";
10 | import { game } from "./game";
11 | import { DRAW_XYMAP_HBTOP, DRAW_XYMAP_SCRLEFT, DRAW_XYMAP_SCRTOP } from "../include/draw";
12 |
13 | /*
14 | * counters positions (pixels, screen)
15 | */
16 | const DRAW_STATUS_BULLETS_X = 0x68;
17 | const DRAW_STATUS_BOMBS_X = 0xA8;
18 | //#ifdef GFXST
19 | const DRAW_STATUS_SCORE_X = 0x20;
20 | const DRAW_STATUS_LIVES_X = 0xF0;
21 | const DRAW_STATUS_Y = 0;
22 | //#endif
23 |
24 | /*
25 | * public vars
26 | */
27 | export const draw = {
28 | /*U8*/ tllst: 0, /* pointer to tiles list */
29 | /*U8*/ tilesBank: 0 /* tile number offset */
30 | };
31 | export const draw_STATUSRECT = rect_t(
32 | DRAW_STATUS_SCORE_X, DRAW_STATUS_Y,
33 | DRAW_STATUS_LIVES_X + 6 * 8 - DRAW_STATUS_SCORE_X, 8,
34 | null
35 | );
36 | export const draw_SCREENRECT = as_const(rect_t( 0, 0, SYSVID_WIDTH, SYSVID_HEIGHT, null ));
37 |
38 | /*
39 | * private vars
40 | */
41 | let fb = new G.Vector2(); /* frame buffer pointer */
42 |
43 |
44 |
45 | /*
46 | * Set the frame buffer pointer
47 | *
48 | * x, y: position (pixels, screen)
49 | */
50 | export function draw_setfb(x, y) {
51 | fb.x = x;
52 | fb.y = y;
53 | }
54 |
55 |
56 | /*
57 | * Clip to map screen
58 | *
59 | * x, y: position (pixels, map) CHANGED clipped
60 | * width, height: dimension CHANGED clipped
61 | * return: TRUE if fully clipped, FALSE if still (at least partly) visible
62 | */
63 | export function
64 | draw_clipms(x, y, width, height)
65 | {
66 | if (x < 0) {
67 | if (x + width < 0)
68 | return { returns: true, x, y, width, height };
69 | else {
70 | width += x;
71 | x = 0;
72 | }
73 | }
74 | else {
75 | if (x > 0x0100)
76 | return { returns: true, x, y, width, height };
77 | else if (x + width > 0x0100) {
78 | width = 0x0100 - x;
79 | }
80 | }
81 |
82 | if (y < DRAW_XYMAP_SCRTOP) {
83 | if ((y + height) < DRAW_XYMAP_SCRTOP)
84 | return { returns: true, x, y, width, height };
85 | else {
86 | height += y - DRAW_XYMAP_SCRTOP;
87 | y = DRAW_XYMAP_SCRTOP;
88 | }
89 | }
90 | else {
91 | if (y >= DRAW_XYMAP_HBTOP)
92 | return { returns: true, x, y, width, height };
93 | else if (y + height > DRAW_XYMAP_HBTOP)
94 | height = DRAW_XYMAP_HBTOP - y;
95 | }
96 |
97 | return { returns: false, x, y, width, height };
98 | }
99 |
100 |
101 | /*
102 | * Draw a list of tiles onto the frame buffer
103 | * start at position indicated by fb ; at the end of each (sub)list,
104 | * perform a "carriage return + line feed" i.e. go back to the initial
105 | * position then go down one tile row (8 pixels)
106 | *
107 | * ASM 1e33
108 | * fb: CHANGED (see above)
109 | * draw_tllst: CHANGED points to the element following 0xfe/0xff end code
110 | */
111 | export function draw_tilesList() {
112 | let t;
113 |
114 | t = fb.clone();
115 | while (draw_tilesSubList() !== 0xFE) { /* draw sub-list */
116 | t.y += 8/* * SYSVID_WIDTH*/; /* go down one tile i.e. 8 lines */
117 | fb = t.clone();
118 | }
119 | }
120 |
121 |
122 | /*
123 | * Draw a list of tiles onto the frame buffer -- same as draw_tilesList,
124 | * but accept an immediate string as parameter. Note that the string needs
125 | * to be properly terminated with 0xfe (\376) and 0xff (\377) chars.
126 | */
127 | export function
128 | draw_tilesListImm(list)
129 | {
130 | if (typeof list === "string") {
131 | list = list.split('');
132 | }
133 | draw.tllst = [...list];
134 | draw_tilesList();
135 | }
136 |
137 |
138 | /*
139 | * Draw a sub-list of tiles onto the frame buffer
140 | * start at position indicated by fb ; leave fb pointing to the next
141 | * tile to the right of the last tile drawn
142 | *
143 | * ASM 1e41
144 | * fpb: CHANGED (see above)
145 | * draw_tllst: CHANGED points to the element following 0xfe/0xff end code
146 | * returns: end code (0xfe : end of list ; 0xff : end of sub-list)
147 | */
148 | export function draw_tilesSubList() {
149 | let i;
150 |
151 | i = plusplus(draw.tllst);
152 | while (i !== 0xFF && i !== 0xFE) { /* while not end */
153 | draw_tile(i); /* draw tile */
154 | i = plusplus(draw.tllst);
155 | }
156 | return i;
157 | }
158 |
159 |
160 | /*
161 | * Draw a tile
162 | * at position indicated by fb ; leave fb pointing to the next tile
163 | * to the right of the tile drawn
164 | *
165 | * ASM 1e6c
166 | * tlnbr: tile number
167 | * draw_filter: CGA colors filter
168 | * fb: CHANGED (see above)
169 | */
170 | export function
171 | draw_tile(tileNumber)
172 | {
173 | tiles.data[draw.tilesBank].draw(sysvid.fb.renderer, fb.x, fb.y, tileNumber);
174 | fb.x += 8; /* next tile */
175 | }
176 |
177 |
178 | /*
179 | * Draw a sprite
180 | *
181 | * foobar
182 | */
183 | //#ifdef GFXST
184 | export function
185 | draw_sprite(number, x, y)
186 | {
187 | draw_setfb(x, y);
188 | sprites.data.draw(sysvid.fb.renderer, fb.x, fb.y, number);
189 | }
190 | //#endif
191 |
192 |
193 | /*
194 | * Draw a sprite
195 | *
196 | * NOTE re-using original ST graphics format
197 | */
198 | //#ifdef GFXST
199 | export function
200 | draw_sprite2(number, x, y, front)
201 | {
202 | let d = 0; /* sprite data */
203 | let x0, y0; /* clipped x, y */
204 | let w, h; /* width, height */
205 | let g, /* sprite data offset*/
206 | r, c, /* row, column */
207 | i, /* frame buffer shifter */
208 | im; /* tile flag shifter */
209 | let flg; /* tile flag */
210 | let tmp;
211 |
212 | x0 = x;
213 | y0 = y;
214 | w = 0x20;
215 | h = 0x15;
216 |
217 | if ((tmp = draw_clipms(x0, y0, w, h)).returns) /* return if not visible */
218 | return;
219 | x0 = tmp.x;
220 | y0 = tmp.y;
221 | w = tmp.width;
222 | h = tmp.height;
223 |
224 | g = 0;
225 | sysvid.fb.enableClipping(new G.Rect(x0 - DRAW_XYMAP_SCRLEFT, y0 - DRAW_XYMAP_SCRTOP + 8, w, h));
226 | draw_setfb(x0 - DRAW_XYMAP_SCRLEFT, y0 - DRAW_XYMAP_SCRTOP + 8);
227 | draw_sprite(number, fb.x, fb.y);
228 | sysvid.fb.disableClipping();
229 | /*
230 | for (r = 0; r < 0x15; r++) {
231 | if (r >= h || y + r < y0) continue;
232 |
233 | i = 0x1f;
234 | im = x - (x & 0xfff8);
235 | flg = map.eflg[map.map[(y + r) >> 3][(x + 0x1f)>> 3]];
236 |
237 | //#ifdef ENABLE_CHEATS
238 | function LOOP(N, C0, C1) {
239 | d = sprites.data[number][g + N];
240 | for (c = C0; c >= C1; c--, i--, d >>= 4, im--) {
241 | if (im == 0) {
242 | flg = map.eflg[map.map[(y + r) >> 3][(x + c) >> 3]];
243 | im = 8;
244 | }
245 | if (c >= w || x + c < x0) continue;
246 | if (!front && !game.cheat3 && (flg & MAP_EFLG_FGND)) continue;
247 | if (d & 0x0F) fb[i] = (fb[i] & 0xF0) | (d & 0x0F);
248 | if (game.cheat3) fb[i] |= 0x10;
249 | }
250 | }*/
251 | /*#else
252 | #define LOOP(N, C0, C1) \
253 | d = sprites_data[number][g + N]; \
254 | for (c = C0; c >= C1; c--, i--, d >>= 4, im--) { \
255 | if (im == 0) { \
256 | flg = map_eflg[map_map[(y + r) >> 3][(x + c) >> 3]]; \
257 | im = 8; \
258 | } \
259 | if (!front && (flg & MAP_EFLG_FGND)) continue; \
260 | if (c >= w || x + c < x0) continue; \
261 | if (d & 0x0F) fb[i] = (fb[i] & 0xF0) | (d & 0x0F); \
262 | }
263 | #endif
264 | */
265 | /* LOOP(3, 0x1f, 0x18);
266 | LOOP(2, 0x17, 0x10);
267 | LOOP(1, 0x0f, 0x08);
268 | LOOP(0, 0x07, 0x00);
269 |
270 | //#undef LOOP
271 |
272 | fb += SYSVID_WIDTH;
273 | g += 4;
274 | }
275 | */
276 | }
277 |
278 | //#endif
279 |
280 |
281 | /*
282 | * Redraw the map behind a sprite
283 | * align to tile column and row, and clip
284 | *
285 | * x, y: sprite position (pixels, map).
286 | */
287 | export function
288 | draw_spriteBackground(x, y)
289 | {
290 | let r, c;
291 | let rmax, cmax;
292 | let xmap, ymap; // S16
293 | let xs, ys;
294 | let tmp;
295 |
296 | /* aligne to column and row, prepare map coordinate, and clip */
297 | xmap = _S16(x & 0xFFF8);
298 | ymap = _S16(y & 0xFFF8);
299 | cmax = (x - xmap == 0 ? 0x20 : 0x28); /* width, 4 tl cols, 8 pix each */
300 | rmax = (y & 0x04) ? 0x20 : 0x18; /* height, 3 or 4 tile rows */
301 | if ((tmp = draw_clipms(xmap, ymap, cmax, rmax)).returns) /* don't draw if fully clipped */
302 | return;
303 | xmap = tmp.x;
304 | ymap = tmp.y;
305 | cmax = tmp.width;
306 | rmax = tmp.height;
307 |
308 | /* get back to screen */
309 | xs = xmap - DRAW_XYMAP_SCRLEFT;
310 | ys = ymap - DRAW_XYMAP_SCRTOP;
311 | xmap >>= 3;
312 | ymap >>= 3;
313 | cmax >>= 3;
314 | rmax >>= 3;
315 |
316 | /* draw */
317 | for (r = 0; r < rmax; r++) { /* for each row */
318 | //#ifdef GFXPC
319 | // draw_setfb(xs, ys + r * 8);
320 | //#endif
321 | //#ifdef GFXST
322 | draw_setfb(xs, 8 + ys + r * 8);
323 | //#endif
324 | for (c = 0; c < cmax; c++) { /* for each column */
325 | draw_tile(map.map[ymap + r][xmap + c]);
326 | }
327 | }
328 | }
329 |
330 |
331 | /*
332 | * Draw entire map screen background tiles onto frame buffer.
333 | *
334 | * ASM 0af5, 0a54
335 | */
336 | export function
337 | draw_map()
338 | {
339 | let i, j;
340 |
341 | draw.tilesBank = map.tilesBank;
342 |
343 | for (i = 0; i < 0x18; i++) { /* 0x18 rows */
344 | //#ifdef GFXPC
345 | // draw_setfb(0x20, (i * 8));
346 | //#endif
347 | //#ifdef GFXST
348 | draw_setfb(0x20, 8 + (i * 8));
349 | //#endif
350 | for (j = 0; j < 0x20; j++) /* 0x20 tiles per row */
351 | draw_tile(map.map[i + 8][j]);
352 | }
353 | }
354 |
355 |
356 | /*
357 | * Draw status indicators
358 | *
359 | * ASM 0309
360 | */
361 | export function
362 | draw_drawStatus()
363 | {
364 | let i;
365 | let sv;
366 | const s = [0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfe];
367 |
368 | draw.tilesBank = 0;
369 |
370 | for (i = 5, sv = game.score; i >= 0; i--) {
371 | s[i] = 0x30 + ((sv | 0) % 10);
372 | sv /= 10;
373 | }
374 | draw.tllst = [...s];
375 |
376 | draw_setfb(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y);
377 | draw_tilesList();
378 |
379 | draw_setfb(DRAW_STATUS_BULLETS_X, DRAW_STATUS_Y);
380 | for (i = 0; i < game.bullets; i++)
381 | draw_tile(TILES_BULLET);
382 |
383 | draw_setfb(DRAW_STATUS_BOMBS_X, DRAW_STATUS_Y);
384 | for (i = 0; i < game.bombs; i++)
385 | draw_tile(TILES_BOMB);
386 |
387 | draw_setfb(DRAW_STATUS_LIVES_X, DRAW_STATUS_Y);
388 | for (i = 0; i < game.lives; i++)
389 | draw_tile(TILES_RICK);
390 | }
391 |
392 |
393 | /*
394 | * Draw info indicators
395 | */
396 | //#ifdef ENABLE_CHEATS
397 | export function
398 | draw_infos()
399 | {
400 | draw.tilesBank = 0;
401 |
402 | //#ifdef GFXPC
403 | // draw_filter = 0xffff;
404 | //#endif
405 |
406 | draw_setfb(0x00 , DRAW_STATUS_Y);
407 | draw_tile(game.cheat1 ? 'T' : '@');
408 | draw_setfb(0x08, DRAW_STATUS_Y);
409 | draw_tile(game.cheat2 ? 'N' : '@');
410 | draw_setfb(0x10, DRAW_STATUS_Y);
411 | draw_tile(game.cheat3 ? 'V' : '@');
412 | }
413 | //#endif
414 |
415 |
416 | /*
417 | * Clear status indicators
418 | */
419 | export function
420 | draw_clearStatus()
421 | {
422 | let i;
423 |
424 | //#ifdef GFXPC
425 | // draw_tilesBank = map_tilesBank;
426 | //#endif
427 | //#ifdef GFXST
428 | draw.tilesBank = 0;
429 | //#endif
430 | draw_setfb(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y);
431 | for (i = 0; i < DRAW_STATUS_LIVES_X/8 + 6 - DRAW_STATUS_SCORE_X/8; i++) {
432 | //#ifdef GFXPC
433 | // draw_tile(map_map[MAP_ROW_SCRTOP + (DRAW_STATUS_Y / 8)][i]);
434 | //#endif
435 | //#ifdef GFXST
436 | draw_tile('@');
437 | //#endif
438 | }
439 | }
440 |
441 |
442 | /*
443 | * Draw a picture
444 | */
445 | //#ifdef GFXST
446 | export function
447 | draw_pic(x, y, w, h, pic)
448 | {
449 | sysvid.fb.renderer.drawBitmapSection(dat_get(pic), x, y, new G.Rect(0, 0, w, h));
450 | }
451 | //#endif
452 |
453 |
454 | /*
455 | * Draw a bitmap
456 | */
457 | /*export function
458 | draw_img(i)
459 | {
460 | let k;
461 |
462 | draw_setfb(0, 0);
463 | if (i->ncolors > 0)
464 | sysvid_setPalette(i->colors, i->ncolors);
465 | for (k = 0; k < SYSVID_WIDTH * SYSVID_HEIGHT; k++)
466 | fb[k] = i->pixels[k];
467 | }
468 | */
469 |
470 | /* eof */
471 |
--------------------------------------------------------------------------------
/src/e_bomb.js:
--------------------------------------------------------------------------------
1 | import { WAV_BOMBSHHT, WAV_EXPLODE } from "../include/game";
2 | import { E_BOMB_TICKER, E_BOMB_ENT } from "../include/e_bomb";
3 | import { syssnd_play } from "./syssnd";
4 | import { ent } from "../include/ents";
5 | import { e_rick_gozombie } from "./e_rick";
6 | import { E_RICK_NO } from "../include/e_rick";
7 |
8 | /*
9 | * public vars (for performance reasons)
10 | */
11 | export const e_bomb = {
12 | lethal: false,
13 | xc: 0,
14 | yc: 0
15 | };
16 |
17 | /*
18 | * private vars
19 | */
20 | let e_bomb_ticker;
21 |
22 |
23 | /*
24 | * Bomb hit test
25 | *
26 | * ASM 11CD
27 | * returns: TRUE/hit, FALSE/not
28 | */
29 | export function e_bomb_hit(e)
30 | {
31 | if (ent.ents[e].x > (E_BOMB_ENT().x >= 0xE0 ? 0xFF : E_BOMB_ENT().x + 0x20))
32 | return false;
33 | if (ent.ents[e].x + ent.ents[e].w < (E_BOMB_ENT().x > 0x04 ? E_BOMB_ENT().x - 0x04 : 0))
34 | return false;
35 | if (ent.ents[e].y > (E_BOMB_ENT().y + 0x1D))
36 | return false;
37 | if (ent.ents[e].y + ent.ents[e].h < (E_BOMB_ENT().y > 0x0004 ? E_BOMB_ENT().y - 0x0004 : 0))
38 | return false;
39 | return true;
40 | }
41 |
42 | /*
43 | * Initialize bomb
44 | */
45 | export function e_bomb_init(x, y)
46 | {
47 | E_BOMB_ENT().n = 0x03;
48 | E_BOMB_ENT().x = x;
49 | E_BOMB_ENT().y = y;
50 | e_bomb_ticker = E_BOMB_TICKER;
51 | e_bomb.lethal = false;
52 |
53 | /*
54 | * Atari ST dynamite sprites are not centered the
55 | * way IBM PC sprites were ... need to adjust things a little bit
56 | */
57 | //#ifdef GFXST
58 | E_BOMB_ENT().x += 4;
59 | E_BOMB_ENT().y += 5;
60 | //#endif
61 |
62 | }
63 |
64 |
65 | /*
66 | * Entity action
67 | *
68 | * ASM 18CA
69 | */
70 | export function
71 | e_bomb_action(UNUSED_e)
72 | {
73 | /* tick */
74 | e_bomb_ticker--;
75 |
76 | if (e_bomb_ticker === 0)
77 | {
78 | /*
79 | * end: deactivate
80 | */
81 | E_BOMB_ENT().n = 0;
82 | e_bomb.lethal = false;
83 | }
84 | else if (e_bomb_ticker >= 0x0A)
85 | {
86 | /*
87 | * ticking
88 | */
89 | //#ifdef ENABLE_SOUND
90 | if ((e_bomb_ticker & 0x03) == 0x02)
91 | syssnd_play(WAV_BOMBSHHT, 1);
92 | //#endif
93 | //#ifdef GFXST
94 | /* ST bomb sprites sequence is longer */
95 | if (e_bomb_ticker < 40)
96 | E_BOMB_ENT().sprite = 0x99 + 19 - (e_bomb_ticker >> 1);
97 | else
98 | //#endif
99 | E_BOMB_ENT().sprite = (e_bomb_ticker & 0x01) ? 0x23 : 0x22;
100 | }
101 | else if (e_bomb_ticker == 0x09)
102 | {
103 | /*
104 | * explode
105 | */
106 | //#ifdef ENABLE_SOUND
107 | syssnd_play(WAV_EXPLODE, 1);
108 | //#endif
109 | //#ifdef GFXPC
110 | // E_BOMB_ENT().sprite = 0x24 + 4 - (e_bomb_ticker >> 1);
111 | //#endif
112 | //#ifdef GFXST
113 | /* See above: fixing alignment */
114 | E_BOMB_ENT().x -= 4;
115 | E_BOMB_ENT().y -= 5;
116 | E_BOMB_ENT().sprite = 0xa8 + 4 - (e_bomb_ticker >> 1);
117 | //#endif
118 | e_bomb.xc = E_BOMB_ENT().x + 0x0C;
119 | e_bomb.yc = E_BOMB_ENT().y + 0x000A;
120 | e_bomb.lethal = true;
121 | if (e_bomb_hit(E_RICK_NO))
122 | e_rick_gozombie();
123 | }
124 | else
125 | {
126 | /*
127 | * exploding
128 | */
129 | //#ifdef GFXPC
130 | // E_BOMB_ENT().sprite = 0x24 + 4 - (e_bomb_ticker >> 1);
131 | //#endif
132 | //#ifdef GFXST
133 | E_BOMB_ENT().sprite = 0xa8 + 4 - (e_bomb_ticker >> 1);
134 | //#endif
135 | /* exploding, hence lethal */
136 | if (e_bomb_hit(E_RICK_NO))
137 | e_rick_gozombie();
138 | }
139 | }
140 |
141 | /* eof */
142 |
143 |
144 |
--------------------------------------------------------------------------------
/src/e_bonus.js:
--------------------------------------------------------------------------------
1 | import { WAV_BONUS } from "../include/game";
2 | import { ent } from "../include/ents";
3 | import { e_rick_boxtest } from "./e_rick";
4 | import { syssnd_play } from "./syssnd";
5 | import { map_marks } from "./dat_maps";
6 | import { game } from "./game";
7 | import { MAP_MARK_NACT } from "../include/maps";
8 | /*
9 | * Entity action
10 | *
11 | * ASM 242C
12 | */
13 | export function
14 | e_bonus_action(e)
15 | {
16 | //#define seq c1
17 |
18 | if (ent.ents[e].seq === 0) {
19 | if (e_rick_boxtest(e)) {
20 | game.score += 500;
21 | //#ifdef ENABLE_SOUND
22 | syssnd_play(WAV_BONUS, 1);
23 | //#endif
24 | map_marks[ent.ents[e].mark].ent |= MAP_MARK_NACT;
25 | ent.ents[e].seq = 1;
26 | ent.ents[e].sprite = 0xad;
27 | ent.ents[e].front = true;
28 | ent.ents[e].y -= 0x08;
29 | }
30 | }
31 |
32 | else if (ent.ents[e].seq > 0 && ent.ents[e].seq < 10) {
33 | ent.ents[e].seq++;
34 | ent.ents[e].y -= 2;
35 | }
36 |
37 | else {
38 | ent.ents[e].n = 0;
39 | }
40 | }
41 |
42 |
43 | /* eof */
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/e_box.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * FIXME this is because the same structure is used
4 | * for all entities. Need to replace this w/ an inheritance
5 | * solution.
6 | */
7 | //#define cnt c1
8 |
9 | import { GAME_BOMBS_INIT, GAME_BULLETS_INIT, WAV_BOX,
10 | WAV_EXPLODE } from "../include/game";
11 | import { ent, ENT_LETHAL } from "../include/ents";
12 | import { e_rick_boxtest } from "./e_rick";
13 | import { MAP_MARK_NACT } from "../include/maps";
14 | import { E_RICK_STSTOP, E_RICK_STTST } from "../include/e_rick";
15 | import { u_fboxtest } from "./util";
16 | import { E_BULLET_ENT } from "../include/e_bullet";
17 | import { e_bomb, e_bomb_hit } from "./e_bomb";
18 | import { game } from "./game";
19 | import { map_marks } from "./dat_maps";
20 | import { e_bullet } from "./e_bullet";
21 | import { syssnd_play } from "./syssnd";
22 |
23 | /*
24 | * Constants
25 | */
26 | const SEQ_INIT = 0x0A;
27 |
28 | /*
29 | * Entity action
30 | *
31 | * ASM 245A
32 | */
33 | export function
34 | e_box_action(e)
35 | {
36 | const sp = [0x24, 0x25, 0x26, 0x27, 0x28]; /* explosion sprites sequence */
37 |
38 | if (ent.ents[e].n & ENT_LETHAL) {
39 | /*
40 | * box is lethal i.e. exploding
41 | * play sprites sequence then stop
42 | */
43 | ent.ents[e].sprite = sp[ent.ents[e].cnt >> 1];
44 | if (--ent.ents[e].cnt == 0) {
45 | ent.ents[e].n = 0;
46 | map_marks[ent.ents[e].mark].ent |= MAP_MARK_NACT;
47 | }
48 | } else {
49 | /*
50 | * not lethal: check to see if triggered
51 | */
52 | if (e_rick_boxtest(e)) {
53 | /* rick: collect bombs or bullets and stop */
54 | //#ifdef ENABLE_SOUND
55 | syssnd_play(WAV_BOX, 1);
56 | //#endif
57 | if (ent.ents[e].n == 0x10)
58 | game.bombs = GAME_BOMBS_INIT;
59 | else /* 0x11 */
60 | game.bullets = GAME_BULLETS_INIT;
61 | ent.ents[e].n = 0;
62 | map_marks[ent.ents[e].mark].ent |= MAP_MARK_NACT;
63 | }
64 | else if (E_RICK_STTST(E_RICK_STSTOP) &&
65 | u_fboxtest(e, e_rick.stop_x, e_rick.stop_y)) {
66 | /* rick's stick: explode */
67 | explode(e);
68 | }
69 | else if (E_BULLET_ENT().n && u_fboxtest(e, e_bullet.xc, e_bullet.yc)) {
70 | /* bullet: explode (and stop bullet) */
71 | E_BULLET_ENT().n = 0;
72 | explode(e);
73 | }
74 | else if (e_bomb.lethal && e_bomb_hit(e)) {
75 | /* bomb: explode */
76 | explode(e);
77 | }
78 | }
79 | }
80 |
81 |
82 | /*
83 | * Explode when
84 | */
85 | function explode(e)
86 | {
87 | ent.ents[e].cnt = SEQ_INIT;
88 | ent.ents[e].n |= ENT_LETHAL;
89 | //#ifdef ENABLE_SOUND
90 | syssnd_play(WAV_EXPLODE, 1);
91 | //#endif
92 | }
93 |
94 | /* eof */
95 |
96 |
97 |
--------------------------------------------------------------------------------
/src/e_bullet.js:
--------------------------------------------------------------------------------
1 | import { E_BULLET_ENT } from "../include/e_bullet";
2 | import { LEFT, WAV_BULLET } from "../include/game";
3 | import { MAP_EFLG_SOLID } from "../include/maps";
4 | import { game } from "./game";
5 | import { syssnd_play } from "./syssnd";
6 | import { map } from "./maps";
7 |
8 | /*
9 | * public vars (for performance reasons)
10 | */
11 | export const e_bullet = {
12 | offsx: 0,
13 | xc: 0, yc: 0
14 | };
15 |
16 | /*
17 | * Initialize bullet
18 | */
19 | export function
20 | e_bullet_init(x, y)
21 | {
22 | E_BULLET_ENT().n = 0x02;
23 | E_BULLET_ENT().x = x;
24 | E_BULLET_ENT().y = y + 0x0006;
25 | if (game.dir === LEFT) {
26 | e_bullet.offsx = -0x08;
27 | E_BULLET_ENT().sprite = 0x21;
28 | }
29 | else {
30 | e_bullet.offsx = 0x08;
31 | E_BULLET_ENT().sprite = 0x20;
32 | }
33 | //#ifdef ENABLE_SOUND
34 | syssnd_play(WAV_BULLET, 1);
35 | //#endif
36 | }
37 |
38 |
39 | /*
40 | * Entity action
41 | *
42 | * ASM 1883, 0F97
43 | */
44 | export function
45 | e_bullet_action(_UNUSED_e)
46 | {
47 | /* move bullet */
48 | E_BULLET_ENT().x += e_bullet.offsx;
49 |
50 | if (E_BULLET_ENT().x <= -0x10 || E_BULLET_ENT().x > 0xe8) {
51 | /* out: deactivate */
52 | E_BULLET_ENT().n = 0;
53 | }
54 | else {
55 | /* update bullet center coordinates */
56 | e_bullet.xc = E_BULLET_ENT().x + 0x0c;
57 | e_bullet.yc = E_BULLET_ENT().y + 0x05;
58 | if (map.eflg[map.map[e_bullet.yc >> 3][e_bullet.xc >> 3]] &
59 | MAP_EFLG_SOLID) {
60 | /* hit something: deactivate */
61 | E_BULLET_ENT().n = 0;
62 | }
63 | }
64 | }
65 |
66 |
67 | /* eof */
68 |
69 |
--------------------------------------------------------------------------------
/src/e_sbonus.js:
--------------------------------------------------------------------------------
1 | import { game } from "./game";
2 | import { ent, ENT_XRICK } from "../include/ents";
3 | import { u_trigbox } from "./util";
4 | import { syssnd_play } from "./syssnd";
5 | import { WAV_SBONUS1, WAV_SBONUS2 } from "../include/game";
6 | import { map_marks } from "./dat_maps";
7 | import { MAP_MARK_NACT } from "../include/maps";
8 |
9 | /*
10 | * public vars
11 | */
12 | export const e_sbonus = {
13 | counting: false,
14 | counter: 0,
15 | bonus: 0
16 | };
17 |
18 |
19 | /*
20 | * Entity action / start counting
21 | *
22 | * ASM 2182
23 | */
24 | export function
25 | e_sbonus_start(e)
26 | {
27 | ent.ents[e].sprite = 0; /* invisible */
28 | if (u_trigbox(e, ENT_XRICK().x + 0x0C, ENT_XRICK().y + 0x0A)) {
29 | /* rick is within trigger box */
30 | ent.ents[e].n = 0;
31 | e_sbonus.counting = true; /* 6DD5 */
32 | e_sbonus.counter = 0x1e; /* 6DDB */
33 | e_sbonus.bonus = 2000; /* 291A-291D */
34 | //#ifdef ENABLE_SOUND
35 | syssnd_play(WAV_SBONUS1, 1);
36 | //#endif
37 | }
38 | }
39 |
40 |
41 | /*
42 | * Entity action / stop counting
43 | *
44 | * ASM 2143
45 | */
46 | export function
47 | e_sbonus_stop(e)
48 | {
49 | ent.ents[e].sprite = 0; /* invisible */
50 |
51 | if (!e_sbonus.counting)
52 | return;
53 |
54 | if (u_trigbox(e, ENT_XRICK().x + 0x0C, ENT_XRICK().y + 0x0A)) {
55 | /* rick is within trigger box */
56 | e_sbonus.counting = false; /* stop counting */
57 | ent.ents[e].n = 0; /* deactivate entity */
58 | game.score += e_sbonus.bonus; /* add bonus to score */
59 | //#ifdef ENABLE_SOUND
60 | syssnd_play(WAV_SBONUS2, 1);
61 | //#endif
62 | /* make sure the entity won't be activated again */
63 | map_marks[ent.ents[e].mark].ent |= MAP_MARK_NACT;
64 | }
65 | else {
66 | /* keep counting */
67 | if (--e_sbonus.counter == 0) {
68 | e_sbonus.counter = 0x1e;
69 | if (e_sbonus.bonus) e_sbonus.bonus--;
70 | }
71 | }
72 | }
73 |
74 | /* eof */
75 |
76 |
77 |
--------------------------------------------------------------------------------
/src/maps.js:
--------------------------------------------------------------------------------
1 | import { create_array, _U8 } from "./c";
2 | import { map_submaps, map_marks, map_eflg_c, map_blocks, map_bnums, map_connect } from "./dat_maps";
3 | import {
4 | MAP_NBR_MARKS, MAP_MARK_NACT,
5 | MAP_ROW_SCRTOP, MAP_ROW_SCRBOT,
6 | MAP_ROW_HTTOP, MAP_ROW_HTBOT,
7 | MAP_ROW_HBTOP, MAP_ROW_HBBOT } from "../include/maps";
8 | import { game } from "./game";
9 | import { ent_reset, ent_actvis } from "./ents";
10 | import { ent } from "../include/ents";
11 | import { e_sbonus } from "./e_sbonus";
12 |
13 | /*
14 | * global vars
15 | */
16 | export const map = {
17 | map: create_array(0x2C, 0x20),
18 | eflg: create_array(0x100),
19 | frow: 0,
20 | tilesBank: 0
21 | };
22 |
23 |
24 | /*
25 | * Fill in map_map with tile numbers by expanding blocks.
26 | *
27 | * add map_submaps[].bnum to map_frow to find out where to start from.
28 | * We need to /4 map_frow to convert from tile rows to block rows, then
29 | * we need to *8 to convert from block rows to block numbers (there
30 | * are 8 blocks per block row). This is achieved by *2 then &0xfff8.
31 | */
32 | export function
33 | map_expand()
34 | {
35 | let i, j, k, l;
36 | let row, col;
37 | let pbnum;
38 |
39 | pbnum = map_submaps[game.submap].bnum + ((2 * map.frow) & 0xfff8);
40 | row = col = 0;
41 | console.log("START", map_submaps[game.submap].bnum, map.frow)
42 | for (i = 0; i < 0x0b; i++) { /* 0x0b rows of blocks */
43 | for (j = 0; j < 0x08; j++) { /* 0x08 blocks per row */
44 | for (k = 0, l = 0; k < 0x04; k++) { /* expand one block */
45 |
46 | //console.log(i, j, k, l, row, col, pbnum)
47 | map.map[row][col++] = map_blocks[map_bnums[pbnum]][l++];
48 | map.map[row][col++] = map_blocks[map_bnums[pbnum]][l++];
49 | map.map[row][col++] = map_blocks[map_bnums[pbnum]][l++];
50 | map.map[row][col] = map_blocks[map_bnums[pbnum]][l++];
51 | row += 1; col -= 3;
52 | }
53 | row -= 4; col += 4;
54 | pbnum++;
55 | }
56 | row += 4; col = 0;
57 | }
58 | }
59 |
60 |
61 | /*
62 | * Initialize a new submap
63 | *
64 | * ASM 0cc3
65 | */
66 | export function
67 | map_init()
68 | {
69 | /*sys_printf("xrick/map_init: map=%#04x submap=%#04x\n", g_map, game_submap);*/
70 |
71 | map.tilesBank = (map_submaps[game.submap].page === 1) ? 2 : 1;
72 |
73 | map_eflg_expand((map_submaps[game.submap].page === 1) ? 0x10 : 0x00);
74 | map_expand();
75 | ent_reset();
76 | ent_actvis(map.frow + MAP_ROW_SCRTOP, map.frow + MAP_ROW_SCRBOT);
77 | ent_actvis(map.frow + MAP_ROW_HTTOP, map.frow + MAP_ROW_HTBOT);
78 | ent_actvis(map.frow + MAP_ROW_HBTOP, map.frow + MAP_ROW_HBBOT);
79 | }
80 |
81 |
82 | /*
83 | * Expand entity flags for this map
84 | *
85 | * ASM 1117
86 | */
87 | export function
88 | map_eflg_expand(offs)
89 | {
90 | let i, j, k;
91 |
92 | for (i = 0, k = 0; i < 0x10; i++) {
93 | j = map_eflg_c[offs + i++];
94 | while (j--) map.eflg[k++] = map_eflg_c[offs + i];
95 | }
96 | }
97 |
98 |
99 | /*
100 | * Chain (sub)maps
101 | *
102 | * ASM 0c08
103 | * return: TRUE/next submap OK, FALSE/map finished
104 | */
105 | export function
106 | map_chain()
107 | {
108 | let c, t;
109 |
110 | game.chsm = 0;
111 | e_sbonus.counting = false;
112 |
113 | /* find connection */
114 | c = map_submaps[game.submap].connect;
115 | t = 3;
116 | /*
117 | IFDEBUG_MAPS(
118 | sys_printf("xrick/maps: chain submap=%#04x frow=%#04x .connect=%#04x %s\n",
119 | game_submap, map_frow, c,
120 | (game_dir == LEFT ? "-> left" : "-> right"));
121 | );
122 | */
123 | /*
124 | * look for the first connector with compatible row number. if none
125 | * found, then panic
126 | */
127 | for (c = map_submaps[game.submap].connect; ; c++) {
128 | if (map_connect[c].dir === 0xff)
129 | sys_panic("(map_chain) can not find connector\n");
130 | if (map_connect[c].dir != game.dir) continue;
131 | t = (ent.ents[1].y >> 3) + map.frow - map_connect[c].rowout;
132 | if (t < 3) break;
133 | }
134 |
135 | /* got it */
136 | /* IFDEBUG_MAPS(
137 | sys_printf("xrick/maps: chain frow=%#04x y=%#06x\n",
138 | map_frow, ent_ents[1].y);
139 | sys_printf("xrick/maps: chain connect=%#04x rowout=%#04x - ",
140 | c, map_connect[c].rowout);
141 | );
142 | */
143 | if (map_connect[c].submap === 0xff) {
144 | /* no next submap - request next map */
145 | /* IFDEBUG_MAPS(
146 | sys_printf("chain to next map\n");
147 | );*/
148 | return false;
149 | }
150 | else {
151 | /* next submap */
152 | /* IFDEBUG_MAPS(
153 | sys_printf("chain to submap=%#04x rowin=%#04x\n",
154 | map_connect[c].submap, map_connect[c].rowin);
155 | );*/
156 | map.frow = _U8(map.frow - map_connect[c].rowout + map_connect[c].rowin);
157 | game.submap = map_connect[c].submap;
158 | /* IFDEBUG_MAPS(
159 | sys_printf("xrick/maps: chain frow=%#04x\n",
160 | map_frow);
161 | );*/
162 | return true;
163 | }
164 | }
165 |
166 |
167 | /*
168 | * Reset all marks, i.e. make them all active again.
169 | *
170 | * ASM 0025
171 | *
172 | */
173 | export function
174 | map_resetMarks()
175 | {
176 | let i;
177 | for (i = 0; i < MAP_NBR_MARKS; i++)
178 | map_marks[i].ent &= ~MAP_MARK_NACT;
179 | }
180 |
181 |
182 | /* eof */
183 |
--------------------------------------------------------------------------------
/src/rects.js:
--------------------------------------------------------------------------------
1 | import { rect_t } from "../include/rects";
2 |
3 | /*
4 | * Free a list of rectangles and set the pointer to NULL.
5 | *
6 | * p: rectangle list CHANGED to NULL
7 | */
8 | export function
9 | rects_free(r) {
10 | if (r) {
11 | rects_free(r.next);
12 | r.next = null;
13 | // free(r);
14 | }
15 | }
16 |
17 | /*
18 | * Add a rectangle to a list of rectangles
19 | */
20 | export function
21 | rects_new(x, y, width, height, next)
22 | {
23 | let r;
24 |
25 | r = rect_t(
26 | x,
27 | y,
28 | width,
29 | height,
30 | next
31 | );
32 | return r;
33 | }
34 |
35 | /* eof */
36 |
--------------------------------------------------------------------------------
/src/scr_gameover.js:
--------------------------------------------------------------------------------
1 | import { CONTROL_EXIT, CONTROL_FIRE } from "../include/control";
2 | import { SCREEN_DONE, SCREEN_EXIT, SCREEN_RUNNING,
3 | SCREEN_TIMEOUT } from "../include/screens";
4 | import { control } from "./control";
5 | import { screen_gameovertxt } from "./dat_screens";
6 | import { draw, draw_SCREENRECT, draw_setfb, draw_tilesList } from "./draw";
7 | import { game, game_setmusic } from "./game";
8 | import { sys_gettime, sys_sleep } from "./system";
9 | import { sysvid_clear } from "./sysvid";
10 |
11 | /*
12 | * Display the game over screen
13 | *
14 | * return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
15 | */
16 | let seq = 0;
17 | let period = 0;
18 | let tm = 0;
19 |
20 | export function
21 | screen_gameover()
22 | {
23 | // static U8 seq = 0;
24 | // static U8 period = 0;
25 | //#ifdef GFXST
26 | // static U32 tm = 0;
27 | //#endif
28 | //#ifdef ENABLE_SOUND
29 | // static sound_t *snd;
30 | // static U8 chan;
31 | //#endif
32 |
33 | if (seq === 0) {
34 | draw.tilesBank = 0;
35 | seq = 1;
36 | period = game.period; /* save period, */
37 | game.period = 50; /* and use our own */
38 | //#ifdef ENABLE_SOUND
39 | game_setmusic("sounds/gameover.wav", 1);
40 | //#endif
41 | }
42 |
43 | switch (seq) {
44 | case 1: /* display banner */
45 | //#ifdef GFXST
46 | sysvid_clear();
47 | tm = sys_gettime();
48 | //#endif
49 | draw.tllst = [...screen_gameovertxt];
50 | draw_setfb(120, 80);
51 | //#ifdef GFXPC
52 | // draw_filter = 0xAAAA;
53 | //#endif
54 | draw_tilesList();
55 |
56 | game.rects = draw_SCREENRECT;
57 | seq = 2;
58 | break;
59 |
60 | case 2: /* wait for key pressed */
61 | if (control.status & CONTROL_FIRE)
62 | seq = 3;
63 | //#ifdef GFXST
64 | else if (sys_gettime() - tm > SCREEN_TIMEOUT)
65 | seq = 4;
66 | //#endif
67 | else
68 | sys_sleep(50);
69 | break;
70 |
71 | case 3: /* wait for key released */
72 | if (!(control.status & CONTROL_FIRE))
73 | seq = 4;
74 | else
75 | sys_sleep(50);
76 | break;
77 | }
78 |
79 | if (control.status & CONTROL_EXIT) /* check for exit request */
80 | return SCREEN_EXIT;
81 |
82 | if (seq === 4) { /* we're done */
83 | sysvid_clear();
84 | seq = 0;
85 | game.period = period;
86 | return SCREEN_DONE;
87 | }
88 |
89 | return SCREEN_RUNNING;
90 | }
91 |
92 | /* eof */
93 |
94 |
--------------------------------------------------------------------------------
/src/scr_getname.js:
--------------------------------------------------------------------------------
1 | import { CONTROL_DOWN, CONTROL_EXIT, CONTROL_FIRE, CONTROL_LEFT,
2 | CONTROL_RIGHT, CONTROL_UP } from "../include/control";
3 | import { SCREEN_DONE, SCREEN_RUNNING } from "../include/screens";
4 | import { _STR } from "./c";
5 | import { control } from "./control";
6 | import { draw, draw_SCREENRECT, draw_setfb, draw_tile,
7 | draw_tilesListImm } from "./draw";
8 | import { game } from "./game";
9 | import { sys_gettime, sys_sleep } from "./system";
10 | import { sysvid_clear } from "./sysvid";
11 |
12 | /*
13 | * local vars
14 | */
15 | let seq = 0;
16 | let x, y, p;
17 | const name = Array(10);
18 |
19 | const TILE_POINTER = 0x3A; // '\072';
20 | const TILE_CURSOR = 0x3B; // '\073';
21 | const TOPLEFT_X = 116;
22 | const TOPLEFT_Y = 64;
23 | const NAMEPOS_X = 120;
24 | const NAMEPOS_Y = 160;
25 | const AUTOREPEAT_TMOUT = 100;
26 |
27 |
28 | /*
29 | * Get name
30 | *
31 | * return: 0 while running, 1 when finished.
32 | */
33 | let tm = 0;
34 |
35 | export function
36 | screen_getname()
37 | {
38 | // static U32 tm = 0;
39 | let i, j;
40 |
41 | if (seq === 0) {
42 | /* figure out if this is a high score */
43 | if (game.score < game.hscores[7].score)
44 | return SCREEN_DONE;
45 |
46 | /* prepare */
47 | draw.tilesBank = 0;
48 | //#ifdef GFXPC
49 | // draw_filter = 0xffff;
50 | //#endif
51 | for (i = 0; i < 10; i++)
52 | name[i] = '@';
53 | x = y = p = 0;
54 | game.rects = draw_SCREENRECT;
55 | seq = 1;
56 | }
57 |
58 | switch (seq) {
59 | case 1: /* prepare screen */
60 | sysvid_clear();
61 | //#ifdef GFXPC
62 | // draw_setfb(32, 8);
63 | // draw_filter = 0xaaaa; /* red */
64 | // draw_tilesListImm(screen_congrats);
65 | //#endif
66 | draw_setfb(76, 40);
67 | //#ifdef GFXPC
68 | // draw_filter = 0xffff; /* yellow */
69 | //#endif
70 | draw_tilesListImm("PLEASE@ENTER@YOUR@NAME\xFE");
71 | //#ifdef GFXPC
72 | // draw_filter = 0x5555; /* green */
73 | //#endif
74 | for (i = 0; i < 6; i++)
75 | for (j = 0; j < 4; j++) {
76 | draw_setfb(TOPLEFT_X + i * 8 * 2, TOPLEFT_Y + j * 8 * 2);
77 | draw_tile('A'.charCodeAt(0) + i + j * 6);
78 | }
79 | draw_setfb(TOPLEFT_X, TOPLEFT_Y + 64);
80 | //#ifdef GFXST
81 | draw_tilesListImm("Y@Z@.@@@\x3C\xFB\xFC\xFD\xFE");
82 | //#endif
83 | //#ifdef GFXPC
84 | // draw_tilesListImm((U8 *)"Y@Z@.@@@\074@\075@\376");
85 | //#endif
86 | name_draw();
87 | pointer_show(true);
88 | seq = 2;
89 | break;
90 |
91 | case 2: /* wait for key pressed */
92 | if (control.status & CONTROL_FIRE)
93 | seq = 3;
94 | if (control.status & CONTROL_UP) {
95 | if (y > 0) {
96 | pointer_show(false);
97 | y--;
98 | pointer_show(true);
99 | tm = sys_gettime();
100 | }
101 | seq = 4;
102 | }
103 | if (control.status & CONTROL_DOWN) {
104 | if (y < 4) {
105 | pointer_show(false);
106 | y++;
107 | pointer_show(true);
108 | tm = sys_gettime();
109 | }
110 | seq = 5;
111 | }
112 | if (control.status & CONTROL_LEFT) {
113 | if (x > 0) {
114 | pointer_show(false);
115 | x--;
116 | pointer_show(true);
117 | tm = sys_gettime();
118 | }
119 | seq = 6;
120 | }
121 | if (control.status & CONTROL_RIGHT) {
122 | if (x < 5) {
123 | pointer_show(false);
124 | x++;
125 | pointer_show(true);
126 | tm = sys_gettime();
127 | }
128 | seq = 7;
129 | }
130 | if (seq === 2)
131 | sys_sleep(50);
132 | break;
133 |
134 | case 3: /* wait for FIRE released */
135 | if (!(control.status & CONTROL_FIRE)) {
136 | if (x == 5 && y == 4) { /* end */
137 | i = 0;
138 | while (game.score < game.hscores[i].score)
139 | i++;
140 | j = 7;
141 | while (j > i) {
142 | game.hscores[j].score = game.hscores[j - 1].score;
143 | //for (x = 0; x < 10; x++)
144 | game.hscores[j].name/*[x]*/ = game.hscores[j - 1].name/*[x]*/;
145 | j--;
146 | }
147 | game.hscores[i].score = game.score;
148 | //for (x = 0; x < 10; x++)
149 | game.hscores[i].name/*[x]*/ = _STR(name)/*[x]*/;
150 | seq = 99;
151 | }
152 | else {
153 | name_update();
154 | name_draw();
155 | seq = 2;
156 | }
157 | }
158 | else
159 | sys_sleep(50);
160 | break;
161 |
162 | case 4: /* wait for UP released */
163 | if (!(control.status & CONTROL_UP) ||
164 | sys_gettime() - tm > AUTOREPEAT_TMOUT)
165 | seq = 2;
166 | else
167 | sys_sleep(50);
168 | break;
169 |
170 | case 5: /* wait for DOWN released */
171 | if (!(control.status & CONTROL_DOWN) ||
172 | sys_gettime() - tm > AUTOREPEAT_TMOUT)
173 | seq = 2;
174 | else
175 | sys_sleep(50);
176 | break;
177 |
178 | case 6: /* wait for LEFT released */
179 | if (!(control.status & CONTROL_LEFT) ||
180 | sys_gettime() - tm > AUTOREPEAT_TMOUT)
181 | seq = 2;
182 | else
183 | sys_sleep(50);
184 | break;
185 |
186 | case 7: /* wait for RIGHT released */
187 | if (!(control.status & CONTROL_RIGHT) ||
188 | sys_gettime() - tm > AUTOREPEAT_TMOUT)
189 | seq = 2;
190 | else
191 | sys_sleep(50);
192 | break;
193 |
194 | }
195 |
196 | if (control.status & CONTROL_EXIT) /* check for exit request */
197 | return SCREEN_EXIT;
198 |
199 | if (seq === 99) { /* seq 99, we're done */
200 | sysvid_clear();
201 | seq = 0;
202 | return SCREEN_DONE;
203 | }
204 | else
205 | return SCREEN_RUNNING;
206 | }
207 |
208 |
209 | function
210 | pointer_show(show)
211 | {
212 | draw_setfb(TOPLEFT_X + x * 8 * 2, TOPLEFT_Y + y * 8 * 2 + 8);
213 | //#ifdef GFXPC
214 | // draw_filter = 0xaaaa; /* red */
215 | //#endif
216 | draw_tile((show === true)?TILE_POINTER:'@'.charCodeAt(0));
217 | }
218 |
219 | function
220 | name_update()
221 | {
222 | let i;
223 |
224 | i = x + y * 6;
225 | if (i < 26 && p < 10)
226 | name[p++] = 'A'.charCodeAt(0) + i;
227 | if (i == 26 && p < 10)
228 | name[p++] = '.'.charCodeAt(0);
229 | if (i == 27 && p < 10)
230 | name[p++] = '@'.charCodeAt(0);
231 | if (i == 28 && p > 0) {
232 | p--;
233 | }
234 | }
235 |
236 | function
237 | name_draw()
238 | {
239 | let i;
240 |
241 | draw_setfb(NAMEPOS_X, NAMEPOS_Y);
242 | //#ifdef GFXPC
243 | // draw_filter = 0xaaaa; /* red */
244 | //#endif
245 | for (i = 0; i < p; i++)
246 | draw_tile(name[i]);
247 | for (i = p; i < 10; i++)
248 | draw_tile(TILE_CURSOR);
249 |
250 | //#ifdef GFXST
251 | draw_setfb(NAMEPOS_X, NAMEPOS_Y + 8);
252 | for (i = 0; i < 10; i++)
253 | draw_tile('@');
254 | draw_setfb(NAMEPOS_X + 8 * (p < 9 ? p : 9), NAMEPOS_Y + 8);
255 | draw_tile(TILE_POINTER);
256 | //#endif
257 | }
258 |
259 |
260 | /* eof */
261 |
--------------------------------------------------------------------------------
/src/scr_imain.js:
--------------------------------------------------------------------------------
1 | import { sprintf, struct } from "./c";
2 | import { game, game_setmusic } from "./game";
3 | import { draw, draw_SCREENRECT, draw_pic, draw_tilesList, draw_setfb } from "./draw";
4 | import { sysvid, sysvid_clear, sysvid_fadeStart, sysvid_fadeEnd } from "./sysvid";
5 | import { sys_gettime } from "./system";
6 | import { pic_splash, pic_haf } from "./dat_picST";
7 | import { control } from "./control";
8 | import { CONTROL_FIRE, CONTROL_EXIT } from "../include/control";
9 | import { SCREEN_RUNNING, SCREEN_TIMEOUT, SCREEN_DONE } from "../include/screens";
10 |
11 | // static in screen_introMain()
12 | let /*U8*/ seq = 0;
13 | let /*U8*/ seen = 0;
14 | let /*U8*/ first = true;
15 | let /*U8*/ period = 0;
16 | let /*U32*/ tm = 0;
17 | let /*U8*/ i, s = Array(32);
18 | let fading;
19 |
20 | /*
21 | * Main introduction
22 | *
23 | * return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
24 | */
25 | export function
26 | screen_introMain(timer)
27 | {
28 | // See static above
29 |
30 | if (seq === 0) {
31 | draw.tilesBank = 0;
32 | if (first === true) {
33 | seq = 1;
34 | } else {
35 | seq = 4;
36 | }
37 | period = game.period;
38 | game.period = 50;
39 | game.rects = draw_SCREENRECT;
40 | //#ifdef ENABLE_SOUND
41 | game_setmusic("sounds/tune5.wav", -1);
42 | //#endif
43 | }
44 |
45 | switch (seq) {
46 | case 1: /* display Rick Dangerous title and Core Design copyright */
47 | if (fading) {
48 | break;
49 | }
50 | sysvid_clear();
51 | tm = sys_gettime();
52 | /*
53 | #ifdef GFXPC
54 | /* Rick Dangerous title //
55 | draw_tllst = (U8 *)screen_imainrdt;
56 | draw_setfb(32, 16);
57 | draw_filter = 0xaaaa;
58 | draw_tilesList();
59 |
60 | /* Core Design copyright + press space to start //
61 | draw_tllst = (U8 *)screen_imaincdc;
62 | draw_setfb(64, 80);
63 | draw_filter = 0x5555;
64 | draw_tilesList();
65 | #endif
66 | */
67 | //#ifdef GFXST
68 | draw_pic(0, 0, 0x140, 0xc8, pic_splash);
69 | //#endif
70 |
71 | seq = 2;
72 | fading = GE.Fader.IN;
73 | sysvid_fadeStart();
74 | break;
75 |
76 | case 2: /* wait for key pressed or timeout */
77 | if (control.status & CONTROL_FIRE) {
78 | seq = 3;
79 | } else if (sys_gettime() - tm > SCREEN_TIMEOUT) {
80 | seen++;
81 | seq = 4;
82 |
83 | fading = GE.Fader.OUT;
84 | sysvid_fadeStart();
85 | }
86 | break;
87 |
88 | case 3: /* wait for key released */
89 | if (!(control.status & CONTROL_FIRE)) {
90 | if (seen++ === 0) {
91 | seq = 4;
92 | } else {
93 | seq = 7;
94 |
95 | fading = GE.Fader.OUT;
96 | sysvid_fadeStart();
97 | }
98 | }
99 | break;
100 |
101 | case 4: /* dispay hall of fame */
102 | if (fading) {
103 | break;
104 | }
105 | sysvid_clear();
106 | tm = sys_gettime();
107 |
108 | /* hall of fame title *//*
109 | #ifdef GFXPC
110 | draw_tllst = (U8 *)screen_imainhoft;
111 | draw_setfb(32, 0);
112 | draw_filter = 0xaaaa;
113 | draw_tilesList();
114 | #endif*/
115 | //#ifdef GFXST
116 | draw_pic(64, 4, 0x140, 0x20, pic_haf);
117 | //#endif
118 |
119 | /* hall of fame content */
120 | draw_setfb(56, 40);
121 | //#ifdef GFXPC
122 | // draw_filter = 0x5555;
123 | //#endif
124 | for (i = 0; i < 8; i++) {
125 | const tmp = `00${game.hscores[i].score}`; // %06d
126 | const game_hscores_i_score = tmp.substring(tmp.length - 6, tmp.length);
127 |
128 | sprintf(s, "{0}@@@....@@@{1}",
129 | game_hscores_i_score, game.hscores[i].name);
130 | s[26] = '\xFF'; s[27] = '\xFF'; s[28] = '\xFE'; // \377 \377 \376
131 | draw.tllst = [...s];
132 | draw_tilesList();
133 | }
134 |
135 | seq = 5;
136 | fading = GE.Fader.IN;
137 | sysvid_fadeStart();
138 | break;
139 |
140 | case 5: /* wait for key pressed or timeout */
141 | if (control.status & CONTROL_FIRE) {
142 | seq = 6;
143 | } else if (sys_gettime() - tm > SCREEN_TIMEOUT) {
144 | seen++;
145 | seq = 1;
146 |
147 | fading = GE.Fader.OUT;
148 | sysvid_fadeStart();
149 | }
150 | break;
151 |
152 | case 6: /* wait for key released */
153 | if (!(control.status & CONTROL_FIRE)) {
154 | if (seen++ == 0) {
155 | seq = 1;
156 | } else {
157 | seq = 7;
158 |
159 | fading = GE.Fader.OUT;
160 | sysvid_fadeStart();
161 | }
162 | }
163 | break;
164 | }
165 |
166 | if (fading) {
167 | game.rects = draw_SCREENRECT;
168 | if (!sysvid.fader.update(timer, fading)) {
169 | fading = sysvid_fadeEnd();
170 | // Loop directly to prevent flipping
171 | if (seq !== 7) {
172 | screen_introMain(timer);
173 | }
174 | }
175 | }
176 |
177 | if (control.status & CONTROL_EXIT) { /* check for exit request */
178 | return SCREEN_EXIT;
179 | }
180 |
181 | if (seq == 7) { /* we're done */
182 | sysvid_clear();
183 | seq = 0;
184 | seen = 0;
185 | first = false;
186 | game.period = period;
187 | return SCREEN_DONE;
188 | } else {
189 | return SCREEN_RUNNING;
190 | }
191 | }
192 |
193 | /* eof */
194 |
195 |
196 |
--------------------------------------------------------------------------------
/src/scr_imap.js:
--------------------------------------------------------------------------------
1 | import { control } from "./control";
2 | import { game, game_setmusic } from "./game";
3 | import { sysvid, sysvid_clear, sysvid_fadeStart, sysvid_fadeEnd } from "./sysvid";
4 | import { draw, draw_SCREENRECT, draw_setfb, draw_tilesSubList, draw_tilesList, draw_tile, draw_sprite } from "./draw";
5 | import { map_maps } from "./dat_maps";
6 | import { screen_imapsteps, screen_imapsl, screen_imapsofs, screen_imaptext } from "./dat_screens";
7 | import { rect_t } from "../include/rects";
8 | import { CONTROL_FIRE, CONTROL_EXIT } from "../include/control";
9 | import { SCREEN_EXIT, SCREEN_DONE, SCREEN_RUNNING } from "../include/screens";
10 | import { sys_sleep } from "./system";
11 | import { struct } from "./c";
12 |
13 | /*
14 | * local vars
15 | */
16 | let step; /* current step */
17 | let count; /* number of loops for current step */
18 | let run; /* 1 = run, 0 = no more step */
19 | let flipflop; /* flipflop for top, bottom, left, right */
20 | let spnum; /* sprite number */
21 | let spx, spdx; /* sprite x position and delta */
22 | let spy, spdy; /* sprite y position and delta */
23 | let spbase, spoffs; /* base, offset for sprite numbers table */
24 | let seq = 0; /* anim sequence */
25 |
26 | let fading;
27 |
28 | // FIXME: like draw_setfb() with +8, +16???
29 | const anim_rect = rect_t( 120 + 8, 16 + 16, 64, 64, null ); /* anim rectangle */
30 |
31 | /*
32 | * Map introduction
33 | *
34 | * ASM: 1948
35 | *
36 | * return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
37 | */
38 | export function
39 | screen_introMap(timer)
40 | {
41 | switch (seq) {
42 | case 0:
43 | sysvid_clear();
44 | /*
45 | #ifdef GFXPC
46 | draw_tilesBank = 1;
47 | draw_filter = 0xAAAA;
48 | #endif*/
49 | //#ifdef GFXST
50 | draw.tilesBank = 0;
51 | //#endif
52 | draw.tllst = [...screen_imaptext[game.map]];
53 | draw_setfb(32 + 8, 0 + 16);
54 | draw_tilesSubList();
55 |
56 | draw_setfb(32 + 8, 96 + 16); // +2???
57 | //#ifdef GFXPC
58 | // draw_filter = 0x5555;
59 | //#endif
60 | draw_tilesList();
61 |
62 | game.rects = null;
63 |
64 | //#ifdef GFXPC
65 | // draw_filter = 0xFFFF;
66 | //#endif
67 |
68 | init();
69 | nextstep();
70 | drawcenter();
71 | drawtb();
72 | drawlr();
73 | drawsprite();
74 | control.last = 0;
75 |
76 | game.rects = draw_SCREENRECT;
77 |
78 | //#ifdef ENABLE_SOUND
79 | game_setmusic(map_maps[game.map].tune, 1);
80 | //#endif
81 |
82 | seq = 1;
83 | fading = GE.Fader.IN;
84 | sysvid_fadeStart();
85 | break;
86 | case 1: /* top and bottom borders */
87 | drawtb();
88 | game.rects = anim_rect;
89 | seq = 2;
90 | break;
91 | case 2: /* background and sprite */
92 | anim();
93 | drawcenter();
94 | drawsprite();
95 | game.rects = anim_rect;
96 | seq = 3;
97 | break;
98 | case 3: /* all borders */
99 | drawtb();
100 | drawlr();
101 | game.rects = anim_rect;
102 | seq = 1;
103 | break;
104 | case 4: /* wait for key release */
105 | if (!(control.status & CONTROL_FIRE))
106 | seq = 5;
107 | else
108 | sys_sleep(50); /* .5s */
109 | break;
110 | }
111 |
112 | if (control.status & CONTROL_FIRE) { /* end as soon as key pressed */
113 | seq = 4;
114 | fading = GE.Fader.OUT;
115 | sysvid_fadeStart();
116 | }
117 |
118 | if (fading) {
119 | game.rects = draw_SCREENRECT;
120 | if (!sysvid.fader.update(timer, fading)) {
121 | fading = sysvid_fadeEnd();
122 | }
123 | }
124 |
125 | if (control.status & CONTROL_EXIT) { /* check for exit request */
126 | return SCREEN_EXIT;
127 | }
128 |
129 | if (seq === 5 && !fading) { /* end as soon as key pressed */
130 | sysvid_clear();
131 | seq = 0;
132 | return SCREEN_DONE;
133 | } else {
134 | return SCREEN_RUNNING;
135 | }
136 | }
137 |
138 |
139 | /*
140 | * Display top and bottom borders (0x1B1F)
141 | *
142 | */
143 | function
144 | drawtb()
145 | {
146 | let i;
147 |
148 | flipflop++;
149 | if (flipflop & 0x01) {
150 | draw_setfb(128 + 8, 16 + 16);
151 | for (i = 0; i < 6; i++)
152 | draw_tile(0x40);
153 | draw_setfb(128 + 8, 72 + 16);
154 | for (i = 0; i < 6; i++)
155 | draw_tile(0x06);
156 | }
157 | else {
158 | draw_setfb(128 + 8, 16 + 16);
159 | for (i = 0; i < 6; i++)
160 | draw_tile(0x05);
161 | draw_setfb(128 + 8, 72 + 16);
162 | for (i = 0; i < 6; i++)
163 | draw_tile(0x40);
164 | }
165 | }
166 |
167 |
168 | /*
169 | * Display left and right borders (0x1B7C)
170 | *
171 | */
172 | function
173 | drawlr()
174 | {
175 | let i;
176 |
177 | if (flipflop & 0x02) {
178 | for (i = 0; i < 8; i++) {
179 | draw_setfb(120 + 8, 16 + i * 8 + 16);
180 | draw_tile(0x04);
181 | draw_setfb(176 + 8, 16 + i * 8 + 16);
182 | draw_tile(0x04);
183 | }
184 | }
185 | else {
186 | for (i = 0; i < 8; i++) {
187 | draw_setfb(120 + 8, 16 + i * 8 + 16);
188 | draw_tile(0x2B);
189 | draw_setfb(176 + 8, 16 + i * 8 + 16);
190 | draw_tile(0x2B);
191 | }
192 | }
193 | }
194 |
195 |
196 | /*
197 | * Draw the sprite (0x19C6)
198 | *
199 | */
200 | function
201 | drawsprite()
202 | {
203 | draw_sprite(spnum, 128 + ((spx << 1) & 0x1C) + 8, 24 + (spy << 1) + 16);
204 | }
205 |
206 |
207 | /*
208 | * Draw the background (0x1AF1)
209 | *
210 | */
211 | function
212 | drawcenter()
213 | {
214 | const tn0 = [ 0x07, 0x5B, 0x7F, 0xA3, 0xC7 ];
215 | let i, j, tn;
216 |
217 | tn = tn0[game.map];
218 | for (i = 0; i < 6; i++) {
219 | draw_setfb(128 + 8, (24 + 8 * i) + 16);
220 | for (j = 0; j < 6; j++)
221 | draw_tile(tn++);
222 | }
223 | }
224 |
225 |
226 | /*
227 | * Next Step (0x1A74)
228 | *
229 | */
230 | function
231 | nextstep()
232 | {
233 | if (screen_imapsteps[step].count) {
234 | count = screen_imapsteps[step].count;
235 | spdx = screen_imapsteps[step].dx;
236 | spdy = screen_imapsteps[step].dy;
237 | spbase = screen_imapsteps[step].base;
238 | spoffs = 0;
239 | step++;
240 | }
241 | else {
242 | run = 0;
243 | }
244 | }
245 |
246 |
247 | /*
248 | * Anim (0x1AA8)
249 | *
250 | */
251 | function
252 | anim()
253 | {
254 | let i;
255 |
256 | if (run) {
257 | i = screen_imapsl[spbase + spoffs];
258 | if (i == 0) {
259 | spoffs = 0;
260 | i = screen_imapsl[spbase];
261 | }
262 | spnum = i;
263 | spoffs++;
264 | spx += spdx;
265 | spy += spdy;
266 | count--;
267 | if (count == 0)
268 | nextstep();
269 | }
270 | }
271 |
272 |
273 | /*
274 | * Initialize (0x1A43)
275 | *
276 | */
277 | function
278 | init()
279 | {
280 | run = 0; run--;
281 | step = screen_imapsofs[game.map];
282 | spx = screen_imapsteps[step].dx;
283 | spy = screen_imapsteps[step].dy;
284 | step++;
285 | spnum = 0; /* NOTE spnum in [8728] is never initialized ? */
286 | }
287 |
288 | /* eof */
289 |
--------------------------------------------------------------------------------
/src/scr_pause.js:
--------------------------------------------------------------------------------
1 | import { struct } from "./c";
2 | import { screen_pausedtxt } from "./dat_screens";
3 |
4 | /*
5 | * Display the pause indicator
6 | */
7 | export function
8 | screen_pause(pause)
9 | {
10 | if (pause === true) {
11 | draw.tilesBank = 0;
12 | draw.tllst = [...screen_pausedtxt];
13 | draw_setfb(120, 80);
14 | //#ifdef GFXPC
15 | // draw_filter = 0xAAAA;
16 | //#endif
17 | draw_tilesList();
18 | }
19 | else {
20 | //#ifdef GFXPC
21 | // draw_filter = 0xFFFF;
22 | //#endif
23 | draw_map();
24 | ent_draw();
25 | draw_drawStatus();
26 | }
27 | game.rects = draw_SCREENRECT;
28 | }
29 |
30 |
31 | /* eof */
32 |
33 |
--------------------------------------------------------------------------------
/src/scr_xrick.js:
--------------------------------------------------------------------------------
1 | import { sysvid_clear, sysvid_setGamePalette } from "./sysvid";
2 | import { SCREEN_EXIT, SCREEN_DONE, SCREEN_RUNNING } from "../include/screens";
3 | import { CONTROL_EXIT } from "../include/control";
4 | import { control } from "./control";
5 | import { draw_SCREENRECT } from "./draw"
6 | import { game, game_setmusic } from "./game";
7 | import { struct } from "./c";
8 |
9 | let seq = 0;
10 | let wait = 0;
11 |
12 | /*
13 | * Display XRICK splash screen
14 | *
15 | * return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
16 | */
17 | export function
18 | screen_xrick()
19 | {
20 |
21 |
22 | if (seq === 0) {
23 | sysvid_clear();
24 | // draw_img(IMG_SPLASH);
25 | game.rects = draw_SCREENRECT;
26 | seq = 1;
27 | }
28 |
29 | switch (seq) {
30 | case 1: /* wait */
31 | if (wait++ > 0x2) {
32 | //#ifdef ENABLE_SOUND
33 | game_setmusic("sounds/bullet.wav", 1);
34 | //#endif
35 | seq = 2;
36 | wait = 0;
37 | }
38 | break;
39 |
40 | case 2: /* wait */
41 | if (wait++ > 0x20) {
42 | seq = 99;
43 | wait = 0;
44 | }
45 | break;
46 | }
47 |
48 | if (control.status & CONTROL_EXIT) /* check for exit request */
49 | return SCREEN_EXIT;
50 |
51 | if (seq === 99) { /* we're done */
52 | sysvid_clear();
53 | sysvid_setGamePalette();
54 | seq = 0;
55 | return SCREEN_DONE;
56 | }
57 |
58 | return SCREEN_RUNNING;
59 | }
60 |
--------------------------------------------------------------------------------
/src/scroller.js:
--------------------------------------------------------------------------------
1 | import { draw_drawStatus, draw_map, draw_SCREENRECT } from "./draw";
2 | import { SCROLL_DONE, SCROLL_PERIOD, SCROLL_RUNNING } from "../include/scroller";
3 | import { MAP_ROW_HBBOT, MAP_ROW_HBTOP, MAP_ROW_HTBOT, MAP_ROW_HTTOP,
4 | MAP_ROW_SCRBOT, MAP_ROW_SCRTOP } from "../include/maps";
5 | import { ent_draw, ent_actvis } from "./ents";
6 | import { map, map_expand } from "./maps";
7 | import { game } from "./game";
8 | import { ent } from "../include/ents";
9 | import { struct, _U8 } from "./c";
10 |
11 | let period;
12 |
13 | /*
14 | * Scroll up
15 | *
16 | */
17 | let n1 = 0;
18 |
19 | export function
20 | scroll_up()
21 | {
22 | let i, j;
23 | // static U8 n = 0;
24 |
25 | /* last call: restore */
26 | if (n1 === 8) {
27 | n1 = 0;
28 | game.period = period;
29 | return SCROLL_DONE;
30 | }
31 |
32 | /* first call: prepare */
33 | if (n1 === 0) {
34 | period = game.period;
35 | game.period = SCROLL_PERIOD;
36 | }
37 |
38 | /* translate map */
39 | for (i = MAP_ROW_SCRTOP; i < MAP_ROW_HBBOT; i++)
40 | for (j = 0x00; j < 0x20; j++)
41 | map.map[i][j] = map.map[i + 1][j];
42 |
43 | /* translate entities */
44 | for (i = 0; ent.ents[i].n != 0xFF; i++) {
45 | if (ent.ents[i].n) {
46 | ent.ents[i].ysave -= 8;
47 | ent.ents[i].trig_y -= 8;
48 | ent.ents[i].y -= 8;
49 | if (ent.ents[i].y & 0x8000) { /* map coord. from 0x0000 to 0x0140 */
50 | /* IFDEBUG_SCROLLER(
51 | sys_printf("xrick/scroller: entity %#04X is gone\n", i);
52 | );*/
53 | ent.ents[i].n = 0;
54 | }
55 | }
56 | }
57 |
58 | /* display */
59 | draw_map();
60 | ent_draw();
61 | draw_drawStatus();
62 | map.frow = _U8(++map.frow);
63 |
64 | /* loop */
65 | if (n1++ === 7) {
66 | /* activate visible entities */
67 | ent_actvis(map.frow + MAP_ROW_HBTOP, map.frow + MAP_ROW_HBBOT);
68 |
69 | /* prepare map */
70 | map_expand();
71 |
72 | /* display */
73 | draw_map();
74 | ent_draw();
75 | draw_drawStatus();
76 | }
77 |
78 | game.rects = draw_SCREENRECT;
79 |
80 | return SCROLL_RUNNING;
81 | }
82 |
83 | /*
84 | * Scroll down
85 | *
86 | */
87 | let n2 = 0;
88 |
89 | export function
90 | scroll_down()
91 | {
92 | let i, j;
93 | // static U8 n = 0;
94 |
95 | /* last call: restore */
96 | if (n2 === 8) {
97 | n2 = 0;
98 | game.period = period;
99 | return SCROLL_DONE;
100 | }
101 |
102 | /* first call: prepare */
103 | if (n2 === 0) {
104 | period = game.period;
105 | game.period = SCROLL_PERIOD;
106 | }
107 |
108 | /* translate map */
109 | for (i = MAP_ROW_SCRBOT; i > MAP_ROW_HTTOP; i--)
110 | for (j = 0x00; j < 0x20; j++)
111 | map.map[i][j] = map.map[i - 1][j];
112 |
113 | /* translate entities */
114 | for (i = 0; ent.ents[i].n != 0xFF; i++) {
115 | if (ent.ents[i].n) {
116 | ent.ents[i].ysave += 8;
117 | ent.ents[i].trig_y += 8;
118 | ent.ents[i].y += 8;
119 | if (ent.ents[i].y > 0x0140) { /* map coord. from 0x0000 to 0x0140 */
120 | /* IFDEBUG_SCROLLER(
121 | sys_printf("xrick/scroller: entity %#04X is gone\n", i);
122 | );*/
123 | ent.ents[i].n = 0;
124 | }
125 | }
126 | }
127 |
128 | /* display */
129 | draw_map();
130 | ent_draw();
131 | draw_drawStatus();
132 | map.frow = _U8(--map.frow);
133 |
134 | /* loop */
135 | if (n2++ === 7) {
136 | /* activate visible entities */
137 | ent_actvis(map.frow + MAP_ROW_HTTOP, map.frow + MAP_ROW_HTBOT);
138 |
139 | /* prepare map */
140 | map_expand();
141 |
142 | /* display */
143 | draw_map();
144 | ent_draw();
145 | draw_drawStatus();
146 | }
147 |
148 | game.rects = draw_SCREENRECT;
149 |
150 | return SCROLL_RUNNING;
151 | }
152 |
153 | /* eof */
154 |
--------------------------------------------------------------------------------
/src/sysarg.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/sysarg.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012-2022 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | export const sysarg = {
19 | args_period: 0,
20 | args_map: 3,
21 | args_submap: 0,
22 |
23 | args_nosound: 0
24 | };
25 |
26 | /*
27 | * Read and process arguments
28 | */
29 | export function sysarg_init(argc, argv) {
30 | // TODO
31 | console.log("sysarg_init()");
32 | }
33 |
--------------------------------------------------------------------------------
/src/sysevt.js:
--------------------------------------------------------------------------------
1 | import { control } from "./control";
2 | import { CONTROL_UP, CONTROL_DOWN, CONTROL_LEFT, CONTROL_RIGHT,
3 | CONTROL_PAUSE, CONTROL_END, CONTROL_FIRE } from "../include/control";
4 |
5 | const MAN = G.EventManager;
6 | const event_man = new G.EventManager(MAN.BIT_KEYBOARD);
7 |
8 | function SETBIT(b) { control.status |= (b); }
9 | function CLRBIT(b) { control.status &= ~(b); }
10 |
11 | /*
12 | * Process an event
13 | */
14 | function
15 | processEvent(event)
16 | {
17 | let key;
18 | const E = G.Event;
19 |
20 | switch (event.type) {
21 | case E.KEYDOWN:
22 | key = event.keyCode;
23 | if (key == E.K_UP) {
24 | SETBIT(CONTROL_UP);
25 | control.last = CONTROL_UP;
26 |
27 | } else if (key == E.K_DOWN) {
28 | SETBIT(CONTROL_DOWN);
29 | control.last = CONTROL_DOWN;
30 |
31 | } else if (key == E.K_LEFT) {
32 | SETBIT(CONTROL_LEFT);
33 | control.last = CONTROL_LEFT;
34 |
35 | } else if (key == E.K_RIGHT) {
36 | SETBIT(CONTROL_RIGHT);
37 | control.last = CONTROL_RIGHT;
38 |
39 | } else if (key == 'P'.charCodeAt(0)) {
40 | SETBIT(CONTROL_PAUSE);
41 | control.last = CONTROL_PAUSE;
42 |
43 | } else if (key == E.K_ESCAPE) {
44 | SETBIT(CONTROL_END);
45 | control.last = CONTROL_END;
46 | /*
47 | } else if (key == syskbd_xtra) {
48 | SETBIT(CONTROL_EXIT);
49 | Control.last = CONTROL_EXIT;
50 | */
51 | } else if (key == E.K_SPACE) {
52 | SETBIT(CONTROL_FIRE);
53 | control.last = CONTROL_FIRE;
54 | }
55 | /*
56 | else if (key == SDLK_F1) {
57 | sysvid_toggleFullscreen();
58 | }
59 | else if (key == SDLK_F2) {
60 | sysvid_zoom(-1);
61 | }
62 | else if (key == SDLK_F3) {
63 | sysvid_zoom(+1);
64 | }
65 | #ifdef ENABLE_SOUND
66 | else if (key == SDLK_F4) {
67 | syssnd_toggleMute();
68 | }
69 | else if (key == SDLK_F5) {
70 | syssnd_vol(-1);
71 | }
72 | else if (key == SDLK_F6) {
73 | syssnd_vol(+1);
74 | }
75 | #endif
76 | #ifdef ENABLE_CHEATS
77 | else if (key == SDLK_F7) {
78 | game_toggleCheat(1);
79 | }
80 | else if (key == SDLK_F8) {
81 | game_toggleCheat(2);
82 | }
83 | else if (key == SDLK_F9) {
84 | game_toggleCheat(3);
85 | }
86 | #endif
87 | */
88 | break;
89 |
90 | case E.KEYUP:
91 | key = event.keyCode;
92 |
93 | if (key == E.K_UP) {
94 | CLRBIT(CONTROL_UP);
95 | control.last = CONTROL_UP;
96 |
97 | } else if (key == E.K_DOWN) {
98 | CLRBIT(CONTROL_DOWN);
99 | control.last = CONTROL_DOWN;
100 |
101 | } else if (key == E.K_LEFT) {
102 | CLRBIT(CONTROL_LEFT);
103 | control.last = CONTROL_LEFT;
104 |
105 | } else if (key == E.K_RIGHT) {
106 | CLRBIT(CONTROL_RIGHT);
107 | control.last = CONTROL_RIGHT;
108 |
109 | } else if (key == 'P'.charCodeAt(0)) {
110 | CLRBIT(CONTROL_PAUSE);
111 | control.last = CONTROL_PAUSE;
112 |
113 | } else if (key == 'S'.charCodeAt(0)) {
114 | sysvid.toggle_scanlines();
115 |
116 | } else if (key == E.K_ESCAPE) {
117 | CLRBIT(CONTROL_END);
118 | control.last = CONTROL_END;
119 | /*
120 | } else if (key == syskbd_xtra) {
121 | CLRBIT(CONTROL_EXIT);
122 | Control.last = CONTROL_EXIT;
123 | */
124 | } else if (key == E.K_SPACE) {
125 | CLRBIT(CONTROL_FIRE);
126 | control.last = CONTROL_FIRE;
127 | }
128 | break;
129 | default:
130 | break;
131 | }
132 | }
133 |
134 | /*
135 | * Process events, if any, then return
136 | */
137 | export function
138 | sysevt_poll()
139 | {
140 | let e;
141 |
142 | while ((e = event_man.poll())) {
143 | processEvent(e);
144 | }
145 | }
146 |
147 | /*
148 | * Wait for an event, then process it and return
149 | */
150 | export function
151 | sysevt_wait()
152 | {
153 | sysevt_poll();
154 | }
155 |
156 | /* eof */
157 |
--------------------------------------------------------------------------------
/src/syssnd.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/syssnd.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012-2022 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 |
19 | let isAudioActive = false;
20 |
21 |
22 | export function
23 | syssnd_init()
24 | {
25 | console.log("syssnd_init()");
26 | // TODO
27 | }
28 |
29 | /*
30 | * Play a sound
31 | *
32 | * loop: number of times the sound should be played, -1 to loop forever
33 | * returns: channel number, or -1 if none was available
34 | *
35 | * NOTE if sound is already playing, simply reset it (i.e. can not have
36 | * twice the same sound playing -- tends to become noisy when too many
37 | * bad guys die at the same time).
38 | */
39 | export function
40 | syssnd_play(sound, loop)
41 | {
42 | let c;
43 |
44 | if (!isAudioActive) return -1;
45 | if (sound === null) return -1;
46 |
47 | c = 0;
48 | /* SDL_mutexP(sndlock);
49 | while ((channel[c].snd != sound || channel[c].loop == 0) &&
50 | channel[c].loop != 0 &&
51 | c < SYSSND_MIXCHANNELS)
52 | c++;
53 | if (c == SYSSND_MIXCHANNELS)
54 | c = -1;
55 |
56 | IFDEBUG_AUDIO(
57 | if (channel[c].snd == sound && channel[c].loop != 0)
58 | sys_printf("xrick/sound: already playing %s on channel %d - resetting\n",
59 | sound->name, c);
60 | else if (c >= 0)
61 | sys_printf("xrick/sound: playing %s on channel %d\n", sound->name, c);
62 | );
63 |
64 | if (c >= 0) {
65 | channel[c].loop = loop;
66 | channel[c].snd = sound;
67 | channel[c].buf = sound->buf;
68 | channel[c].len = sound->len;
69 | }
70 | SDL_mutexV(sndlock);*/
71 |
72 | console.log("syssnd_play(%s) %dx", sound, loop);
73 | return c;
74 | }
75 |
--------------------------------------------------------------------------------
/src/system.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/system.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012-2022 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | import { sysarg_init, sysarg } from "./sysarg";
19 | import { sysvid_init } from "./sysvid";
20 | import { syssnd_init } from "./syssnd";
21 |
22 | let /*U32*/ ticks_base = 0; // static
23 |
24 | /*
25 | * Return number of microseconds elapsed since first call
26 | */
27 | export function
28 | sys_gettime()
29 | {
30 | // See static above
31 | let ticks;
32 |
33 | ticks = Date.now();
34 |
35 | if (!ticks_base) {
36 | ticks_base = ticks;
37 | }
38 |
39 | return ticks - ticks_base;
40 | }
41 |
42 |
43 | /*
44 | * Sleep a number of microseconds
45 | */
46 | export function
47 | sys_sleep(s)
48 | {
49 | console.log("sys_sleep(%d)", s);
50 | //SDL_Delay(s);
51 | }
52 |
53 | /*
54 | * Initialize system
55 | */
56 | export function
57 | sys_init(argc, argv)
58 | {
59 | sysarg_init(argc, argv);
60 | sysvid_init();
61 | //#ifdef ENABLE_JOYSTICK
62 | // sysjoy_init();
63 | //#endif
64 | //#ifdef ENABLE_SOUND
65 | if (sysarg.args_nosound === 0) {
66 | syssnd_init();
67 | }
68 | //#endif
69 | // atexit(sys_shutdown);
70 | // signal(SIGINT, exit);
71 | // signal(SIGTERM, exit);
72 | }
73 |
74 | /*
75 | * Shutdown system
76 | */
77 | export function
78 | sys_shutdown()
79 | {
80 | //#ifdef ENABLE_SOUND
81 | syssnd_shutdown();
82 | //#endif
83 | //#ifdef ENABLE_JOYSTICK
84 | // sysjoy_shutdown();
85 | //#endif
86 | sysvid_shutdown();
87 | }
88 |
89 | /* eof */
90 |
--------------------------------------------------------------------------------
/src/sysvid.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/sysvid.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012-2022 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | import { rect_t } from "../include/rects";
19 | import { SYSVID_WIDTH, SYSVID_HEIGHT } from "../include/system";
20 | import { as_const } from "./c";
21 |
22 | export const sysvid = {
23 | fb: null /* frame buffer */,
24 | fader: null
25 | };
26 | const SCREENRECT = as_const(rect_t(0, 0, SYSVID_WIDTH, SYSVID_HEIGHT, null));
27 |
28 | let screen, buffer;
29 |
30 | /*
31 | * Initialize screen
32 | */
33 | function
34 | initScreen(w, h/*, bpp, flags*/)
35 | {
36 | var s = new G.Screen(w, h);
37 | G.Screen.setActive(s);
38 | s.enableFiltering(false);
39 | s.setStretch(s.STRETCH_UNIFORM);
40 |
41 | return s;
42 | }
43 |
44 | export function
45 | sysvid_setGamePalette()
46 | {
47 | console.log("sysvid_setGamePalette()");
48 | // TODO
49 | }
50 |
51 | /*
52 | * Initialise video
53 | */
54 | export function
55 | sysvid_init()
56 | {
57 | // TODO: zoom
58 | screen = initScreen(SYSVID_WIDTH, SYSVID_HEIGHT);
59 |
60 | /*
61 | * create v_ frame buffer
62 | */
63 | sysvid.fb = new G.Surface(SYSVID_WIDTH, SYSVID_HEIGHT);
64 |
65 | // Gamalto specific to handle true color mode
66 | buffer = sysvid.fb;
67 | sysvid.fader = new GE.Fader(sysvid.fb, new G.Color(), 150);
68 | }
69 |
70 | /*
71 | * Shutdown video
72 | */
73 | export function
74 | sysvid_shutdown()
75 | {
76 | // free(sysvid_fb);
77 | sysvid.fb = null;
78 | console.log("sysvid_shutdown()");
79 | // SDL_Quit();
80 | }
81 |
82 |
83 | /*
84 | * Update screen
85 | * NOTE errors processing ?
86 | */
87 | export function
88 | sysvid_update(rects)
89 | {
90 | if (rects == null)
91 | return;
92 |
93 | const rs = [];
94 | while (rects) {
95 | rs.push(new G.Rect(rects.x, rects.y, rects.width, rects.height));
96 | rects = rects.next;
97 | }
98 | screen.redraw(buffer, 0, 0, rs);
99 | screen.refresh();
100 | }
101 |
102 | /*
103 | * Clear screen
104 | * (077C)
105 | */
106 | export function
107 | sysvid_clear()
108 | {
109 | sysvid.fb.renderer.fillRect(null, new G.Color(0,0,0));
110 | }
111 |
112 | /*
113 | * Gamalto
114 | */
115 | export function
116 | sysvid_fadeStart()
117 | {
118 | sysvid.fader.reset();
119 | buffer = sysvid.fader.surface;
120 | }
121 |
122 | export function
123 | sysvid_fadeEnd()
124 | {
125 | buffer = sysvid.fb;
126 | }
127 |
128 | /* eof */
129 |
--------------------------------------------------------------------------------
/src/util.js:
--------------------------------------------------------------------------------
1 | import { ent, ENT_ENTSNUM } from "../include/ents";
2 | import { ent_entdata } from "./dat_ents";
3 | import { map } from "./maps";
4 | import { game } from "./game";
5 | import { e_rick_boxtest } from "./e_rick";
6 | import { E_RICK_NO } from "../include/e_rick";
7 | import { MAP_EFLG_01, MAP_EFLG_CLIMB, MAP_EFLG_FGND, MAP_EFLG_LETHAL,
8 | MAP_EFLG_SOLID, MAP_EFLG_SPAD, MAP_EFLG_VERT,
9 | MAP_EFLG_WAYUP } from "../include/maps";
10 | import { _U8 } from "./c";
11 |
12 | /*
13 | * Full box test.
14 | *
15 | * ASM 1199
16 | *
17 | * e: entity to test against.
18 | * x,y: coordinates to test.
19 | * ret: TRUE/(x,y) is within e's space, FALSE/not.
20 | */
21 | export function
22 | u_fboxtest(e, x, y)
23 | {
24 | if (ent.ents[e].x >= x ||
25 | ent.ents[e].x + ent.ents[e].w < x ||
26 | ent.ents[e].y >= y ||
27 | ent.ents[e].y + ent.ents[e].h < y)
28 | return false;
29 | else
30 | return true;
31 | }
32 |
33 |
34 |
35 |
36 | /*
37 | * Box test (then whole e2 is checked agains the center of e1).
38 | *
39 | * ASM 113E
40 | *
41 | * e1: entity to test against (corresponds to DI in asm code).
42 | * e2: entity to test (corresponds to SI in asm code).
43 | * ret: TRUE/intersect, FALSE/not.
44 | */
45 | export function
46 | u_boxtest(e1, e2)
47 | {
48 | /* rick is special (may be crawling) */
49 | if (e1 === E_RICK_NO)
50 | return e_rick_boxtest(e2);
51 |
52 | /*
53 | * entity 1: x+0x05 to x+0x011, y to y+0x14
54 | * entity 2: x to x+ .w, y to y+ .h
55 | */
56 | if (ent.ents[e1].x + 0x11 < ent.ents[e2].x ||
57 | ent.ents[e1].x + 0x05 > ent.ents[e2].x + ent.ents[e2].w ||
58 | ent.ents[e1].y + 0x14 < ent.ents[e2].y ||
59 | ent.ents[e1].y > ent.ents[e2].y + ent.ents[e2].h - 1)
60 | return false;
61 | else
62 | return true;
63 | }
64 |
65 |
66 | /*
67 | * Compute the environment flag.
68 | *
69 | * ASM 0FBC if !crawl, else 103E
70 | *
71 | * x, y: coordinates where to compute the environment flag
72 | * crawl: is rick crawling?
73 | * rc0: anything CHANGED to the environment flag for crawling (6DBA)
74 | * rc1: anything CHANGED to the environment flag (6DAD)
75 | */
76 | export function
77 | u_envtest(x, y, crawl, rc0, rc1)
78 | {
79 | let i, xx;
80 |
81 | /* prepare for ent #0 test */
82 | ent.ents[ENT_ENTSNUM].x = x;
83 | ent.ents[ENT_ENTSNUM].y = y;
84 |
85 | i = 1;
86 | if (!crawl) i++;
87 | if (y & 0x0004) i++;
88 |
89 | x += 4;
90 | xx = _U8(x); /* FIXME? */
91 |
92 | x = x >> 3; /* from pixels to tiles */
93 | y = y >> 3; /* from pixels to tiles */
94 |
95 | rc0 = rc1 = 0;
96 |
97 | if (xx & 0x07) { /* tiles columns alignment */
98 | if (crawl) {
99 | rc0 |= (map.eflg[map.map[y][x]] &
100 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
101 | rc0 |= (map.eflg[map.map[y][x + 1]] &
102 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
103 | rc0 |= (map.eflg[map.map[y][x + 2]] &
104 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
105 | y++;
106 | }
107 | do {
108 | rc1 |= (map.eflg[map.map[y][x]] &
109 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
110 | MAP_EFLG_LETHAL|MAP_EFLG_01));
111 | rc1 |= (map.eflg[map.map[y][x + 1]] &
112 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
113 | MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
114 | rc1 |= (map.eflg[map.map[y][x + 2]] &
115 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
116 | MAP_EFLG_LETHAL|MAP_EFLG_01));
117 | y++;
118 | } while (--i > 0);
119 |
120 | rc1 |= (map.eflg[map.map[y][x]] &
121 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP|MAP_EFLG_FGND|
122 | MAP_EFLG_LETHAL|MAP_EFLG_01));
123 | rc1 |= (map.eflg[map.map[y][x + 1]]);
124 | rc1 |= (map.eflg[map.map[y][x + 2]] &
125 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP|MAP_EFLG_FGND|
126 | MAP_EFLG_LETHAL|MAP_EFLG_01));
127 | }
128 | else {
129 | if (crawl) {
130 | rc0 |= (map.eflg[map.map[y][x]] &
131 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
132 | rc0 |= (map.eflg[map.map[y][x + 1]] &
133 | (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
134 | y++;
135 | }
136 | do {
137 | rc1 |= (map.eflg[map.map[y][x]] &
138 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
139 | MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
140 | rc1 |= (map.eflg[map.map[y][x + 1]] &
141 | (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
142 | MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
143 | y++;
144 | } while (--i > 0);
145 |
146 | rc1 |= (map.eflg[map.map[y][x]]);
147 | rc1 |= (map.eflg[map.map[y][x + 1]]);
148 | }
149 |
150 | /*
151 | * If not lethal yet, and there's an entity on slot zero, and (x,y)
152 | * boxtests this entity, then raise SOLID flag. This is how we make
153 | * sure that no entity can move over the entity that is on slot zero.
154 | *
155 | * Beware! When game_cheat2 is set, this means that a block can
156 | * move over rick without killing him -- but then rick is trapped
157 | * because the block is solid.
158 | */
159 | if (!(rc1 & MAP_EFLG_LETHAL)
160 | && ent.ents[0].n
161 | && u_boxtest(ENT_ENTSNUM, 0)) {
162 | rc1 |= MAP_EFLG_SOLID;
163 | }
164 |
165 | /* When game_cheat2 is set, the environment can not be lethal. */
166 | //#ifdef ENABLE_CHEATS
167 | if (game.cheat2) rc1 &= ~MAP_EFLG_LETHAL;
168 | //#endif
169 |
170 | return { rc0, rc1 };
171 | }
172 |
173 |
174 | /*
175 | * Check if x,y is within e trigger box.
176 | *
177 | * ASM 126F
178 | * return: FALSE if not in box, TRUE if in box.
179 | */
180 | export function
181 | u_trigbox(e, x, y)
182 | {
183 | let xmax, ymax;
184 |
185 | xmax = ent.ents[e].trig_x + (ent_entdata[ent.ents[e].n & 0x7F].trig_w << 3);
186 | ymax = ent.ents[e].trig_y + (ent_entdata[ent.ents[e].n & 0x7F].trig_h << 3);
187 |
188 | if (xmax > 0xFF) xmax = 0xFF;
189 |
190 | if (x <= ent.ents[e].trig_x || x > xmax ||
191 | y <= ent.ents[e].trig_y || y > ymax)
192 | return false;
193 | else
194 | return true;
195 | }
196 |
197 |
198 | /* eof */
199 |
200 |
201 |
--------------------------------------------------------------------------------
/src/xrick.js:
--------------------------------------------------------------------------------
1 | /*
2 | * RickJS, a JavaScript port of XRick
3 | *
4 | * This source file is based on the folliwing files:
5 | * - xrick/src/xrick.c
6 | *
7 | * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
8 | * Copyright (C) 2012-2022 Chrilith (me@chrilith.com). All rights reserved.
9 | *
10 | * The use and distribution terms for this software are contained in the file
11 | * named README, which can be found in the root of this distribution. By
12 | * using this software in any fashion, you are agreeing to be bound by the
13 | * terms of this license.
14 | *
15 | * You must not remove this notice, or any other, from this software.
16 | */
17 |
18 | import { sys_init } from "./system";
19 | import { game_run } from "./game";
20 | import { dat_init } from "./dat_loader";
21 |
22 | import { sysarg } from "./sysarg";
23 |
24 | /*
25 | * main
26 | */
27 | export async function main(argc, argv) {
28 | console.log("Running xrick...");
29 | sys_init(argc, argv);
30 | /* if (sysarg_args_data) {
31 | data_setpath(sysarg_args_data);
32 | } else {
33 | data_setpath("data.zip");
34 | }*/
35 | await dat_init();
36 | game_run();
37 | /* data_closepath();
38 | sys_shutdown();*/
39 | return 0;
40 | }
41 |
42 | /* eof */
43 |
--------------------------------------------------------------------------------
/xrick.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 | RickJS, a JavaScript port of XRick using HTML5
10 |
11 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------