#include <string.h>
extern char tiles1;
extern char tiles2;
extern char bg1map;
extern char bg2map;
extern char palette;
extern char backpal;
typedef struct
{
s16 x, y;
} Vec2;
const Vec2 dir[4] = {
{-2, -1}, {-1, -2}, {1, -2}, {2, -1}};
const u8 map[0x64] = {
7,
8,
8,
8,
8,
8,
8,
8,
8,
7,
8,
7,
8,
7,
8,
8,
7,
8,
7,
8,
8,
8,
7,
8,
7,
7,
8,
7,
8,
8,
8,
8,
8,
1,
3,
3,
1,
8,
8,
8,
8,
0,
4,
8,
8,
8,
8,
4,
0,
8,
8,
0,
8,
8,
5,
5,
8,
8,
0,
8,
8,
0,
4,
8,
8,
8,
8,
4,
0,
8,
8,
8,
8,
1,
3,
3,
1,
8,
8,
8,
8,
8,
6,
8,
6,
6,
8,
6,
8,
8,
7,
7,
7,
7,
8,
8,
7,
7,
7,
7,
};
#define ST_READY "PLAYER 1\n\n READY"
#define ST_GAMEOVER "GAME OVER"
#define ST_PAUSED "PAUSE"
#define ST_BLANK " "
u16 blockmap[0x400];
u16 backmap[0x400];
u16 pal[0x100];
u8 blocks[0x64];
u8 i, j, k;
u16 a, c, b;
u16 blockcount;
u16 bx, by;
u16 obx, oby;
u16 score, hiscore;
u16 level2;
u16 color, level, lives;
u16 px;
Vec2 vel;
Vec2 pos;
u16 pad0;
u16 clamp(u16 val, u16 min, u16 max)
{
if (val < min)
val = min;
if (val > max)
val = max;
return val;
}
void writestring(const char *st, u16 *map, u16 p, u16 offset)
{
u16 sp = p;
u8 c;
while ((c = *st))
{
if (c == '\n')
{
sp += 0x20;
p = sp;
}
else
{
map[p] = c + offset;
p++;
}
st++;
}
}
void writenum(u16 num, u8 len, u16 *map, u16 p, u16 offset)
{
u8 figure;
p += len - 1;
if (!num)
{
map[p] = offset;
}
else
{
while (len && num)
{
figure = num % 10;
if (num || figure)
map[p] = figure + offset;
num /= 10;
p--;
len--;
}
}
}
void draw_screen(void)
{
oamSet(0, pos.x, pos.y, 3, 0, 0, 20 | (1 << 8), 0);
oamSet(1 * 4, px + 0, 200, 3, 0, 0, 15 | (1 << 8), 0);
oamSet(2 * 4, px + 8, 200, 3, 0, 0, 16 | (1 << 8), 0);
oamSet(3 * 4, px + 16, 200, 3, 1, 0, 16 | (1 << 8), 0);
oamSet(4 * 4, px + 24, 200, 3, 0, 0, 17 | (1 << 8), 0);
oamSet(5 * 4, pos.x + 3, pos.y + 3, 1, 0, 0, 21 | (1 << 8), 0);
oamSet(6 * 4, px + 4, 204, 1, 0, 0, 18 | (1 << 8), 0);
oamSet(7 * 4, px + 12, 204, 1, 0, 0, 19 | (1 << 8), 0);
oamSet(8 * 4, px + 20, 204, 1, 1, 0, 19 | (1 << 8), 0);
oamSet(9 * 4, px + 28, 204, 1, 0, 0, 18 | (1 << 8), 0);
}
void new_level(void)
{
level++;
level2++;
pos.x = 94;
pos.y = 109;
px = 80;
writenum(level2, 8, blockmap, 0x2D6, 0x426);
writestring(ST_READY, blockmap, 0x248, 0x3F6);
memcpy((u8 *)&backmap, &bg2map + 0x800 * (level & 3), 0x800);
memcpy((u8 *)&blocks, &map, 0x64);
if (color < 6)
{
color++;
}
else
color = 0;
memcpy((u8 *)&pal + 16, &backpal + color * 16, 0x10);
b = 0;
for (j = 0; j < 10; j++)
{
for (i = 0; i < 20; i++, i++)
{
a = blocks[b];
if (a < 8)
{
c = (j << 5) + i;
blockcount++;
blockmap[0x62 + c] = 13 + (a << 10);
blockmap[0x63 + c] = 14 + (a << 10);
backmap[0x83 + c] += 0x400;
backmap[0x84 + c] += 0x400;
}
b++;
}
}
draw_screen();
writestring(ST_BLANK, blockmap, 0x248, 0x3F6);
writestring(ST_BLANK, blockmap, 0x289, 0x3F6);
}
void die(void)
{
if (lives == 0)
{
writestring(ST_GAMEOVER, blockmap, 0x267, 0x3F6);
while (1)
;
}
lives--;
pos.x = 94;
pos.y = 109;
px = 80;
writenum(lives, 8, blockmap, 0x136, 0x426);
writestring(ST_READY, blockmap, 0x248, 0x3F6);
draw_screen();
writestring(ST_BLANK, blockmap, 0x248, 0x3F6);
writestring(ST_BLANK, blockmap, 0x289, 0x3F6);
}
void handle_pause(void)
{
{
writestring(ST_PAUSED, blockmap, 0x269, 0x3F6);
{
}
{
}
writestring(ST_BLANK, blockmap, 0x269, 0x3F6);
}
}
void run_frame(void)
{
handle_pause();
{
px += 4;
px -= 4;
}
else
{
px += 2;
px -= 2;
}
px = clamp(px, 16, 144);
pos.x += vel.x;
pos.y += vel.y;
if (pos.x > 171)
{
vel.x = -vel.x;
pos.x = 171;
}
else if (pos.x < 16)
{
vel.x = -vel.x;
pos.x = 16;
}
if (pos.y < 15)
{
vel.y = -vel.y;
}
else if (pos.y > 195)
{
if (pos.y < 203)
{
if ((pos.x >= px) && (pos.x <= px + 27))
{
k = (pos.x - px) / 7;
vel.x = dir[k].x;
vel.y = dir[k].y;
}
}
else if (pos.y > 224)
{
die();
}
}
else if (pos.y < 112)
{
obx = bx;
oby = by;
bx = (pos.x - 14) >> 4;
by = (pos.y - 14) >> 3;
b = bx + (by << 3) + (by << 1) - 10;
if ((b >= 0) && (b < 100))
{
if (blocks[b] != 8)
{
blockcount--;
for (i = 0; i <= level; i++)
score += blocks[b] + 1;
if (oby != by)
vel.y = -vel.y;
if (obx != bx)
vel.x = -vel.x;
blocks[b] = 8;
b = (by << 5) + (bx << 1);
blockmap[0x42 + b] = 0;
blockmap[0x43 + b] = 0;
backmap[0x63 + b] -= 0x400;
backmap[0x64 + b] -= 0x400;
writenum(score, 8, blockmap, 0xF5, 0x426);
if (score > hiscore)
{
hiscore = score;
writenum(score, 8, blockmap, 0x95, 0x426);
}
if (blockcount == 0)
{
new_level();
}
}
}
}
draw_screen();
}
int main(void)
{
memcpy((u8 *)&blockmap, &bg1map, 0x800);
memcpy((u8 *)&backmap, &bg2map, 0x800);
memcpy((u8 *)&blocks, &map, 0x64);
memcpy((u8 *)&pal, &palette, 0x200);
blockcount = 0;
bx = 5;
by = 11;
score = 0;
hiscore = 50000;
level2 = 1;
color = 0;
level = 0;
lives = 4;
px = 80;
vel.x = 2;
vel.y = 1;
pos.x = 94;
pos.y = 109;
b = 0;
for (j = 0; j < 10; j++)
{
for (i = 0; i < 20; i += 2)
{
a = blocks[b++];
if (a < 8)
{
c = (j << 5) + i;
blockcount++;
blockmap[0x62 + c] = 13 + (a << 10);
blockmap[0x63 + c] = 14 + (a << 10);
backmap[0x83 + c] += 0x400;
backmap[0x84 + c] += 0x400;
}
}
}
writenum(lives, 8, blockmap, 0x136, 0x426);
writestring(ST_READY, blockmap, 0x248, 0x3F6);
draw_screen();
for (i = 0; i < 10 * 4; i += 4)
writestring(ST_BLANK, blockmap, 0x248, 0x3F6);
writestring(ST_BLANK, blockmap, 0x289, 0x3F6);
while (1)
{
run_frame();
}
return 0;
}
void bgSetGfxPtr(u8 bgNumber, u16 address)
Definition of each background address.
void bgSetDisable(u8 bgNumber)
Disable a BG in the actual SNES mode.
void bgInitMapSet(u8 bgNumber, u8 *mapSource, u16 mapSize, u8 sizeMode, u16 address)
Initializes a Map Set and loads it into SNES VRAM.
void consoleInit(void)
Initialize console.
void dmaCopyVram(u8 *source, u16 address, u16 size)
copy data from source to destination using channel 0 of DMA available channels in half words
void dmaCopyCGram(u8 *source, u16 address, u16 size)
copy data from source to destination using channel 0 of DMA available channels in half words
void WaitForVBlank(void)
Wait for vblank interrupt
the master include file for snes applications.
void oamSetEx(u16 id, u8 size, u8 hide)
Put the correct size and hide or show a sprite.
void oamSet(u16 id, u16 xspr, u16 yspr, u8 priority, u8 hflip, u8 vflip, u16 gfxoffset, u8 paletteoffset)
sets an oam entry to the supplied values
void setBrightness(u8 level)
sets the screens brightness.
void setScreenOn(void)
Put screen On.
void setMode(u8 mode, u8 size)
Set the SNES hardware to operate in new display mode.