mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-22 14:33:51 +00:00
updated coleco include/lib; nes siege game
This commit is contained in:
parent
ec9a3136ac
commit
97a9525552
277
presets/nes/siegegame.c
Normal file
277
presets/nes/siegegame.c
Normal file
@ -0,0 +1,277 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <nes.h>
|
||||
#include <joystick.h>
|
||||
|
||||
#define COLS 32
|
||||
#define ROWS 28
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef signed char sbyte;
|
||||
typedef unsigned short word;
|
||||
|
||||
// read a character from VRAM.
|
||||
// this is tricky because we have to wait
|
||||
// for VSYNC to start, then set the VRAM
|
||||
// address to read, then set the VRAM address
|
||||
// back to the start of the frame.
|
||||
byte getchar(byte x, byte y) {
|
||||
// compute VRAM read address
|
||||
word addr = 0x2020+x+y*32;
|
||||
byte rd;
|
||||
// wait for VBLANK to start
|
||||
waitvblank();
|
||||
// set VRAM read address in PPU
|
||||
PPU.vram.address = addr>>8;
|
||||
PPU.vram.address = addr&0xff;
|
||||
// read the char from PPUDATA
|
||||
rd = PPU.vram.data; // discard
|
||||
rd = PPU.vram.data; // keep this one
|
||||
// reset the VRAM address to start of frame
|
||||
PPU.vram.address = 0x00;
|
||||
PPU.vram.address = 0x00;
|
||||
// return result
|
||||
return rd;
|
||||
}
|
||||
|
||||
void delay(byte count) {
|
||||
while (count--) waitvblank();
|
||||
}
|
||||
|
||||
////////// GAME DATA
|
||||
|
||||
typedef struct {
|
||||
byte x;
|
||||
byte y;
|
||||
byte dir;
|
||||
word score;
|
||||
char head_attr;
|
||||
char tail_attr;
|
||||
int collided:1;
|
||||
int human:1;
|
||||
} Player;
|
||||
|
||||
Player players[2];
|
||||
|
||||
byte credits = 0;
|
||||
byte frames_per_move;
|
||||
|
||||
#define START_SPEED 12
|
||||
#define MAX_SPEED 5
|
||||
#define MAX_SCORE 7
|
||||
|
||||
///////////
|
||||
|
||||
const char BOX_CHARS[8] = { 17, 8, 20, 18, 11, 11, 14, 14 };
|
||||
|
||||
void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) {
|
||||
byte x1 = x;
|
||||
cputcxy(x, y, chars[2]);
|
||||
cputcxy(x2, y, chars[3]);
|
||||
cputcxy(x, y2, chars[0]);
|
||||
cputcxy(x2, y2, chars[1]);
|
||||
while (++x < x2) {
|
||||
cputcxy(x, y, chars[5]);
|
||||
cputcxy(x, y2, chars[4]);
|
||||
}
|
||||
while (++y < y2) {
|
||||
cputcxy(x1, y, chars[6]);
|
||||
cputcxy(x2, y, chars[7]);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_playfield() {
|
||||
draw_box(0,1,COLS-1,ROWS-1,BOX_CHARS);
|
||||
cputsxy(0,0,"Plyr1:");
|
||||
cputsxy(20,0,"Plyr2:");
|
||||
cputcxy(7,0,players[0].score+'0');
|
||||
cputcxy(27,0,players[1].score+'0');
|
||||
}
|
||||
|
||||
typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } dir_t;
|
||||
const char DIR_X[4] = { 1, 0, -1, 0 };
|
||||
const char DIR_Y[4] = { 0, 1, 0, -1 };
|
||||
|
||||
void init_game() {
|
||||
memset(players, 0, sizeof(players));
|
||||
players[0].head_attr = '1';
|
||||
players[1].head_attr = '2';
|
||||
players[0].tail_attr = 1;
|
||||
players[1].tail_attr = 9;
|
||||
frames_per_move = START_SPEED;
|
||||
}
|
||||
|
||||
void reset_players() {
|
||||
players[0].x = players[0].y = 5;
|
||||
players[0].dir = D_RIGHT;
|
||||
players[1].x = COLS-6;
|
||||
players[1].y = ROWS-6;
|
||||
players[1].dir = D_LEFT;
|
||||
players[0].collided = players[1].collided = 0;
|
||||
}
|
||||
|
||||
void draw_player(Player* p) {
|
||||
cputcxy(p->x, p->y, p->head_attr);
|
||||
}
|
||||
|
||||
void move_player(Player* p) {
|
||||
cputcxy(p->x, p->y, p->tail_attr);
|
||||
p->x += DIR_X[p->dir];
|
||||
p->y += DIR_Y[p->dir];
|
||||
if (getchar(p->x, p->y) != ' ')
|
||||
p->collided = 1;
|
||||
draw_player(p);
|
||||
}
|
||||
|
||||
void human_control(Player* p) {
|
||||
byte dir = 0xff;
|
||||
byte joy;
|
||||
if (!p->human) return;
|
||||
joy = joy_read (JOY_1);
|
||||
if (joy & KEY_LEFT) dir = D_LEFT;
|
||||
if (joy & KEY_RIGHT) dir = D_RIGHT;
|
||||
if (joy & KEY_UP) dir = D_UP;
|
||||
if (joy & KEY_DOWN) dir = D_DOWN;
|
||||
// don't let the player reverse
|
||||
if (dir < 0x80 && dir != (p->dir ^ 2)) {
|
||||
p->dir = dir;
|
||||
}
|
||||
}
|
||||
|
||||
byte ai_try_dir(Player* p, dir_t dir, byte shift) {
|
||||
byte x,y;
|
||||
dir &= 3;
|
||||
x = p->x + (DIR_X[dir] << shift);
|
||||
y = p->y + (DIR_Y[dir] << shift);
|
||||
if (x < COLS && y < ROWS && getchar(x, y) == ' ') {
|
||||
p->dir = dir;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ai_control(Player* p) {
|
||||
dir_t dir;
|
||||
if (p->human) return;
|
||||
dir = p->dir;
|
||||
if (!ai_try_dir(p, dir, 0)) {
|
||||
ai_try_dir(p, dir+1, 0);
|
||||
ai_try_dir(p, dir-1, 0);
|
||||
} else {
|
||||
ai_try_dir(p, dir-1, 0) && ai_try_dir(p, dir-1, 1+(rand() & 3));
|
||||
ai_try_dir(p, dir+1, 0) && ai_try_dir(p, dir+1, 1+(rand() & 3));
|
||||
ai_try_dir(p, dir, rand() & 3);
|
||||
}
|
||||
}
|
||||
|
||||
byte gameover;
|
||||
|
||||
void flash_colliders() {
|
||||
byte i;
|
||||
// flash players that collided
|
||||
for (i=0; i<56; i++) {
|
||||
//cv_set_frequency(CV_SOUNDCHANNEL_0, 1000+i*8);
|
||||
//cv_set_attenuation(CV_SOUNDCHANNEL_0, i/2);
|
||||
if (players[0].collided) players[0].head_attr ^= 0x80;
|
||||
if (players[1].collided) players[1].head_attr ^= 0x80;
|
||||
delay(2);
|
||||
draw_player(&players[0]);
|
||||
draw_player(&players[1]);
|
||||
}
|
||||
//cv_set_attenuation(CV_SOUNDCHANNEL_0, 28);
|
||||
}
|
||||
|
||||
void make_move() {
|
||||
byte i;
|
||||
for (i=0; i<frames_per_move; i++) {
|
||||
human_control(&players[0]);
|
||||
delay(1);
|
||||
}
|
||||
ai_control(&players[0]);
|
||||
ai_control(&players[1]);
|
||||
// if players collide, 2nd player gets the point
|
||||
move_player(&players[1]);
|
||||
move_player(&players[0]);
|
||||
}
|
||||
|
||||
void declare_winner(byte winner) {
|
||||
byte i;
|
||||
clrscr();
|
||||
for (i=0; i<ROWS/2-3; i++) {
|
||||
draw_box(i,i,COLS-1-i,ROWS-1-i,BOX_CHARS);
|
||||
delay(1);
|
||||
}
|
||||
cputsxy(12,10,"WINNER:");
|
||||
cputsxy(12,13,"PLAYER ");
|
||||
cputcxy(12+7, 13, '1'+winner);
|
||||
delay(75);
|
||||
gameover = 1;
|
||||
}
|
||||
|
||||
#define AE(a,b,c,d) (((a)<<0)|((b)<<2)|((c)<<4)|((d)<<6))
|
||||
|
||||
// this is attribute table data,
|
||||
// each 2 bits defines a color palette
|
||||
// for a 16x16 box
|
||||
const unsigned char Attrib_Table[0x40]={
|
||||
AE(3,3,1,1),AE(3,3,1,1),AE(3,3,1,1),AE(3,3,1,1), AE(2,2,1,1),AE(2,2,1,1),AE(2,2,1,1),AE(2,2,1,1),
|
||||
AE(1,0,1,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0), AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,1,0,1),
|
||||
AE(1,0,1,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0), AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,1,0,1),
|
||||
AE(1,0,1,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0), AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,1,0,1),
|
||||
AE(1,0,1,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0), AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,1,0,1),
|
||||
AE(1,0,1,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0), AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,1,0,1),
|
||||
AE(1,0,1,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0), AE(0,0,0,0),AE(0,0,0,0),AE(0,0,0,0),AE(0,1,0,1),
|
||||
AE(1,1,1,1),AE(1,1,1,1),AE(1,1,1,1),AE(1,1,1,1), AE(1,1,1,1),AE(1,1,1,1),AE(1,1,1,1),AE(1,1,1,1),
|
||||
};
|
||||
|
||||
// put 8x8 grid of palette entries into the PPU
|
||||
void setup_attrib_table() {
|
||||
byte index;
|
||||
waitvblank(); // wait for VBLANK
|
||||
PPU.vram.address = 0x23;
|
||||
PPU.vram.address = 0xc0;
|
||||
for( index = 0; index < 0x40; ++index ){
|
||||
PPU.vram.data = Attrib_Table[index];
|
||||
}
|
||||
}
|
||||
|
||||
void play_round() {
|
||||
reset_players();
|
||||
clrscr();
|
||||
setup_attrib_table();
|
||||
draw_playfield();
|
||||
while (1) {
|
||||
make_move();
|
||||
if (players[0].collided || players[1].collided) break;
|
||||
}
|
||||
flash_colliders();
|
||||
// add scores to players that didn't collide
|
||||
if (players[0].collided) players[1].score++;
|
||||
if (players[1].collided) players[0].score++;
|
||||
// increase speed
|
||||
if (frames_per_move > MAX_SPEED) frames_per_move--;
|
||||
// game over?
|
||||
if (players[0].score != players[1].score) {
|
||||
if (players[0].score >= MAX_SCORE)
|
||||
declare_winner(0);
|
||||
else if (players[1].score >= MAX_SCORE)
|
||||
declare_winner(1);
|
||||
}
|
||||
}
|
||||
|
||||
void play_game() {
|
||||
gameover = 0;
|
||||
init_game();
|
||||
players[0].human = 1;
|
||||
while (!gameover) {
|
||||
play_round();
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
joy_install (joy_static_stddrv);
|
||||
play_game();
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
var NES_PRESETS = [
|
||||
{id:'hello.c', name:'Hello PPU'},
|
||||
{id:'conio.c', name:'Hello Console I/O'},
|
||||
{id:'siegegame.c', name:'Siege Game'},
|
||||
];
|
||||
|
||||
/// JSNES
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -126,10 +126,8 @@ Module['FS_createPath']('/include', 'pic14', true, true);
|
||||
Module['FS_createPath']('/include', 'ds400', true, true);
|
||||
Module['FS_createPath']('/', 'lib', true, true);
|
||||
Module['FS_createPath']('/lib', 'z80', true, true);
|
||||
Module['FS_createPath']('/lib', 'libcv', true, true);
|
||||
Module['FS_createPath']('/lib', 'libcvu', true, true);
|
||||
Module['FS_createPath']('/include', 'libcv', true, true);
|
||||
Module['FS_createPath']('/include', 'libcvu', true, true);
|
||||
Module['FS_createPath']('/lib', 'coleco', true, true);
|
||||
Module['FS_createPath']('/include', 'coleco', true, true);
|
||||
|
||||
function DataRequest(start, end, crunched, audio) {
|
||||
this.start = start;
|
||||
|
File diff suppressed because one or more lines are too long
@ -64,8 +64,11 @@ var PLATFORM_PARAMS = {
|
||||
data_start: 0x7000,
|
||||
data_size: 0x400,
|
||||
stack_end: 0x8000,
|
||||
extra_preproc_args: ['-I', '/share/include/libcv', '-I', '/share/include/libcvu'],
|
||||
extra_link_args: ['-k', '/share/lib/libcv', '-l', 'libcv', '-k', '/share/lib/libcvu', '-l', 'libcvu', '/share/lib/libcv/crt0.rel', 'main.rel'],
|
||||
extra_preproc_args: ['-I', '/share/include/coleco'],
|
||||
extra_link_args: ['-k', '/share/lib/coleco',
|
||||
'-l', 'libcv', '-l', 'libcvu',
|
||||
'/share/lib/coleco/crt0.rel',
|
||||
'main.rel'],
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user