mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-23 06:32:11 +00:00
updated climber.c; nes debug view
This commit is contained in:
parent
6853c0ba62
commit
86dac3ba8a
@ -3,11 +3,12 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
#include "nes.h"
|
||||||
|
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
typedef signed char sbyte;
|
typedef signed char sbyte;
|
||||||
typedef unsigned short word;
|
typedef unsigned short word;
|
||||||
typedef enum { false, true} bool;
|
typedef enum { false, true } bool;
|
||||||
|
|
||||||
// TILES
|
// TILES
|
||||||
|
|
||||||
@ -23,20 +24,23 @@ extern unsigned char jroatch_chr[0x1000];
|
|||||||
#define ACTOR_MIN_X 16
|
#define ACTOR_MIN_X 16
|
||||||
#define ACTOR_SCROLL_UP_Y 110
|
#define ACTOR_SCROLL_UP_Y 110
|
||||||
#define ACTOR_SCROLL_DOWN_Y 140
|
#define ACTOR_SCROLL_DOWN_Y 140
|
||||||
#define BOTTOM_LEVEL_Y 1
|
#define BOTTOM_LEVEL_Y 2
|
||||||
|
#define JUMP_VELOCITY 17
|
||||||
|
|
||||||
#define BGCOL CV_COLOR_BLUE
|
#define BGCOL CV_COLOR_BLUE
|
||||||
|
|
||||||
#define CH_BORDER 64
|
#define CH_BORDER 64
|
||||||
#define CH_FLOOR 127
|
#define CH_FLOOR 0xf4
|
||||||
#define CH_LADDER 212
|
#define CH_LADDER 0xd4
|
||||||
#define CH_FRUIT 204
|
#define CH_FRUIT 0xcc
|
||||||
#define BLANK 32
|
#define BLANK 0x20
|
||||||
|
|
||||||
byte rndint(byte a, byte b) {
|
byte rndint(byte a, byte b) {
|
||||||
return (rand8() % (b-a)) + a;
|
return (rand8() % (b-a)) + a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define OAMBUF ((unsigned char*) 0x200)
|
||||||
|
|
||||||
// VRAM UPDATE BUFFER
|
// VRAM UPDATE BUFFER
|
||||||
|
|
||||||
#define VBUFSIZE 64
|
#define VBUFSIZE 64
|
||||||
@ -72,8 +76,22 @@ word getntaddr(byte x, byte y) {
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void putchar(byte x, byte y, char ch) {
|
word nt2attraddr(word a) {
|
||||||
word addr = getntaddr(x,y);
|
return (a & 0x2c00) | 0x3c0 | (a & 0x0C00) |
|
||||||
|
((a >> 4) & 0x38) | ((a >> 2) & 0x07);
|
||||||
|
}
|
||||||
|
|
||||||
|
word getattraddr(byte row) {
|
||||||
|
word addr;
|
||||||
|
if (row < 15) {
|
||||||
|
addr = NAMETABLE_A + 0x3c0 + (row>>1)*8;
|
||||||
|
} else {
|
||||||
|
addr = NAMETABLE_C + 0x3c0 + ((row-15)>>1)*8;
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void putchar(word addr, char ch) {
|
||||||
if (updptr >= VBUFSIZE-4) cflushnow();
|
if (updptr >= VBUFSIZE-4) cflushnow();
|
||||||
updbuf[updptr++] = addr >> 8;
|
updbuf[updptr++] = addr >> 8;
|
||||||
updbuf[updptr++] = addr & 0xff;
|
updbuf[updptr++] = addr & 0xff;
|
||||||
@ -81,8 +99,7 @@ void putchar(byte x, byte y, char ch) {
|
|||||||
cendbuf();
|
cendbuf();
|
||||||
}
|
}
|
||||||
|
|
||||||
void putbytes(byte x, byte y, char* str, byte len) {
|
void putbytes(word addr, char* str, byte len) {
|
||||||
word addr = getntaddr(x,y);
|
|
||||||
if (updptr >= VBUFSIZE-4-len) cflushnow();
|
if (updptr >= VBUFSIZE-4-len) cflushnow();
|
||||||
updbuf[updptr++] = (addr >> 8) | NT_UPD_HORZ;
|
updbuf[updptr++] = (addr >> 8) | NT_UPD_HORZ;
|
||||||
updbuf[updptr++] = addr & 0xff;
|
updbuf[updptr++] = addr & 0xff;
|
||||||
@ -94,7 +111,7 @@ void putbytes(byte x, byte y, char* str, byte len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void putstring(byte x, byte y, char* str) {
|
void putstring(byte x, byte y, char* str) {
|
||||||
putbytes(x, y, str, strlen(str));
|
putbytes(getntaddr(x,y), str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
void clrscr() {
|
void clrscr() {
|
||||||
@ -109,66 +126,45 @@ void clrscr() {
|
|||||||
|
|
||||||
/// METASPRITES
|
/// METASPRITES
|
||||||
|
|
||||||
const unsigned char playerStand[]={
|
#define DEF_METASPRITE_4x4(name,code,pal)\
|
||||||
0, 0, 0xd8, 0,
|
const unsigned char name[]={\
|
||||||
8, 0, 0xd9, 0,
|
0, 0, (code)+0, pal, \
|
||||||
0, 8, 0xda, 0,
|
8, 0, (code)+1, pal, \
|
||||||
8, 8, 0xdb, 0,
|
0, 8, (code)+2, pal, \
|
||||||
128
|
8, 8, (code)+3, pal, \
|
||||||
};
|
128};
|
||||||
|
|
||||||
const unsigned char playerRun1[]={
|
#define DEF_METASPRITE_4x4_FLIP(name,code,pal)\
|
||||||
0, 0, 0xdc, 0,
|
const unsigned char name[]={\
|
||||||
8, 0, 0xdd, 0,
|
8, 0, (code)+0, (pal)|OAM_FLIP_H, \
|
||||||
0, 8, 0xde, 0,
|
0, 0, (code)+1, (pal)|OAM_FLIP_H, \
|
||||||
8, 8, 0xdf, 0,
|
8, 8, (code)+2, (pal)|OAM_FLIP_H, \
|
||||||
128
|
0, 8, (code)+3, (pal)|OAM_FLIP_H, \
|
||||||
};
|
128};
|
||||||
|
|
||||||
const unsigned char playerRun2[]={
|
DEF_METASPRITE_4x4(playerRStand, 0xd8, 0);
|
||||||
0, 0, 0xe0, 0,
|
DEF_METASPRITE_4x4(playerRRun1, 0xdc, 0);
|
||||||
8, 0, 0xe1, 0,
|
DEF_METASPRITE_4x4(playerRRun2, 0xe0, 0);
|
||||||
0, 8, 0xe2, 0,
|
DEF_METASPRITE_4x4(playerRRun3, 0xe4, 0);
|
||||||
8, 8, 0xe3, 0,
|
DEF_METASPRITE_4x4(playerRJump, 0xe8, 0);
|
||||||
128
|
DEF_METASPRITE_4x4(playerRClimb, 0xec, 0);
|
||||||
};
|
DEF_METASPRITE_4x4(playerRSad, 0xf0, 0);
|
||||||
|
|
||||||
const unsigned char playerRun3[]={
|
DEF_METASPRITE_4x4_FLIP(playerLStand, 0xd8, 0);
|
||||||
0, 0, 0xe4, 0,
|
DEF_METASPRITE_4x4_FLIP(playerLRun1, 0xdc, 0);
|
||||||
8, 0, 0xe5, 0,
|
DEF_METASPRITE_4x4_FLIP(playerLRun2, 0xe0, 0);
|
||||||
0, 8, 0xe6, 0,
|
DEF_METASPRITE_4x4_FLIP(playerLRun3, 0xe4, 0);
|
||||||
8, 8, 0xe7, 0,
|
DEF_METASPRITE_4x4_FLIP(playerLJump, 0xe8, 0);
|
||||||
128
|
DEF_METASPRITE_4x4_FLIP(playerLClimb, 0xec, 0);
|
||||||
};
|
DEF_METASPRITE_4x4_FLIP(playerLSad, 0xf0, 0);
|
||||||
|
|
||||||
const unsigned char playerJump[]={
|
const unsigned char* const playerRunSeq[16] = {
|
||||||
0, 0, 0xe8, 0,
|
playerLRun1, playerLRun2, playerLRun3,
|
||||||
8, 0, 0xe9, 0,
|
playerLRun1, playerLRun2, playerLRun3,
|
||||||
0, 8, 0xea, 0,
|
playerLRun1, playerLRun2,
|
||||||
8, 8, 0xeb, 0,
|
playerRRun1, playerRRun2, playerRRun3,
|
||||||
128
|
playerRRun1, playerRRun2, playerRRun3,
|
||||||
};
|
playerRRun1, playerRRun2,
|
||||||
|
|
||||||
const unsigned char playerClimb[]={
|
|
||||||
0, 0, 0xec, 0,
|
|
||||||
8, 0, 0xed, 0,
|
|
||||||
0, 8, 0xee, 0,
|
|
||||||
8, 8, 0xef, 0,
|
|
||||||
128
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned char playerSad[]={
|
|
||||||
0, 0, 0xf0, 0,
|
|
||||||
8, 0, 0xf1, 0,
|
|
||||||
0, 8, 0xf2, 0,
|
|
||||||
8, 8, 0xf3, 0,
|
|
||||||
128
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned char* playerRunSeq[8] = {
|
|
||||||
playerRun1, playerRun2, playerRun3,
|
|
||||||
playerRun1, playerRun2, playerRun3,
|
|
||||||
playerRun1, playerRun2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// GAME LOGIC
|
/// GAME LOGIC
|
||||||
@ -184,7 +180,7 @@ typedef struct Level {
|
|||||||
} Level;
|
} Level;
|
||||||
|
|
||||||
#define MAX_LEVELS 32
|
#define MAX_LEVELS 32
|
||||||
#define GAPSIZE 3
|
#define GAPSIZE 4
|
||||||
|
|
||||||
Level levels[MAX_LEVELS];
|
Level levels[MAX_LEVELS];
|
||||||
|
|
||||||
@ -207,15 +203,20 @@ void make_levels() {
|
|||||||
Level* prevlev = &levels[0];
|
Level* prevlev = &levels[0];
|
||||||
for (i=0; i<MAX_LEVELS; i++) {
|
for (i=0; i<MAX_LEVELS; i++) {
|
||||||
Level* lev = &levels[i];
|
Level* lev = &levels[i];
|
||||||
lev->height = rndint(4,7);
|
lev->height = rndint(2,5)*2;
|
||||||
lev->ladder1 = rndint(1,14);
|
|
||||||
lev->ladder2 = rndint(1,14);
|
|
||||||
do {
|
do {
|
||||||
lev->gap = i>0 ? rndint(0,13) : 0;
|
lev->gap = i>0 ? rndint(0,13) : 0;
|
||||||
} while (ladder_in_gap(prevlev->ladder1, lev->gap) ||
|
} while (ladder_in_gap(prevlev->ladder1, lev->gap) ||
|
||||||
ladder_in_gap(prevlev->ladder2, lev->gap));
|
ladder_in_gap(prevlev->ladder2, lev->gap));
|
||||||
|
do {
|
||||||
|
lev->ladder1 = rndint(1,14);
|
||||||
|
lev->ladder2 = rndint(1,14);
|
||||||
|
} while (ladder_in_gap(lev->ladder1, lev->gap) ||
|
||||||
|
ladder_in_gap(lev->ladder2, lev->gap));
|
||||||
lev->objtype = rndint(1,3);
|
lev->objtype = rndint(1,3);
|
||||||
lev->objpos = rndint(1,14);
|
do {
|
||||||
|
lev->objpos = rndint(1,14);
|
||||||
|
} while (ladder_in_gap(lev->objpos, lev->gap));
|
||||||
lev->ypos = y;
|
lev->ypos = y;
|
||||||
y += lev->height;
|
y += lev->height;
|
||||||
prevlev = lev;
|
prevlev = lev;
|
||||||
@ -238,18 +239,30 @@ static byte player_screen_y = 0;
|
|||||||
|
|
||||||
void create_actors_on_level(byte i);
|
void create_actors_on_level(byte i);
|
||||||
|
|
||||||
|
// TODO: crashes when drawing top floor
|
||||||
void draw_level_line(byte screen_y) {
|
void draw_level_line(byte screen_y) {
|
||||||
char buf[COLS];
|
char buf[COLS];
|
||||||
byte i;
|
char attrs[8];
|
||||||
byte y = screen_y; // + scroll_tile_y
|
byte level, i;
|
||||||
for (i=0; i<MAX_LEVELS; i++) {
|
byte y = screen_y;
|
||||||
Level* lev = &levels[i];
|
byte rowy;
|
||||||
|
word addr;
|
||||||
|
for (level=0; level<MAX_LEVELS; level++) {
|
||||||
|
Level* lev = &levels[level];
|
||||||
byte dy = y - lev->ypos;
|
byte dy = y - lev->ypos;
|
||||||
// is this level visible on-screen?
|
// is this level visible on-screen?
|
||||||
if (dy < lev->height) {
|
if (dy < lev->height) {
|
||||||
if (dy == 0) {
|
if (dy <= 1) {
|
||||||
// draw floor
|
// draw floor
|
||||||
memset(buf, CH_FLOOR, COLS);
|
for (i=0; i<COLS; i+=2) {
|
||||||
|
if (dy) {
|
||||||
|
buf[i] = CH_FLOOR;
|
||||||
|
buf[i+1] = CH_FLOOR+1;
|
||||||
|
} else {
|
||||||
|
buf[i] = CH_FLOOR+2;
|
||||||
|
buf[i+1] = CH_FLOOR+3;
|
||||||
|
}
|
||||||
|
}
|
||||||
// draw the gap
|
// draw the gap
|
||||||
if (lev->gap)
|
if (lev->gap)
|
||||||
memset(buf+lev->gap*2, 0, GAPSIZE);
|
memset(buf+lev->gap*2, 0, GAPSIZE);
|
||||||
@ -257,8 +270,8 @@ void draw_level_line(byte screen_y) {
|
|||||||
// draw empty space
|
// draw empty space
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
// draw walls
|
// draw walls
|
||||||
if (i < MAX_LEVELS-1) {
|
if (level < MAX_LEVELS-1) {
|
||||||
buf[0] = CH_FLOOR;
|
buf[0] = CH_FLOOR+1;
|
||||||
buf[COLS-1] = CH_FLOOR;
|
buf[COLS-1] = CH_FLOOR;
|
||||||
}
|
}
|
||||||
// draw ladders
|
// draw ladders
|
||||||
@ -271,25 +284,41 @@ void draw_level_line(byte screen_y) {
|
|||||||
buf[lev->ladder2*2+1] = CH_LADDER+1;
|
buf[lev->ladder2*2+1] = CH_LADDER+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//buf[0] = i+'a';buf[1] = y;buf[2] = dy+'0';buf[3] = lev->ypos;buf[4] = lev->height+'0';
|
|
||||||
// draw object, if it exists
|
// draw object, if it exists
|
||||||
if (lev->objtype) {
|
if (lev->objtype) {
|
||||||
byte ch = lev->objtype*4 + CH_FRUIT - 4;
|
byte ch = lev->objtype*4 + CH_FRUIT - 4;
|
||||||
if (dy == 1) {
|
if (dy == 2) {
|
||||||
buf[lev->objpos*2] = ch+2;
|
buf[lev->objpos*2] = ch+2;
|
||||||
buf[lev->objpos*2+1] = ch+3;
|
buf[lev->objpos*2+1] = ch+3;
|
||||||
}
|
}
|
||||||
else if (dy == 2) {
|
else if (dy == 3) {
|
||||||
buf[lev->objpos*2] = ch+0;
|
buf[lev->objpos*2] = ch+0;
|
||||||
buf[lev->objpos*2+1] = ch+1;
|
buf[lev->objpos*2+1] = ch+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// compute row in name buffer and address
|
||||||
|
rowy = (ROWS-1) - (screen_y%60);
|
||||||
|
addr = getntaddr(1, rowy);
|
||||||
|
// copy attribute table (every 4th row)
|
||||||
|
if ((addr & 0x60) == 0) {
|
||||||
|
byte a;
|
||||||
|
if (dy==1)
|
||||||
|
a = 0x05;
|
||||||
|
else if (dy==3)
|
||||||
|
a = 0x50;
|
||||||
|
else
|
||||||
|
a = 0x00;
|
||||||
|
memset(attrs, a, 8);
|
||||||
|
// TODO: this misses one row at the end?
|
||||||
|
putbytes(nt2attraddr(addr), attrs, 8);
|
||||||
|
}
|
||||||
// copy line to screen buffer
|
// copy line to screen buffer
|
||||||
putbytes(1, (ROWS-1)-(screen_y%60), buf, COLS);
|
putbytes(addr, buf, COLS);
|
||||||
// create actors on this level, if needed
|
// create actors on this level, if needed
|
||||||
// TODO: maybe this happens too early?
|
// TODO: maybe this happens too early?
|
||||||
if (dy == 0)
|
if (dy == 0 && level > 0) {
|
||||||
create_actors_on_level(i);
|
create_actors_on_level(level);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,16 +332,17 @@ void draw_screen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
word get_floor_yy(byte level) {
|
word get_floor_yy(byte level) {
|
||||||
return levels[level].ypos * 8 + 8;
|
return levels[level].ypos * 8 + 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
word get_ceiling_yy(byte level) {
|
word get_ceiling_yy(byte level) {
|
||||||
return (levels[level].ypos + levels[level].height) * 8 + 8;
|
return (levels[level].ypos + levels[level].height) * 8 + 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_scroll_pixel_yy(int yy) {
|
void set_scroll_pixel_yy(int yy) {
|
||||||
if ((yy & 7) == 0) {
|
if ((yy & 7) == 0) {
|
||||||
// draw an offscreen line
|
// draw an offscreen line
|
||||||
|
// TODO: doesn't work when going downward
|
||||||
draw_level_line(scroll_tile_y+30);
|
draw_level_line(scroll_tile_y+30);
|
||||||
}
|
}
|
||||||
scroll_pixel_yy = yy;
|
scroll_pixel_yy = yy;
|
||||||
@ -323,7 +353,7 @@ void set_scroll_pixel_yy(int yy) {
|
|||||||
void refresh_level(byte level) {
|
void refresh_level(byte level) {
|
||||||
byte y = levels[level].ypos;
|
byte y = levels[level].ypos;
|
||||||
draw_level_line(y+2);
|
draw_level_line(y+2);
|
||||||
draw_level_line(y+1);
|
draw_level_line(y+3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACTORS
|
// ACTORS
|
||||||
@ -366,12 +396,14 @@ void create_actors_on_level(byte level_index) {
|
|||||||
a->x = level->ladder1 ^ (level->ladder2<<3) ^ (level->gap<<6);
|
a->x = level->ladder1 ^ (level->ladder2<<3) ^ (level->gap<<6);
|
||||||
a->yy = get_floor_yy(level_index);
|
a->yy = get_floor_yy(level_index);
|
||||||
a->level = level_index;
|
a->level = level_index;
|
||||||
|
a->onscreen = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte draw_actor(byte oam_id, byte i) {
|
byte draw_actor(byte oam_id, byte i) {
|
||||||
struct Actor* a = &actors[i];
|
struct Actor* a = &actors[i];
|
||||||
const unsigned char* meta = playerStand;
|
bool dir = a->dir;
|
||||||
|
const unsigned char* meta;
|
||||||
byte x,y; // sprite variables
|
byte x,y; // sprite variables
|
||||||
int screen_y = SCREEN_Y_BOTTOM - a->yy + scroll_pixel_yy;
|
int screen_y = SCREEN_Y_BOTTOM - a->yy + scroll_pixel_yy;
|
||||||
if (screen_y > 192+8 || screen_y < -18) {
|
if (screen_y > 192+8 || screen_y < -18) {
|
||||||
@ -383,30 +415,34 @@ byte draw_actor(byte oam_id, byte i) {
|
|||||||
a->onscreen = 0;
|
a->onscreen = 0;
|
||||||
return oam_id; // inactive, offscreen
|
return oam_id; // inactive, offscreen
|
||||||
case STANDING:
|
case STANDING:
|
||||||
meta = playerStand;
|
meta = dir ? playerLStand : playerRStand;
|
||||||
break;
|
break;
|
||||||
case WALKING:
|
case WALKING:
|
||||||
meta = playerRunSeq[(a->x >> 1) & 7];
|
meta = playerRunSeq[((a->x >> 1) & 7) + (dir?0:8)];
|
||||||
break;
|
break;
|
||||||
case JUMPING:
|
case JUMPING:
|
||||||
meta = playerJump;
|
meta = dir ? playerLJump : playerRJump;
|
||||||
break;
|
break;
|
||||||
case FALLING:
|
case FALLING:
|
||||||
meta = playerSad;
|
meta = dir ? playerLSad : playerRSad;
|
||||||
break;
|
break;
|
||||||
case CLIMBING:
|
case CLIMBING:
|
||||||
meta = playerClimb;
|
meta = (a->yy & 4) ? playerLClimb : playerRClimb;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// set sprite values
|
// set sprite values
|
||||||
x = a->x;
|
x = a->x;
|
||||||
y = screen_y;
|
y = screen_y;
|
||||||
/*
|
|
||||||
tag = a->color1 | 0x80;
|
|
||||||
*/
|
|
||||||
if (i == 0)
|
|
||||||
player_screen_y = y;
|
|
||||||
oam_id = oam_meta_spr(x, y, oam_id, meta);
|
oam_id = oam_meta_spr(x, y, oam_id, meta);
|
||||||
|
// actor 0 is player sprite
|
||||||
|
if (i == 0) {
|
||||||
|
player_screen_y = y; // last screen Y position
|
||||||
|
// set special palette for player sprites
|
||||||
|
OAMBUF[0+2] |= 3;
|
||||||
|
OAMBUF[4+2] |= 3;
|
||||||
|
OAMBUF[8+2] |= 3;
|
||||||
|
OAMBUF[12+2] |= 3;
|
||||||
|
}
|
||||||
a->onscreen = 1;
|
a->onscreen = 1;
|
||||||
return oam_id;
|
return oam_id;
|
||||||
}
|
}
|
||||||
@ -483,7 +519,7 @@ void move_actor(struct Actor* actor, byte joystick, bool scroll) {
|
|||||||
if (joystick & PAD_A) {
|
if (joystick & PAD_A) {
|
||||||
actor->state = JUMPING;
|
actor->state = JUMPING;
|
||||||
actor->u.jumping.xvel = 0;
|
actor->u.jumping.xvel = 0;
|
||||||
actor->u.jumping.yvel = 15;
|
actor->u.jumping.yvel = JUMP_VELOCITY;
|
||||||
if (joystick & PAD_LEFT) actor->u.jumping.xvel = -1;
|
if (joystick & PAD_LEFT) actor->u.jumping.xvel = -1;
|
||||||
if (joystick & PAD_RIGHT) actor->u.jumping.xvel = 1;
|
if (joystick & PAD_RIGHT) actor->u.jumping.xvel = 1;
|
||||||
} else if (joystick & PAD_LEFT) {
|
} else if (joystick & PAD_LEFT) {
|
||||||
@ -528,8 +564,12 @@ void move_actor(struct Actor* actor, byte joystick, bool scroll) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JUMPING:
|
|
||||||
case FALLING:
|
case FALLING:
|
||||||
|
if (scroll) {
|
||||||
|
check_scroll_up();
|
||||||
|
check_scroll_down();
|
||||||
|
}
|
||||||
|
case JUMPING:
|
||||||
actor->x += actor->u.jumping.xvel;
|
actor->x += actor->u.jumping.xvel;
|
||||||
actor->yy += actor->u.jumping.yvel/4;
|
actor->yy += actor->u.jumping.yvel/4;
|
||||||
actor->u.jumping.yvel -= 1;
|
actor->u.jumping.yvel -= 1;
|
||||||
@ -647,22 +687,20 @@ void play_scene() {
|
|||||||
while (actors[0].level != MAX_LEVELS-1) {
|
while (actors[0].level != MAX_LEVELS-1) {
|
||||||
//set_scroll_pixel_yy(scroll_pixel_yy+1);
|
//set_scroll_pixel_yy(scroll_pixel_yy+1);
|
||||||
cflushnow();
|
cflushnow();
|
||||||
//ppu_wait_frame();
|
|
||||||
refresh_actors();
|
refresh_actors();
|
||||||
move_player();
|
move_player();
|
||||||
// move all the actors
|
// move all the actors
|
||||||
for (i=1; i<MAX_ACTORS; i++) {
|
for (i=1; i<MAX_ACTORS; i++) {
|
||||||
move_actor(&actors[i], rand(), false);
|
move_actor(&actors[i], rand8(), false);
|
||||||
}
|
}
|
||||||
// see if the player hit another actor
|
// see if the player hit another actor
|
||||||
/* TODO
|
// test sprite 0 collision flag
|
||||||
if (cv_get_sprite_collission()) {
|
if (PPU.status & 0x40) {
|
||||||
if (actors[0].level > BOTTOM_LEVEL_Y
|
if (actors[0].level > BOTTOM_LEVEL_Y
|
||||||
&& check_collision(&actors[0])) {
|
&& check_collision(&actors[0])) {
|
||||||
fall_down(&actors[0]);
|
fall_down(&actors[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blimp_pickup_scene();
|
blimp_pickup_scene();
|
||||||
@ -683,6 +721,7 @@ const char PALETTE[32] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void setup_graphics() {
|
void setup_graphics() {
|
||||||
|
ppu_off();
|
||||||
vram_adr(0x0);
|
vram_adr(0x0);
|
||||||
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
pal_all(PALETTE);
|
pal_all(PALETTE);
|
||||||
@ -691,7 +730,9 @@ void setup_graphics() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
setup_graphics();
|
while (1) {
|
||||||
make_levels();
|
setup_graphics();
|
||||||
play_scene();
|
make_levels();
|
||||||
|
play_scene();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,9 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
var video, audio, timer;
|
var video, audio, timer;
|
||||||
const audioFrequency = 44030; //44100
|
const audioFrequency = 44030; //44100
|
||||||
var frameindex = 0;
|
var frameindex = 0;
|
||||||
var nsamples = 0;
|
var ntvideo;
|
||||||
|
var ntlastbuf;
|
||||||
|
var ntvisible;
|
||||||
|
|
||||||
class JSNESPlatform extends Base6502Platform implements Platform {
|
class JSNESPlatform extends Base6502Platform implements Platform {
|
||||||
debugPCDelta = 1;
|
debugPCDelta = 1;
|
||||||
@ -79,24 +81,35 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
|
|
||||||
start() {
|
start() {
|
||||||
var self = this;
|
var self = this;
|
||||||
video = new RasterVideo(mainElement,256,224,{overscan:true});
|
var debugbar = $("<div>").appendTo(mainElement);
|
||||||
audio = new SampleAudio(audioFrequency);
|
audio = new SampleAudio(audioFrequency);
|
||||||
|
video = new RasterVideo(mainElement,256,224,{overscan:true});
|
||||||
video.create();
|
video.create();
|
||||||
|
// debugging view
|
||||||
|
ntvideo = new RasterVideo(mainElement,512,480,{overscan:false});
|
||||||
|
ntvideo.create();
|
||||||
|
$(ntvideo.canvas).hide();
|
||||||
|
ntvisible = false;
|
||||||
|
ntlastbuf = new Uint32Array(0x1000);
|
||||||
|
ntlastbuf.fill(-1);
|
||||||
|
// toggle buttons
|
||||||
|
$('<button>').text("Video").appendTo(debugbar).click(() => { $(video.canvas).toggle() });
|
||||||
|
$('<button>').text("Nametable").appendTo(debugbar).click(() => { $(ntvideo.canvas).toggle() });
|
||||||
|
|
||||||
var idata = video.getFrameData();
|
var idata = video.getFrameData();
|
||||||
nes = new jsnes.NES({
|
nes = new jsnes.NES({
|
||||||
onFrame: function(frameBuffer) {
|
onFrame: (frameBuffer : number[]) => {
|
||||||
for (var i=0; i<frameBuffer.length; i++)
|
for (var i=0; i<frameBuffer.length; i++)
|
||||||
idata[i] = frameBuffer[i] | 0xff000000;
|
idata[i] = frameBuffer[i] | 0xff000000;
|
||||||
video.updateFrame();
|
video.updateFrame();
|
||||||
frameindex++;
|
frameindex++;
|
||||||
//if (frameindex == 2000) console.log(nsamples*60/frameindex,'Hz');
|
this.updateDebugViews();
|
||||||
},
|
},
|
||||||
onAudioSample: function(left, right) {
|
onAudioSample: (left:number, right:number) => {
|
||||||
if (frameindex < 10)
|
if (frameindex < 10)
|
||||||
audio.feedSample(0, 1); // avoid popping at powerup
|
audio.feedSample(0, 1); // avoid popping at powerup
|
||||||
else
|
else
|
||||||
audio.feedSample(left+right, 1);
|
audio.feedSample(left+right, 1);
|
||||||
//nsamples++;
|
|
||||||
},
|
},
|
||||||
onStatusUpdate: function(s) {
|
onStatusUpdate: function(s) {
|
||||||
console.log(s);
|
console.log(s);
|
||||||
@ -130,7 +143,46 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
|
|
||||||
advance(novideo : boolean) {
|
advance(novideo : boolean) {
|
||||||
nes.frame();
|
nes.frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateDebugViews() {
|
||||||
|
//console.log(nes.ppu);
|
||||||
|
var a = 0;
|
||||||
|
var attraddr = 0;
|
||||||
|
var idata = ntvideo.getFrameData();
|
||||||
|
var baseTile = nes.ppu.regS === 0 ? 0 : 256;
|
||||||
|
for (var row=0; row<60; row++) {
|
||||||
|
for (var col=0; col<64; col++) {
|
||||||
|
a = 0x2000 + (col&31) + ((row%30)*32);
|
||||||
|
if (col >= 32) a += 0x400;
|
||||||
|
if (row >= 30) a += 0x800;
|
||||||
|
var name = nes.ppu.mirroredLoad(a) + baseTile;
|
||||||
|
var t = nes.ppu.ptTile[name];
|
||||||
|
attraddr = (a & 0x2c00) | 0x3c0 | (a & 0x0C00) | ((a >> 4) & 0x38) | ((a >> 2) & 0x07);
|
||||||
|
var attr = nes.ppu.mirroredLoad(attraddr);
|
||||||
|
var tag = name ^ (attr<<9);
|
||||||
|
if (tag != ntlastbuf[a & 0xfff]) {
|
||||||
|
ntlastbuf[a & 0xfff] = tag;
|
||||||
|
var i = row*64*8*8 + col*8;
|
||||||
|
var j = 0;
|
||||||
|
var attrshift = (col&2) + ((a&0x40)>>4);
|
||||||
|
var coloradd = ((attr >> attrshift) & 3) << 2;
|
||||||
|
for (var y=0; y<8; y++) {
|
||||||
|
for (var x=0; x<8; x++) {
|
||||||
|
var color = t.pix[j++] + coloradd;
|
||||||
|
var rgb = nes.ppu.imgPalette[color];
|
||||||
|
idata[i++] = rgb;
|
||||||
|
}
|
||||||
|
i += 64*8-8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i=0; i<idata.length; i++) {
|
||||||
|
idata[i] = idata[i] | 0xff000000;
|
||||||
|
}
|
||||||
|
ntvideo.updateFrame();
|
||||||
|
}
|
||||||
|
|
||||||
loadROM(title, data) {
|
loadROM(title, data) {
|
||||||
var romstr = String.fromCharCode.apply(null, data);
|
var romstr = String.fromCharCode.apply(null, data);
|
||||||
|
Loading…
Reference in New Issue
Block a user