romdevtools 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +17 -10
- package/CHANGELOG.md +63 -0
- package/examples/atari2600/main.asm +1 -1
- package/examples/atari2600/templates/default.asm +1 -1
- package/examples/atari2600/templates/paddle.asm +59 -47
- package/examples/atari7800/main.c +1 -1
- package/examples/atari7800/templates/default.c +1 -1
- package/examples/atari7800/templates/music_demo.c +1 -1
- package/examples/c64/main.c +1 -1
- package/examples/c64/templates/platformer.c +2 -2
- package/examples/c64/templates/puzzle.c +1 -1
- package/examples/c64/templates/racing.c +3 -3
- package/examples/c64/templates/shmup.c +6 -5
- package/examples/c64/templates/sports.c +4 -4
- package/examples/gb/main.asm +1 -1
- package/examples/gb/main.c +1 -1
- package/examples/gb/templates/puzzle.c +1 -1
- package/examples/gb/templates/racing.c +1 -1
- package/examples/gb/templates/shmup.c +1 -1
- package/examples/gba/templates/gba_hello.c +1 -1
- package/examples/gba/templates/maxmod_demo.c +1 -1
- package/examples/gba/templates/puzzle.c +17 -3
- package/examples/gba/templates/racing.c +16 -2
- package/examples/gba/templates/shmup.c +23 -4
- package/examples/gba/templates/tonc_hello.c +6 -4
- package/examples/gbc/main.asm +1 -1
- package/examples/gbc/templates/puzzle.c +1 -1
- package/examples/gbc/templates/racing.c +1 -1
- package/examples/gbc/templates/shmup.c +1 -1
- package/examples/genesis/main.s +1 -1
- package/examples/genesis/templates/puzzle.c +1 -1
- package/examples/genesis/templates/racing.c +45 -1
- package/examples/genesis/templates/shmup.c +12 -3
- package/examples/genesis/templates/shmup_2p.c +2 -2
- package/examples/genesis/templates/sports.c +39 -0
- package/examples/gg/templates/hello_sprite.c +38 -23
- package/examples/gg/templates/music_demo.c +11 -8
- package/examples/gg/templates/platformer.c +37 -15
- package/examples/gg/templates/racing.c +25 -12
- package/examples/gg/templates/shmup.c +12 -6
- package/examples/gg/templates/sports.c +30 -16
- package/examples/gg/templates/tile_engine.c +24 -10
- package/examples/lynx/templates/platformer.c +7 -1
- package/examples/lynx/templates/puzzle.c +8 -2
- package/examples/lynx/templates/racing.c +7 -1
- package/examples/lynx/templates/sports.c +7 -1
- package/examples/nes/main.c +2 -2
- package/examples/nes/space-shooter/nes_runtime.h +1 -1
- package/examples/nes/templates/default.c +4 -1
- package/examples/nes/templates/racing.c +50 -1
- package/examples/pce/main.c +1 -1
- package/examples/sms/templates/hello_sprite.c +1 -1
- package/examples/sms/templates/music_demo.c +1 -1
- package/examples/sms/templates/puzzle.c +1 -1
- package/examples/sms/templates/racing.c +1 -1
- package/examples/sms/templates/shmup.c +1 -1
- package/examples/sms/templates/shmup_2p.c +2 -2
- package/examples/snes/main.asm +1 -1
- package/examples/snes/templates/c-hello-data.asm +309 -14
- package/examples/snes/templates/c-hello.c +13 -2
- package/examples/snes/templates/default.c +1 -1
- package/examples/snes/templates/hello_sprite-data.asm +300 -2
- package/examples/snes/templates/hello_sprite.c +10 -1
- package/examples/snes/templates/music_demo-data.asm +300 -2
- package/examples/snes/templates/music_demo.c +10 -1
- package/examples/snes/templates/platformer-data.asm +300 -2
- package/examples/snes/templates/platformer.c +10 -1
- package/examples/snes/templates/puzzle-data.asm +300 -2
- package/examples/snes/templates/puzzle.c +11 -1
- package/examples/snes/templates/racing-data.asm +300 -2
- package/examples/snes/templates/racing.c +40 -4
- package/examples/snes/templates/shmup-data.asm +299 -6
- package/examples/snes/templates/shmup.c +11 -7
- package/examples/snes/templates/sports-data.asm +300 -2
- package/examples/snes/templates/sports.c +40 -5
- package/package.json +1 -1
- package/src/mcp/tools/project.js +33 -22
- package/src/mcp/tools/toolchain.js +183 -19
- package/src/observer/livestream.html +34 -4
- package/src/platforms/gg/MENTAL_MODEL.md +14 -13
- package/src/platforms/gg/lib/c/vdp_init.c +10 -8
- package/src/platforms/msx/MENTAL_MODEL.md +1 -1
- package/src/platforms/nes/TROUBLESHOOTING.md +1 -1
- package/src/platforms/nes/lib/c/nes_runtime.c +28 -6
- package/src/platforms/pce/MENTAL_MODEL.md +1 -1
- package/src/platforms/pce/lib/c/pce_hw.h +1 -0
- package/src/platforms/pce/lib/c/pce_video.c +26 -0
- package/src/platforms/sms/MENTAL_MODEL.md +12 -12
- package/src/platforms/sms/lib/c/vdp_init.c +10 -8
- package/src/platforms/sms/lib/vdp_init.s +1 -1
- package/src/toolchains/cc65/presets/nes/chr-ram-runtime.cfg +1 -1
- package/src/toolchains/cc65/presets/nes/chr-ram.cfg +1 -1
- package/src/toolchains/cc65/presets/nes/chr-ram.crt0.s +1 -1
- package/src/toolchains/genesis-c/README.md +1 -1
- package/src/toolchains/sdcc/preflight-lint.js +47 -7
- package/src/toolchains/snes-c/snes-c.js +3 -7
|
@@ -17,19 +17,32 @@ extern void gg_sprite_init(void);
|
|
|
17
17
|
extern void gg_sprite_set(uint8_t slot, uint8_t x, uint8_t y, uint8_t tile);
|
|
18
18
|
extern void gg_sat_upload(void);
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
/* ── Game Gear visible viewport ──────────────────────────────────────
|
|
21
|
+
* Only the centered 160x144 of the 256x192 frame shows. Keep the whole
|
|
22
|
+
* court inside [VIS_X0..VIS_X1] x [VIS_Y0..VIS_Y1] or it's off-screen. */
|
|
23
|
+
#define VIS_X0 48
|
|
24
|
+
#define VIS_Y0 24
|
|
25
|
+
#define VIS_X1 207 /* 48 + 160 - 1 */
|
|
26
|
+
#define VIS_Y1 167 /* 24 + 144 - 1 */
|
|
27
|
+
|
|
28
|
+
#define COURT_TOP VIS_Y0
|
|
29
|
+
#define COURT_BOT VIS_Y1
|
|
22
30
|
#define PADDLE_H 24
|
|
23
31
|
#define BALL_SIZE 8
|
|
24
|
-
#define PADDLE_X1
|
|
25
|
-
#define PADDLE_X2
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
#define PADDLE_X1 (VIS_X0 + 8) /* near the visible left edge */
|
|
33
|
+
#define PADDLE_X2 (VIS_X1 - 16) /* near the visible right edge */
|
|
34
|
+
|
|
35
|
+
/* GG palette = 32 entries × 2 bytes (4-4-4 BGR LE): low=(g<<4)|r, high=b.
|
|
36
|
+
* gg_load_palette reads 64 bytes; a 32-byte array leaves the sprite palette
|
|
37
|
+
* (entries 16-31) reading garbage = invisible sprites. Sprite colour 1 = entry
|
|
38
|
+
* 17 (white). */
|
|
39
|
+
static const uint8_t palette[64] = {
|
|
40
|
+
/* BG 0-15: entry 0 = dark navy backdrop */
|
|
41
|
+
0x20,0x02, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
|
42
|
+
0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
|
43
|
+
/* SPRITE 16-31: 16=transparent, 17=white */
|
|
44
|
+
0,0, 0xFF,0x0F, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
|
45
|
+
0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
|
33
46
|
};
|
|
34
47
|
|
|
35
48
|
static const uint8_t tile_solid[32] = {
|
|
@@ -45,15 +58,16 @@ static uint8_t score_p1, score_p2;
|
|
|
45
58
|
static uint8_t serve_timer;
|
|
46
59
|
|
|
47
60
|
static void serve_ball(uint8_t to_left) {
|
|
48
|
-
bx =
|
|
49
|
-
by =
|
|
61
|
+
bx = (VIS_X0 + VIS_X1) / 2;
|
|
62
|
+
by = (VIS_Y0 + VIS_Y1) / 2;
|
|
50
63
|
bdx = to_left ? -2 : 2;
|
|
51
64
|
bdy = ((score_p1 + score_p2) & 1) ? -1 : 1;
|
|
52
65
|
serve_timer = 30;
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
static void reset_match(void) {
|
|
56
|
-
p1y =
|
|
69
|
+
p1y = (VIS_Y0 + VIS_Y1) / 2 - PADDLE_H / 2;
|
|
70
|
+
p2y = p1y;
|
|
57
71
|
score_p1 = 0; score_p2 = 0;
|
|
58
72
|
serve_ball(0);
|
|
59
73
|
}
|
|
@@ -130,8 +144,8 @@ void main(void) {
|
|
|
130
144
|
sfx_tone(0, 250, 3);
|
|
131
145
|
}
|
|
132
146
|
|
|
133
|
-
if (bx <
|
|
134
|
-
if (bx >
|
|
147
|
+
if (bx < VIS_X0) { if (score_p2 < 9) score_p2++; sfx_noise(20); serve_ball(0); }
|
|
148
|
+
if (bx > VIS_X1 - BALL_SIZE) { if (score_p1 < 9) score_p1++; sfx_tone(0, 180, 16); serve_ball(1); }
|
|
135
149
|
}
|
|
136
150
|
} while (1);
|
|
137
151
|
}
|
|
@@ -30,15 +30,28 @@ extern void gg_sat_upload(void);
|
|
|
30
30
|
|
|
31
31
|
#define T_OPEN 0
|
|
32
32
|
#define T_WALL 1
|
|
33
|
-
#define T_SPR 0 /* sprite tile uses sprite-tile-bank (R6=
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
#define T_SPR 0 /* sprite tile uses sprite-tile-bank (R6=0xFF → $2000) */
|
|
34
|
+
|
|
35
|
+
/* ── Game Gear visible viewport ──────────────────────────────────────
|
|
36
|
+
* The 32x24 name table fills the whole 256x192 frame, but only the
|
|
37
|
+
* centered 160x144 SHOWS: fetch pixels [VIS_X0..VIS_X1] x [VIS_Y0..VIS_Y1]
|
|
38
|
+
* (tile columns 6..25, rows 3..20). Place the player sprite inside it. */
|
|
39
|
+
#define VIS_X0 48
|
|
40
|
+
#define VIS_Y0 24
|
|
41
|
+
#define VIS_X1 207 /* 48 + 160 - 1 */
|
|
42
|
+
#define VIS_Y1 167 /* 24 + 144 - 1 */
|
|
43
|
+
|
|
44
|
+
/* GG palette = 32 entries × 2 bytes (4-4-4 BGR LE): low=(g<<4)|r, high=b.
|
|
45
|
+
* gg_load_palette reads 64 bytes; a 32-byte array leaves the sprite palette
|
|
46
|
+
* (entries 16-31) reading garbage = invisible sprites. BG colour 1 = entry 1
|
|
47
|
+
* (dark grey wall); sprite colour 1 = entry 17 (white player). */
|
|
48
|
+
static const uint8_t palette[64] = {
|
|
49
|
+
/* BG 0-15: entry 0 = dark navy backdrop, entry 1 = dark grey wall */
|
|
50
|
+
0x20,0x02, 0x66,0x06, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
|
51
|
+
0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
|
52
|
+
/* SPRITE 16-31: 16=transparent, 17=white player */
|
|
53
|
+
0,0, 0xFF,0x0F, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
|
54
|
+
0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
|
42
55
|
};
|
|
43
56
|
|
|
44
57
|
static const uint8_t bg_tiles[32 * 2] = {
|
|
@@ -92,7 +105,8 @@ static uint8_t solid_at(int16_t px, int16_t py) {
|
|
|
92
105
|
}
|
|
93
106
|
|
|
94
107
|
void main(void) {
|
|
95
|
-
|
|
108
|
+
/* Start the player inside the visible window (tile ~10,10 = pixel 80,80). */
|
|
109
|
+
int16_t px = 80, py = 80;
|
|
96
110
|
|
|
97
111
|
gg_vdp_init();
|
|
98
112
|
gg_load_palette(palette);
|
|
@@ -43,7 +43,13 @@ void main(void) {
|
|
|
43
43
|
sfx_init();
|
|
44
44
|
|
|
45
45
|
for (;;) {
|
|
46
|
-
|
|
46
|
+
/* Lynx frame loop: WAIT for the blitter, then clear with a full-screen
|
|
47
|
+
* tgi_bar (NOT tgi_clear, which leaves the back page stale on this core)
|
|
48
|
+
* — drawing while the blitter is mid-flight loses the frame → black.
|
|
49
|
+
* (Copied from the shmup scaffold, the LYNX-1 fix.) */
|
|
50
|
+
while (tgi_busy()) { }
|
|
51
|
+
tgi_setcolor(COLOR_BLACK);
|
|
52
|
+
tgi_bar(0, 0, tgi_getmaxx(), tgi_getmaxy());
|
|
47
53
|
tgi_setcolor(COLOR_GREY);
|
|
48
54
|
for (i = 0; i < N_PLATFORMS; i++) {
|
|
49
55
|
tgi_bar(platforms[i].x, platforms[i].y, platforms[i].x + platforms[i].w - 1, platforms[i].y + platforms[i].h - 1);
|
|
@@ -62,7 +62,7 @@ static void lock_piece(void) {
|
|
|
62
62
|
a = grid[r][c]; b = grid[r][c+1]; d = grid[r][c+2];
|
|
63
63
|
if (a != 0 && a == b && b == d) {
|
|
64
64
|
grid[r][c] = 0; grid[r][c+1] = 0; grid[r][c+2] = 0;
|
|
65
|
-
if (score <
|
|
65
|
+
if (score < 65500u) score += 30;
|
|
66
66
|
sfx_tone(0, 60, 10);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -93,7 +93,13 @@ void main(void) {
|
|
|
93
93
|
new_piece();
|
|
94
94
|
|
|
95
95
|
for (;;) {
|
|
96
|
-
|
|
96
|
+
/* Lynx frame loop: WAIT for the blitter, then clear with a full-screen
|
|
97
|
+
* tgi_bar (NOT tgi_clear, which leaves the back page stale on this core)
|
|
98
|
+
* — drawing while the blitter is mid-flight loses the frame → black.
|
|
99
|
+
* (Copied from the shmup scaffold, the LYNX-1 fix.) */
|
|
100
|
+
while (tgi_busy()) { }
|
|
101
|
+
tgi_setcolor(COLOR_BLACK);
|
|
102
|
+
tgi_bar(0, 0, tgi_getmaxx(), tgi_getmaxy());
|
|
97
103
|
/* grid */
|
|
98
104
|
for (r = 0; r < ROWS; r++) for (c = 0; c < COLS; c++) {
|
|
99
105
|
if (grid[r][c] != 0) {
|
|
@@ -31,7 +31,13 @@ void main(void) {
|
|
|
31
31
|
for (i = 0; i < MAX_OBS; i++) obs[i].alive = 0;
|
|
32
32
|
|
|
33
33
|
for (;;) {
|
|
34
|
-
|
|
34
|
+
/* Lynx frame loop: WAIT for the blitter, then clear with a full-screen
|
|
35
|
+
* tgi_bar (NOT tgi_clear, which leaves the back page stale on this core)
|
|
36
|
+
* — drawing while the blitter is mid-flight loses the frame → black.
|
|
37
|
+
* (Copied from the shmup scaffold, the LYNX-1 fix.) */
|
|
38
|
+
while (tgi_busy()) { }
|
|
39
|
+
tgi_setcolor(COLOR_BLACK);
|
|
40
|
+
tgi_bar(0, 0, tgi_getmaxx(), tgi_getmaxy());
|
|
35
41
|
/* lane lines */
|
|
36
42
|
tgi_setcolor(COLOR_DARKGREY);
|
|
37
43
|
tgi_line(28, 0, 28, 101);
|
|
@@ -28,7 +28,13 @@ void main(void) {
|
|
|
28
28
|
sfx_init();
|
|
29
29
|
|
|
30
30
|
for (;;) {
|
|
31
|
-
|
|
31
|
+
/* Lynx frame loop: WAIT for the blitter, then clear with a full-screen
|
|
32
|
+
* tgi_bar (NOT tgi_clear, which leaves the back page stale on this core)
|
|
33
|
+
* — drawing while the blitter is mid-flight loses the frame → black.
|
|
34
|
+
* (Copied from the shmup scaffold, the LYNX-1 fix.) */
|
|
35
|
+
while (tgi_busy()) { }
|
|
36
|
+
tgi_setcolor(COLOR_BLACK);
|
|
37
|
+
tgi_bar(0, 0, tgi_getmaxx(), tgi_getmaxy());
|
|
32
38
|
tgi_setcolor(COLOR_WHITE);
|
|
33
39
|
tgi_bar(PADDLE_X1, (unsigned)p1y, PADDLE_X1 + PADDLE_W - 1, (unsigned)(p1y + PADDLE_H - 1));
|
|
34
40
|
tgi_bar(PADDLE_X2, (unsigned)p2y, PADDLE_X2 + PADDLE_W - 1, (unsigned)(p2y + PADDLE_H - 1));
|
package/examples/nes/main.c
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
* 5. Enables the PPU and loops forever (NMI does all the real work).
|
|
10
10
|
*
|
|
11
11
|
* BUILD: this file expects linkerConfig: "chr-ram" so the CHR-RAM
|
|
12
|
-
* region is writable at runtime. Pass it to
|
|
12
|
+
* region is writable at runtime. Pass it to build:
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* build({ output: "rom",
|
|
15
15
|
* platform: "nes",
|
|
16
16
|
* language: "c",
|
|
17
17
|
* linkerConfig: "chr-ram",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ── nes_runtime.h — neslib-shaped runtime for cc65 NES builds ───
|
|
2
|
-
* Auto-included on every `
|
|
2
|
+
* Auto-included on every `build({ output: "rom", platform:"nes", language:"c"})`.
|
|
3
3
|
*
|
|
4
4
|
* API mirrors Shiru's neslib so existing tutorials port cleanly:
|
|
5
5
|
*
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
#include "nes_runtime.h"
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
/* 4 VISIBLE hues — never 0x0F (black), so a screenshot on ANY phase of the
|
|
17
|
+
* cycle shows a non-black backdrop (NES-2: the old cycle started on + passed
|
|
18
|
+
* through black, so a fresh agent's screenshot could land on a "blank" frame). */
|
|
19
|
+
static const uint8_t bg_colors[4] = { 0x21, 0x01, 0x11, 0x31 };
|
|
17
20
|
|
|
18
21
|
void main(void) {
|
|
19
22
|
uint8_t palette[32];
|
|
@@ -56,6 +56,26 @@ static const uint8_t tile_digits[10 * 16] = {
|
|
|
56
56
|
#define T_CAR_ENEMY 2
|
|
57
57
|
#define T_DIGIT0 3
|
|
58
58
|
|
|
59
|
+
/* ── Background road tiles ───────────────────────────────────────────
|
|
60
|
+
* Default PPUCTRL ($90) reads BG patterns from pattern table 1 ($1000),
|
|
61
|
+
* so these go to CHR $1000+ and are indexed independently of the sprite
|
|
62
|
+
* tiles above. Colour 1 (white, BG palette 0) draws the markings; the
|
|
63
|
+
* grey backdrop (colour 0) is the road surface.
|
|
64
|
+
*
|
|
65
|
+
* BG_T_EDGE: a solid 2px vertical stripe — the road shoulder line.
|
|
66
|
+
* BG_T_LANE: a 2px vertical dash (on for 4 rows, off for 4) — the
|
|
67
|
+
* dashed centre lane marking when stacked down a column. */
|
|
68
|
+
#define BG_T_EDGE 1
|
|
69
|
+
#define BG_T_LANE 2
|
|
70
|
+
static const uint8_t bg_tile_edge[16] = {
|
|
71
|
+
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* plane 0 (colour bit 0) */
|
|
72
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
|
73
|
+
};
|
|
74
|
+
static const uint8_t bg_tile_lane[16] = {
|
|
75
|
+
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* dash: 4 on, 4 off */
|
|
76
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
|
77
|
+
};
|
|
78
|
+
|
|
59
79
|
static const uint8_t palette[32] = {
|
|
60
80
|
/* BG palettes — light grey backdrop simulates road */
|
|
61
81
|
0x10, 0x30, 0x16, 0x12,
|
|
@@ -93,6 +113,29 @@ static uint8_t aabb(Car *a, Car *b) {
|
|
|
93
113
|
&& a->y < b->y + 8 && a->y + 8 > b->y;
|
|
94
114
|
}
|
|
95
115
|
|
|
116
|
+
/* Draw the static road into nametable 0 ($2000): solid shoulder lines on
|
|
117
|
+
* the outside of the outer lanes and dashed dividers between the three
|
|
118
|
+
* lanes. PPU must be OFF — call from init (uses vram_unsafe_set). Tile
|
|
119
|
+
* columns: lanes sit at 11/15/19, so dividers go at 13/17 and shoulders
|
|
120
|
+
* just outside at 9/21. */
|
|
121
|
+
#define ROAD_TOP_ROW 2
|
|
122
|
+
#define ROAD_BOT_ROW 27
|
|
123
|
+
#define ROAD_EDGE_L 9
|
|
124
|
+
#define ROAD_EDGE_R 21
|
|
125
|
+
#define ROAD_DIV_1 13
|
|
126
|
+
#define ROAD_DIV_2 17
|
|
127
|
+
static void draw_road(void) {
|
|
128
|
+
uint8_t row;
|
|
129
|
+
uint16_t base;
|
|
130
|
+
for (row = ROAD_TOP_ROW; row <= ROAD_BOT_ROW; row++) {
|
|
131
|
+
base = (uint16_t)(0x2000 + (uint16_t)row * 32);
|
|
132
|
+
vram_unsafe_set((uint16_t)(base + ROAD_EDGE_L), BG_T_EDGE);
|
|
133
|
+
vram_unsafe_set((uint16_t)(base + ROAD_EDGE_R), BG_T_EDGE);
|
|
134
|
+
vram_unsafe_set((uint16_t)(base + ROAD_DIV_1), BG_T_LANE);
|
|
135
|
+
vram_unsafe_set((uint16_t)(base + ROAD_DIV_2), BG_T_LANE);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
96
139
|
static void reset_run(void) {
|
|
97
140
|
uint8_t i;
|
|
98
141
|
player_lane = 1;
|
|
@@ -138,7 +181,13 @@ void main(void) {
|
|
|
138
181
|
chr_ram_upload(T_CAR_ENEMY * 16, tile_car_enemy, 16);
|
|
139
182
|
chr_ram_upload(T_DIGIT0 * 16, tile_digits, sizeof(tile_digits));
|
|
140
183
|
|
|
184
|
+
/* BG road tiles live in pattern table 1 ($1000) — that's where the
|
|
185
|
+
* default PPUCTRL ($90) tells the PPU to read background patterns. */
|
|
186
|
+
chr_ram_upload((uint16_t)(0x1000 + BG_T_EDGE * 16), bg_tile_edge, 16);
|
|
187
|
+
chr_ram_upload((uint16_t)(0x1000 + BG_T_LANE * 16), bg_tile_lane, 16);
|
|
188
|
+
|
|
141
189
|
palette_load(palette);
|
|
190
|
+
draw_road(); /* paint the static road while the PPU is off */
|
|
142
191
|
oam_clear();
|
|
143
192
|
ppu_on_all();
|
|
144
193
|
sound_init();
|
|
@@ -198,6 +247,6 @@ void main(void) {
|
|
|
198
247
|
}
|
|
199
248
|
}
|
|
200
249
|
|
|
201
|
-
if (score <
|
|
250
|
+
if (score < 65500u) score++;
|
|
202
251
|
}
|
|
203
252
|
}
|
package/examples/pce/main.c
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Boots to a guaranteed-VISIBLE screen using cc65's conio (text) library, which
|
|
5
5
|
* initializes the HuC6270 VDC + HuC6260 VCE for you and uploads a font to VRAM.
|
|
6
|
-
* Build with:
|
|
6
|
+
* Build with: build({ output: "rom", platform: "pce" }) (language defaults to C).
|
|
7
7
|
*
|
|
8
8
|
* FOOTGUN — the empty-BSS crt0 trap (cc65 pce/crt0.s line 84):
|
|
9
9
|
* The PCE crt0 clears .bss with `tii __BSS_RUN__, __BSS_RUN__+1, __BSS_SIZE__-1`.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - 64 sprite slots × 4 bytes (Y / X / tile / unused)
|
|
12
12
|
*
|
|
13
13
|
* Multi-file project — main.c plus the runtime .c files. Build with:
|
|
14
|
-
*
|
|
14
|
+
* build({ output: "rom", platform:"sms", language:"c",
|
|
15
15
|
* sources: { "main.c": ..., "vdp_init.c": ..., ... },
|
|
16
16
|
* includes: { "sms_hw.h": ... }})
|
|
17
17
|
*
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* them by name-table index).
|
|
13
13
|
*
|
|
14
14
|
* Build via createProject({platform:"sms", template:"music_demo"}) or
|
|
15
|
-
*
|
|
15
|
+
* build({ output: "rom", platform:"sms", language:"c", sources:{ "main.c": ...,
|
|
16
16
|
* "sms_music.c": ... , ...runtime... }}).
|
|
17
17
|
*/
|
|
18
18
|
|
|
@@ -126,7 +126,7 @@ static void lock_piece(void) {
|
|
|
126
126
|
a = grid[r][c]; b = grid[r][c + 1]; d = grid[r][c + 2];
|
|
127
127
|
if (a != 0 && a == b && b == d) {
|
|
128
128
|
grid[r][c] = 0; grid[r][c + 1] = 0; grid[r][c + 2] = 0;
|
|
129
|
-
if (score <
|
|
129
|
+
if (score < 65500u) score = (uint16_t)(score + 30);
|
|
130
130
|
sfx_tone(0, 200, 10); /* triple-clear chime */
|
|
131
131
|
}
|
|
132
132
|
}
|
|
@@ -157,7 +157,7 @@ void main(void) {
|
|
|
157
157
|
if (aabb(&bullets[i], &enemies[j])) {
|
|
158
158
|
bullets[i].alive = 0;
|
|
159
159
|
enemies[j].alive = 0;
|
|
160
|
-
if (score <
|
|
160
|
+
if (score < 65500u) score = (uint16_t)(score + 10);
|
|
161
161
|
sfx_noise(8);
|
|
162
162
|
break;
|
|
163
163
|
}
|
|
@@ -199,7 +199,7 @@ void main(void) {
|
|
|
199
199
|
if (p1_bullets[i].alive && aabb(&p1_bullets[i], &enemies[j])) {
|
|
200
200
|
p1_bullets[i].alive = 0;
|
|
201
201
|
enemies[j].alive = 0;
|
|
202
|
-
if (score_p1 <
|
|
202
|
+
if (score_p1 < 65500u) score_p1 = (uint16_t)(score_p1 + 10);
|
|
203
203
|
sfx_noise(8);
|
|
204
204
|
break;
|
|
205
205
|
}
|
|
@@ -209,7 +209,7 @@ void main(void) {
|
|
|
209
209
|
if (p2_bullets[i].alive && aabb(&p2_bullets[i], &enemies[j])) {
|
|
210
210
|
p2_bullets[i].alive = 0;
|
|
211
211
|
enemies[j].alive = 0;
|
|
212
|
-
if (score_p2 <
|
|
212
|
+
if (score_p2 < 65500u) score_p2 = (uint16_t)(score_p2 + 10);
|
|
213
213
|
sfx_noise(8);
|
|
214
214
|
break;
|
|
215
215
|
}
|
package/examples/snes/main.asm
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
; - nmi_safe.asm: vblank handler skeleton
|
|
21
21
|
;
|
|
22
22
|
; BUILD: complete LoROM image, no extra options needed.
|
|
23
|
-
;
|
|
23
|
+
; build({ output: "rom", platform: "snes", source: /* this file */ });
|
|
24
24
|
|
|
25
25
|
lorom
|
|
26
26
|
|