mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-27 01:51:35 +00:00
150 lines
4.0 KiB
C
150 lines
4.0 KiB
C
|
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
// include NESLIB header
|
||
|
|
||
|
#include "neslib.h"
|
||
|
|
||
|
// include CC65 NES Header (PPU)
|
||
|
|
||
|
#include <nes.h>
|
||
|
|
||
|
///// PATTERN TABLE
|
||
|
|
||
|
//#link "jroatch.c"
|
||
|
extern unsigned char jroatch_chr[0x1000];
|
||
|
#define PATTERN_TABLE jroatch_chr
|
||
|
|
||
|
///// METASPRITES
|
||
|
|
||
|
// define a 2x2 metasprite
|
||
|
#define DEF_METASPRITE_2x2(name,code,pal)\
|
||
|
const unsigned char name[]={\
|
||
|
0, 0, (code)+0, pal, \
|
||
|
8, 0, (code)+1, pal, \
|
||
|
0, 8, (code)+2, pal, \
|
||
|
8, 8, (code)+3, pal, \
|
||
|
128};
|
||
|
|
||
|
// define a 2x2 metasprite, flipped horizontally
|
||
|
#define DEF_METASPRITE_2x2_FLIP(name,code,pal)\
|
||
|
const unsigned char name[]={\
|
||
|
8, 0, (code)+0, (pal)|OAM_FLIP_H, \
|
||
|
0, 0, (code)+1, (pal)|OAM_FLIP_H, \
|
||
|
8, 8, (code)+2, (pal)|OAM_FLIP_H, \
|
||
|
0, 8, (code)+3, (pal)|OAM_FLIP_H, \
|
||
|
128};
|
||
|
|
||
|
DEF_METASPRITE_2x2(playerRStand, 0xd8, 0);
|
||
|
DEF_METASPRITE_2x2(playerRRun1, 0xdc, 0);
|
||
|
DEF_METASPRITE_2x2(playerRRun2, 0xe0, 0);
|
||
|
DEF_METASPRITE_2x2(playerRRun3, 0xe4, 0);
|
||
|
DEF_METASPRITE_2x2(playerRJump, 0xe8, 0);
|
||
|
DEF_METASPRITE_2x2(playerRClimb, 0xec, 0);
|
||
|
DEF_METASPRITE_2x2(playerRSad, 0xf0, 0);
|
||
|
|
||
|
DEF_METASPRITE_2x2_FLIP(playerLStand, 0xd8, 0);
|
||
|
DEF_METASPRITE_2x2_FLIP(playerLRun1, 0xdc, 0);
|
||
|
DEF_METASPRITE_2x2_FLIP(playerLRun2, 0xe0, 0);
|
||
|
DEF_METASPRITE_2x2_FLIP(playerLRun3, 0xe4, 0);
|
||
|
DEF_METASPRITE_2x2_FLIP(playerLJump, 0xe8, 0);
|
||
|
DEF_METASPRITE_2x2_FLIP(playerLClimb, 0xec, 0);
|
||
|
DEF_METASPRITE_2x2_FLIP(playerLSad, 0xf0, 0);
|
||
|
|
||
|
DEF_METASPRITE_2x2(personToSave, 0xba, 1);
|
||
|
|
||
|
const unsigned char* const playerRunSeq[16] = {
|
||
|
playerLRun1, playerLRun2, playerLRun3,
|
||
|
playerLRun1, playerLRun2, playerLRun3,
|
||
|
playerLRun1, playerLRun2,
|
||
|
playerRRun1, playerRRun2, playerRRun3,
|
||
|
playerRRun1, playerRRun2, playerRRun3,
|
||
|
playerRRun1, playerRRun2,
|
||
|
};
|
||
|
|
||
|
const char PALETTE[32] = {
|
||
|
0x03, // background color
|
||
|
|
||
|
0x11,0x30,0x27, 0, // ladders and pickups
|
||
|
0x1c,0x20,0x2c, 0, // floor blocks
|
||
|
0x00,0x10,0x20, 0,
|
||
|
0x06,0x16,0x26, 0,
|
||
|
|
||
|
0x16,0x35,0x24, 0, // enemy sprites
|
||
|
0x00,0x37,0x25, 0, // rescue person
|
||
|
0x0d,0x2d,0x3a, 0,
|
||
|
0x0d,0x27,0x2a // player sprites
|
||
|
};
|
||
|
|
||
|
// setup PPU and tables
|
||
|
void setup_graphics() {
|
||
|
// set pattern table
|
||
|
vram_adr(0x0);
|
||
|
vram_write((unsigned char*)PATTERN_TABLE, sizeof(PATTERN_TABLE));
|
||
|
// clear sprites
|
||
|
oam_hide_rest(0);
|
||
|
// set palette colors
|
||
|
pal_all(PALETTE);
|
||
|
// turn on PPU
|
||
|
ppu_on_all();
|
||
|
}
|
||
|
|
||
|
// number of actors (4 h/w sprites each)
|
||
|
#define NUM_ACTORS 16
|
||
|
|
||
|
// actor x/y positions
|
||
|
char actor_x[NUM_ACTORS];
|
||
|
char actor_y[NUM_ACTORS];
|
||
|
// actor x/y deltas per frame
|
||
|
char actor_dx[NUM_ACTORS];
|
||
|
char actor_dy[NUM_ACTORS];
|
||
|
|
||
|
// OAM buffer pointer, in case we want to manipulate directly
|
||
|
#define OAMBUF ((unsigned char*) 0x200)
|
||
|
|
||
|
// main program
|
||
|
void main() {
|
||
|
char i;
|
||
|
char oam_id;
|
||
|
char pad; // controller flags
|
||
|
|
||
|
setup_graphics();
|
||
|
// initialize actors with random values
|
||
|
for (i=0; i<NUM_ACTORS; i++) {
|
||
|
actor_x[i] = i*32+128;
|
||
|
actor_y[i] = i*8+64;
|
||
|
actor_dx[i] = 0;
|
||
|
actor_dy[i] = 0;
|
||
|
}
|
||
|
// loop forever
|
||
|
while (1) {
|
||
|
// start with OAMid/sprite 0
|
||
|
oam_id = 0;
|
||
|
// set player 0/1 velocity based on controller
|
||
|
for (i=0; i<2; i++) {
|
||
|
// poll controller i (0-1)
|
||
|
pad = pad_poll(i);
|
||
|
// move actor[i] left/right
|
||
|
if (pad&PAD_LEFT && actor_x[i]>0) actor_dx[i]=-2;
|
||
|
else if (pad&PAD_RIGHT && actor_x[i]<232) actor_dx[i]=2;
|
||
|
else actor_dx[i]=0;
|
||
|
// move actor[i] up/down
|
||
|
if (pad&PAD_UP && actor_y[i]>0) actor_dy[i]=-2;
|
||
|
else if (pad&PAD_DOWN && actor_y[i]<212) actor_dy[i]=2;
|
||
|
else actor_dy[i]=0;
|
||
|
}
|
||
|
// draw and move all actors
|
||
|
for (i=0; i<NUM_ACTORS; i++) {
|
||
|
oam_id = oam_meta_spr(actor_x[i], actor_y[i], oam_id, playerRunSeq[i]);
|
||
|
actor_x[i] += actor_dx[i];
|
||
|
actor_y[i] += actor_dy[i];
|
||
|
}
|
||
|
// hide rest of sprites
|
||
|
// if we haven't wrapped oam_id around to 0
|
||
|
if (oam_id!=0) oam_hide_rest(oam_id);
|
||
|
// wait for next frame
|
||
|
ppu_wait_frame();
|
||
|
}
|
||
|
}
|