mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-06-01 05:41:31 +00:00
new neslib2.lib (from clbr/neslib) using extrafiles parameter, local .h, disasm uses symbols
This commit is contained in:
parent
4a82d341bc
commit
b29f11a1cc
|
@ -60,6 +60,7 @@ $("#deleteitem").click(function(e) {
|
||||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||||
|
|
||||||
ga('create', 'UA-54497476-9', 'auto');
|
ga('create', 'UA-54497476-9', 'auto');
|
||||||
|
ga('set', 'anonymizeIp', true);
|
||||||
ga('send', 'pageview');
|
ga('send', 'pageview');
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
|
||||||
|
#pragma data-name (push,"CHARS")
|
||||||
|
#pragma data-name (pop)
|
||||||
|
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
#define HAS_DEBUGGER
|
#define HAS_DEBUGGER
|
||||||
|
|
||||||
|
@ -34,6 +37,8 @@ static const unsigned char paused_palette[]={
|
||||||
#pragma bss-name(push,"ZEROPAGE")
|
#pragma bss-name(push,"ZEROPAGE")
|
||||||
#pragma data-name(push,"ZEROPAGE")
|
#pragma data-name(push,"ZEROPAGE")
|
||||||
|
|
||||||
|
unsigned char oam_off;
|
||||||
|
|
||||||
static unsigned char i, j;
|
static unsigned char i, j;
|
||||||
|
|
||||||
static unsigned char player_dir[2];
|
static unsigned char player_dir[2];
|
||||||
|
@ -2632,14 +2637,20 @@ void __fastcall__ init(void){
|
||||||
bank_spr(0);
|
bank_spr(0);
|
||||||
bank_bg(1);
|
bank_bg(1);
|
||||||
|
|
||||||
unrle_vram(bg_top_left, NAMETABLE_A);
|
vram_adr(NAMETABLE_A);
|
||||||
unrle_vram(bg_top_right, NAMETABLE_B);
|
vram_unrle(bg_top_left);
|
||||||
unrle_vram(bg_bottom_left, NAMETABLE_C);
|
vram_adr(NAMETABLE_B);
|
||||||
unrle_vram(bg_bottom_right, NAMETABLE_D);
|
vram_unrle(bg_top_right);
|
||||||
|
vram_adr(NAMETABLE_C);
|
||||||
|
vram_unrle(bg_bottom_left);
|
||||||
|
vram_adr(NAMETABLE_D);
|
||||||
|
vram_unrle(bg_bottom_right);
|
||||||
|
|
||||||
// copy tilesets
|
// copy tilesets
|
||||||
vram_write((unsigned char*)0x0000, 0x0, 0x2000);
|
vram_adr(0x0);
|
||||||
vram_write((unsigned char*)0x2000, 0x0, 0x2000);
|
vram_write((unsigned char*)0x0000, 0x2000);
|
||||||
|
vram_adr(0x2000);
|
||||||
|
vram_write((unsigned char*)0x2000, 0x2000);
|
||||||
|
|
||||||
ppu_on_all();
|
ppu_on_all();
|
||||||
|
|
||||||
|
@ -2823,20 +2834,21 @@ void main(void){
|
||||||
while(1){
|
while(1){
|
||||||
pal_all(paused_palette);
|
pal_all(paused_palette);
|
||||||
scroll(0, 0);
|
scroll(0, 0);
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
|
|
||||||
|
|
||||||
ppu_off();
|
ppu_off();
|
||||||
unrle_vram(bg_menu, NAMETABLE_A);
|
vram_adr(NAMETABLE_A);
|
||||||
|
vram_unrle(bg_menu);
|
||||||
ppu_on_all();
|
ppu_on_all();
|
||||||
|
|
||||||
pal_all(palette);
|
pal_all(palette);
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
|
|
||||||
|
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
while(1){
|
while(1){
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
spr=0;
|
spr=0;
|
||||||
oam_clear();
|
oam_clear();
|
||||||
frame++;
|
frame++;
|
||||||
|
@ -2894,20 +2906,21 @@ void main(void){
|
||||||
oam_clear();
|
oam_clear();
|
||||||
|
|
||||||
pal_all(paused_palette);
|
pal_all(paused_palette);
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
|
|
||||||
|
|
||||||
ppu_off();
|
ppu_off();
|
||||||
unrle_vram(bg_top_left, NAMETABLE_A);
|
vram_adr(NAMETABLE_A);
|
||||||
|
vram_unrle(bg_top_left);
|
||||||
ppu_on_all();
|
ppu_on_all();
|
||||||
|
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
|
|
||||||
difficulty = 0;
|
difficulty = 0;
|
||||||
next_level = 1;
|
next_level = 1;
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
spr=0;
|
spr=0;
|
||||||
oam_clear();
|
oam_clear();
|
||||||
|
|
||||||
|
@ -2941,7 +2954,7 @@ void main(void){
|
||||||
frame = 0;
|
frame = 0;
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
frame++;
|
frame++;
|
||||||
if((frame > 100) && (frame == 255 || ((pad_trigger(0)|pad_trigger(1))&(PAD_A|PAD_B|PAD_START))))
|
if((frame > 100) && (frame == 255 || ((pad_trigger(0)|pad_trigger(1))&(PAD_A|PAD_B|PAD_START))))
|
||||||
{
|
{
|
||||||
|
@ -2981,7 +2994,7 @@ void main(void){
|
||||||
frame = 0;
|
frame = 0;
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
frame++;
|
frame++;
|
||||||
if(frame == 255)
|
if(frame == 255)
|
||||||
{
|
{
|
||||||
|
@ -3014,7 +3027,7 @@ void main(void){
|
||||||
|
|
||||||
while(!(pad_trigger(0) & PAD_START))
|
while(!(pad_trigger(0) & PAD_START))
|
||||||
{
|
{
|
||||||
ppu_waitnmi();
|
ppu_wait_nmi();
|
||||||
}
|
}
|
||||||
|
|
||||||
pal_all(palette);
|
pal_all(palette);
|
||||||
|
|
292
presets/nes/neslib.h
Normal file
292
presets/nes/neslib.h
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
/*
|
||||||
|
(C) 2015 Alex Semenov (Shiru)
|
||||||
|
(C) 2016 Lauri Kasanen
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NES hardware-dependent functions by Shiru (shiru@mail.ru)
|
||||||
|
// Feel free to do anything you want with this code, consider it Public Domain
|
||||||
|
|
||||||
|
// Versions history:
|
||||||
|
// 280215 - fixed palette glitch caused with the active DMC DMA glitch
|
||||||
|
// 030914 - minor fixes in the vram update system
|
||||||
|
// 310814 - added vram_flush_update
|
||||||
|
// 120414 - removed adr argument from vram_write and vram_read,
|
||||||
|
// unrle_vram renamed to vram_unrle, with adr argument removed
|
||||||
|
// 060414 - many fixes and improvements, including sequental VRAM updates
|
||||||
|
// previous versions were created since mid-2011, there were many updates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// set bg and spr palettes, data is 32 bytes array
|
||||||
|
void __fastcall__ pal_all(const char *data);
|
||||||
|
|
||||||
|
// set bg palette only, data is 16 bytes array
|
||||||
|
void __fastcall__ pal_bg(const char *data);
|
||||||
|
|
||||||
|
// set spr palette only, data is 16 bytes array
|
||||||
|
void __fastcall__ pal_spr(const char *data);
|
||||||
|
|
||||||
|
// set a palette entry, index is 0..31
|
||||||
|
void __fastcall__ pal_col(unsigned char index, unsigned char color);
|
||||||
|
|
||||||
|
// reset palette to $0f
|
||||||
|
void __fastcall__ pal_clear(void);
|
||||||
|
|
||||||
|
// set virtual bright both for sprites and background, 0 is black, 4 is normal, 8 is white
|
||||||
|
void __fastcall__ pal_bright(unsigned char bright);
|
||||||
|
|
||||||
|
// set virtual bright for sprites only
|
||||||
|
void __fastcall__ pal_spr_bright(unsigned char bright);
|
||||||
|
|
||||||
|
// set virtual bright for sprites background only
|
||||||
|
void __fastcall__ pal_bg_bright(unsigned char bright);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// wait actual TV frame, 50hz for PAL, 60hz for NTSC
|
||||||
|
void __fastcall__ ppu_wait_nmi(void);
|
||||||
|
|
||||||
|
// wait virtual frame, it is always 50hz, frame-to-frame in PAL, frameskip in NTSC
|
||||||
|
void __fastcall__ ppu_wait_frame(void);
|
||||||
|
|
||||||
|
// turn off rendering, nmi still enabled when rendering is disabled
|
||||||
|
void __fastcall__ ppu_off(void);
|
||||||
|
|
||||||
|
// turn on bg, spr
|
||||||
|
void __fastcall__ ppu_on_all(void);
|
||||||
|
|
||||||
|
// turn on bg only
|
||||||
|
void __fastcall__ ppu_on_bg(void);
|
||||||
|
|
||||||
|
// turn on spr only
|
||||||
|
void __fastcall__ ppu_on_spr(void);
|
||||||
|
|
||||||
|
// set PPU_MASK directly
|
||||||
|
void __fastcall__ ppu_mask(unsigned char mask);
|
||||||
|
|
||||||
|
// get current video system, 0 for PAL, not 0 for NTSC
|
||||||
|
unsigned char __fastcall__ ppu_system(void);
|
||||||
|
|
||||||
|
// Return an 8-bit counter incremented at each vblank
|
||||||
|
unsigned char __fastcall__ nesclock(void);
|
||||||
|
|
||||||
|
// get/set the internal ppu ctrl cache var for manual writing
|
||||||
|
unsigned char __fastcall__ get_ppu_ctrl_var(void);
|
||||||
|
void __fastcall__ set_ppu_ctrl_var(unsigned char var);
|
||||||
|
|
||||||
|
|
||||||
|
// clear OAM buffer, all the sprites are hidden
|
||||||
|
void __fastcall__ oam_clear(void);
|
||||||
|
|
||||||
|
// set sprite display mode, 0 for 8x8 sprites, 1 for 8x16 sprites
|
||||||
|
void __fastcall__ oam_size(unsigned char size);
|
||||||
|
|
||||||
|
// set sprite in OAM buffer, chrnum is tile, attr is attribute, sprid is offset in OAM in bytes
|
||||||
|
// returns sprid+4, which is offset for a next sprite
|
||||||
|
unsigned char __fastcall__ oam_spr(unsigned char x, unsigned char y,
|
||||||
|
unsigned char chrnum, unsigned char attr,
|
||||||
|
unsigned char sprid);
|
||||||
|
|
||||||
|
// set metasprite in OAM buffer
|
||||||
|
// meta sprite is a const unsigned char array, it contains four bytes per sprite
|
||||||
|
// in order x offset, y offset, tile, attribute
|
||||||
|
// x=128 is end of a meta sprite
|
||||||
|
// returns sprid+4, which is offset for a next sprite
|
||||||
|
unsigned char __fastcall__ oam_meta_spr(unsigned char x, unsigned char y,
|
||||||
|
unsigned char sprid, const unsigned char *data);
|
||||||
|
|
||||||
|
// hide all remaining sprites from given offset
|
||||||
|
void __fastcall__ oam_hide_rest(unsigned char sprid);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// play a music in FamiTone format
|
||||||
|
void __fastcall__ music_play(unsigned char song);
|
||||||
|
|
||||||
|
// stop music
|
||||||
|
void __fastcall__ music_stop(void);
|
||||||
|
|
||||||
|
// pause and unpause music
|
||||||
|
void __fastcall__ music_pause(unsigned char pause);
|
||||||
|
|
||||||
|
// play FamiTone sound effect on channel 0..3
|
||||||
|
void __fastcall__ sfx_play(unsigned char sound, unsigned char channel);
|
||||||
|
|
||||||
|
// play a DPCM sample, 1..63
|
||||||
|
void __fastcall__ sample_play(unsigned char sample);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// poll controller and return flags like PAD_LEFT etc, input is pad number (0 or 1)
|
||||||
|
unsigned char __fastcall__ pad_poll(unsigned char pad);
|
||||||
|
|
||||||
|
// poll controller in trigger mode, a flag is set only on button down, not hold
|
||||||
|
// if you need to poll the pad in both normal and trigger mode, poll it in the
|
||||||
|
// trigger mode for first, then use pad_state
|
||||||
|
unsigned char __fastcall__ pad_trigger(unsigned char pad);
|
||||||
|
|
||||||
|
// get previous pad state without polling ports
|
||||||
|
unsigned char __fastcall__ pad_state(unsigned char pad);
|
||||||
|
|
||||||
|
|
||||||
|
// set scroll, including rhe top bits
|
||||||
|
// it is always applied at beginning of a TV frame, not at the function call
|
||||||
|
void __fastcall__ scroll(unsigned int x, unsigned int y);
|
||||||
|
|
||||||
|
// set scroll after screen split invoked by the sprite 0 hit
|
||||||
|
// warning: all CPU time between the function call and the actual split point will be wasted!
|
||||||
|
// warning: the program loop has to fit into the frame time, ppu_wait_frame should not be used
|
||||||
|
// otherwise empty frames without split will be inserted, resulting in jumpy screen
|
||||||
|
// warning: only X scroll could be changed in this version
|
||||||
|
void __fastcall__ split(unsigned int x, unsigned int y);
|
||||||
|
|
||||||
|
|
||||||
|
// select current chr bank for sprites, 0..1
|
||||||
|
void __fastcall__ bank_spr(unsigned char n);
|
||||||
|
|
||||||
|
// select current chr bank for background, 0..1
|
||||||
|
void __fastcall__ bank_bg(unsigned char n);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// get random number 0..255 or 0..65535
|
||||||
|
unsigned char __fastcall__ rand8(void);
|
||||||
|
unsigned int __fastcall__ rand16(void);
|
||||||
|
|
||||||
|
// set random seed
|
||||||
|
void __fastcall__ set_rand(unsigned int seed);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// when display is enabled, vram access could only be done with this vram update system
|
||||||
|
// the function sets a pointer to the update buffer that contains data and addresses
|
||||||
|
// in a special format. It allows to write non-sequental bytes, as well as horizontal or
|
||||||
|
// vertical nametable sequences.
|
||||||
|
// buffer pointer could be changed during rendering, but it only takes effect on a new frame
|
||||||
|
// number of transferred bytes is limited by vblank time
|
||||||
|
// to disable updates, call this function with NULL pointer
|
||||||
|
|
||||||
|
// the update data format:
|
||||||
|
// MSB, LSB, byte for a non-sequental write
|
||||||
|
// MSB|NT_UPD_HORZ, LSB, LEN, [bytes] for a horizontal sequence
|
||||||
|
// MSB|NT_UPD_VERT, LSB, LEN, [bytes] for a vertical sequence
|
||||||
|
// NT_UPD_EOF to mark end of the buffer
|
||||||
|
|
||||||
|
// length of this data should be under 256 bytes
|
||||||
|
|
||||||
|
void __fastcall__ set_vram_update(unsigned char *buf);
|
||||||
|
|
||||||
|
// all following vram functions only work when display is disabled
|
||||||
|
|
||||||
|
// do a series of VRAM writes, the same format as for set_vram_update, but writes done right away
|
||||||
|
void __fastcall__ flush_vram_update(unsigned char *buf);
|
||||||
|
|
||||||
|
// set vram pointer to write operations if you need to write some data to vram
|
||||||
|
void __fastcall__ vram_adr(unsigned int adr);
|
||||||
|
|
||||||
|
// put a byte at current vram address, works only when rendering is turned off
|
||||||
|
void __fastcall__ vram_put(unsigned char n);
|
||||||
|
|
||||||
|
// fill a block with a byte at current vram address, works only when rendering is turned off
|
||||||
|
void __fastcall__ vram_fill(unsigned char n, unsigned int len);
|
||||||
|
|
||||||
|
// set vram autoincrement, 0 for +1 and not 0 for +32
|
||||||
|
void __fastcall__ vram_inc(unsigned char n);
|
||||||
|
|
||||||
|
// read a block from current address of vram, works only when rendering is turned off
|
||||||
|
void __fastcall__ vram_read(unsigned char *dst, unsigned int size);
|
||||||
|
|
||||||
|
// write a block to current address of vram, works only when rendering is turned off
|
||||||
|
void __fastcall__ vram_write(const unsigned char *src, unsigned int size);
|
||||||
|
|
||||||
|
|
||||||
|
// unpack RLE data to current address of vram, mostly used for nametables
|
||||||
|
void __fastcall__ vram_unrle(const unsigned char *data);
|
||||||
|
|
||||||
|
// unpack LZ4 data to this address
|
||||||
|
void __fastcall__ vram_unlz4(const unsigned char *in, unsigned char *out,
|
||||||
|
const unsigned uncompressed_size);
|
||||||
|
/*
|
||||||
|
Rough speeds for a full 1024 nametable:
|
||||||
|
- rle takes 0.5 frames
|
||||||
|
- uncompressed takes 1.3 frames
|
||||||
|
- lz4 takes 2.8 frames
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// like memset, but does not return anything
|
||||||
|
void __fastcall__ memfill(void *dst, unsigned char value, unsigned int len);
|
||||||
|
|
||||||
|
// delay for N frames
|
||||||
|
void __fastcall__ delay(unsigned char frames);
|
||||||
|
|
||||||
|
// display.sinc functions
|
||||||
|
void __fastcall__ oam_clear_fast(void);
|
||||||
|
void __fastcall__ oam_meta_spr_pal(unsigned char x,unsigned char y,unsigned char pal,const unsigned char *metasprite);
|
||||||
|
void __fastcall__ oam_meta_spr_clip(signed int x,unsigned char y,const unsigned char *metasprite);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define PAD_A 0x01
|
||||||
|
#define PAD_B 0x02
|
||||||
|
#define PAD_SELECT 0x04
|
||||||
|
#define PAD_START 0x08
|
||||||
|
#define PAD_UP 0x10
|
||||||
|
#define PAD_DOWN 0x20
|
||||||
|
#define PAD_LEFT 0x40
|
||||||
|
#define PAD_RIGHT 0x80
|
||||||
|
|
||||||
|
#define OAM_FLIP_V 0x80
|
||||||
|
#define OAM_FLIP_H 0x40
|
||||||
|
#define OAM_BEHIND 0x20
|
||||||
|
|
||||||
|
#define MAX(x1,x2) ((x1)<(x2)?(x2):(x1))
|
||||||
|
#define MIN(x1,x2) ((x1)<(x2)?(x1):(x2))
|
||||||
|
|
||||||
|
#define MASK_SPR 0x10
|
||||||
|
#define MASK_BG 0x08
|
||||||
|
#define MASK_EDGE_SPR 0x04
|
||||||
|
#define MASK_EDGE_BG 0x02
|
||||||
|
|
||||||
|
#define NAMETABLE_A 0x2000
|
||||||
|
#define NAMETABLE_B 0x2400
|
||||||
|
#define NAMETABLE_C 0x2800
|
||||||
|
#define NAMETABLE_D 0x2c00
|
||||||
|
|
||||||
|
#define NULL 0
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
#define NT_UPD_HORZ 0x40
|
||||||
|
#define NT_UPD_VERT 0x80
|
||||||
|
#define NT_UPD_EOF 0xff
|
||||||
|
|
||||||
|
// macro to calculate nametable address from X,Y in compile time
|
||||||
|
|
||||||
|
#define NTADR_A(x,y) (NAMETABLE_A|(((y)<<5)|(x)))
|
||||||
|
#define NTADR_B(x,y) (NAMETABLE_B|(((y)<<5)|(x)))
|
||||||
|
#define NTADR_C(x,y) (NAMETABLE_C|(((y)<<5)|(x)))
|
||||||
|
#define NTADR_D(x,y) (NAMETABLE_D|(((y)<<5)|(x)))
|
||||||
|
|
||||||
|
// macro to get MSB and LSB
|
||||||
|
|
||||||
|
#define MSB(x) (((x)>>8))
|
||||||
|
#define LSB(x) (((x)&0xff))
|
|
@ -3,7 +3,11 @@
|
||||||
|
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
|
||||||
// tileset data
|
#pragma bss-name (push,"ZEROPAGE")
|
||||||
|
unsigned char oam_off;
|
||||||
|
#pragma bss-name (pop)
|
||||||
|
|
||||||
|
#pragma data-name (push,"CHARS")
|
||||||
|
|
||||||
const unsigned char TILESET[8*128] = {/*{w:8,h:8,bpp:1,count:128,brev:1}*/
|
const unsigned char TILESET[8*128] = {/*{w:8,h:8,bpp:1,count:128,brev:1}*/
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x7c,0x7c,0x7c,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x6c,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0xfe,0x6c,0xfe,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xfe,0xd0,0xfe,0x16,0xfe,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xdc,0x38,0x76,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x6c,0x7c,0xec,0xee,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x70,0x70,0x70,0x70,0x70,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x38,0x38,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x38,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0xfe,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x1e,0x3c,0x78,0xf0,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x7c,0x7c,0x7c,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x6c,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0xfe,0x6c,0xfe,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xfe,0xd0,0xfe,0x16,0xfe,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xdc,0x38,0x76,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x6c,0x7c,0xec,0xee,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x70,0x70,0x70,0x70,0x70,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x38,0x38,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x38,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0xfe,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x1e,0x3c,0x78,0xf0,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
@ -12,6 +16,8 @@ const unsigned char TILESET[8*128] = {/*{w:8,h:8,bpp:1,count:128,brev:1}*/
|
||||||
0x00,0xfc,0xee,0xee,0xee,0xfc,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0xee,0xee,0xee,0xec,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xee,0xee,0xee,0xfc,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0xe0,0x7c,0x0e,0xee,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x38,0x38,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0xee,0xee,0xee,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0xee,0x6c,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0xfe,0xfe,0xee,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0x7c,0x38,0x7c,0xee,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0xee,0x7c,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x1c,0x38,0x70,0xe0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
0x00,0xfc,0xee,0xee,0xee,0xfc,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0xee,0xee,0xee,0xec,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xee,0xee,0xee,0xfc,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0xe0,0x7c,0x0e,0xee,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x38,0x38,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0xee,0xee,0xee,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0xee,0x6c,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0xfe,0xfe,0xee,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0x7c,0x38,0x7c,0xee,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xee,0xee,0xee,0x7c,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x1c,0x38,0x70,0xe0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
//this macro is used remove need of calculation of the nametable address in runtime
|
//this macro is used remove need of calculation of the nametable address in runtime
|
||||||
|
|
||||||
#define NTADR(x,y) ((0x2000|((y)<<5)|x))
|
#define NTADR(x,y) ((0x2000|((y)<<5)|x))
|
||||||
|
@ -32,7 +38,8 @@ void put_str(unsigned int adr,const char *str)
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
//copy tileset to RAM
|
//copy tileset to RAM
|
||||||
vram_write((unsigned char*)TILESET, 0x0, sizeof(TILESET));
|
vram_adr(0x0);
|
||||||
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
|
|
||||||
//rendering is disabled at the startup, and palette is all black
|
//rendering is disabled at the startup, and palette is all black
|
||||||
pal_col(1,0x30);//set while color
|
pal_col(1,0x30);//set while color
|
||||||
|
|
|
@ -4,6 +4,13 @@
|
||||||
|
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
|
||||||
|
#pragma bss-name (push,"ZEROPAGE")
|
||||||
|
unsigned char oam_off;
|
||||||
|
#pragma bss-name (pop)
|
||||||
|
|
||||||
|
#pragma data-name (push,"CHARS")
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
//#link "tileset1.c"
|
//#link "tileset1.c"
|
||||||
|
|
||||||
// palette for balls, there are four sets for different ball colors
|
// palette for balls, there are four sets for different ball colors
|
||||||
|
@ -35,7 +42,8 @@ static unsigned char ball_dy[BALLS_MAX];
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
//copy tileset to RAM
|
//copy tileset to RAM
|
||||||
vram_write((unsigned char*)TILESET, 0x0, sizeof(TILESET));
|
vram_adr(0x0);
|
||||||
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
|
|
||||||
pal_spr(palSprites);//set palette for sprites
|
pal_spr(palSprites);//set palette for sprites
|
||||||
oam_size(1);
|
oam_size(1);
|
||||||
|
@ -69,7 +77,7 @@ void main(void)
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
ppu_waitnmi();//wait for next TV frame
|
ppu_wait_nmi();//wait for next TV frame
|
||||||
|
|
||||||
spr=0;
|
spr=0;
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,17 @@
|
||||||
//this example shows how to set up a palette and use 8x8 HW sprites
|
//this example shows how to set up a palette and use 8x8 HW sprites
|
||||||
//also shows how fast (or slow) C code is
|
//also shows how fast (or slow) C code is
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
|
||||||
|
#pragma bss-name (push,"ZEROPAGE")
|
||||||
|
unsigned char oam_off;
|
||||||
|
#pragma bss-name (pop)
|
||||||
|
|
||||||
|
#pragma data-name (push,"CHARS")
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
//#link "tileset1.c"
|
//#link "tileset1.c"
|
||||||
|
|
||||||
// tile set, two planes for 4 colors
|
// tile set, two planes for 4 colors
|
||||||
|
@ -13,9 +22,6 @@ extern unsigned char TILESET[8*256];
|
||||||
//and how to use nametable update system that allows to modify nametable
|
//and how to use nametable update system that allows to modify nametable
|
||||||
//while rendering is enabled
|
//while rendering is enabled
|
||||||
|
|
||||||
#include "neslib.h"
|
|
||||||
|
|
||||||
|
|
||||||
//these macro are needed to simplify defining update list constants
|
//these macro are needed to simplify defining update list constants
|
||||||
|
|
||||||
#define NTADR(x,y) ((0x2000|((y)<<5)|x))
|
#define NTADR(x,y) ((0x2000|((y)<<5)|x))
|
||||||
|
@ -35,27 +41,27 @@ static unsigned char list[6*3];
|
||||||
//init data for the update list, it contains MSB and LSB of a tile address
|
//init data for the update list, it contains MSB and LSB of a tile address
|
||||||
//in the nametable, then the tile number
|
//in the nametable, then the tile number
|
||||||
|
|
||||||
const unsigned char list_init[6*3]={
|
const unsigned char list_init[6*3+1]={
|
||||||
MSB(NTADR(2,2)),LSB(NTADR(2,2)),0,
|
MSB(NTADR(2,2)),LSB(NTADR(2,2)),0,
|
||||||
MSB(NTADR(3,2)),LSB(NTADR(3,2)),0,
|
MSB(NTADR(3,2)),LSB(NTADR(3,2)),0,
|
||||||
MSB(NTADR(4,2)),LSB(NTADR(4,2)),0,
|
MSB(NTADR(4,2)),LSB(NTADR(4,2)),0,
|
||||||
MSB(NTADR(6,2)),LSB(NTADR(6,2)),0,
|
MSB(NTADR(6,2)),LSB(NTADR(6,2)),0,
|
||||||
MSB(NTADR(7,2)),LSB(NTADR(7,2)),0,
|
MSB(NTADR(7,2)),LSB(NTADR(7,2)),0,
|
||||||
MSB(NTADR(8,2)),LSB(NTADR(8,2)),0
|
MSB(NTADR(8,2)),LSB(NTADR(8,2)),0,
|
||||||
|
NT_UPD_EOF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
//copy tileset to RAM
|
//copy tileset to RAM
|
||||||
vram_write((unsigned char*)TILESET, 0x0, sizeof(TILESET));
|
vram_adr(0x0);
|
||||||
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
|
|
||||||
pal_col(1,0x21);//blue color for text
|
pal_col(1,0x21);//blue color for text
|
||||||
pal_col(17,0x30);//white color for sprite
|
pal_col(17,0x30);//white color for sprite
|
||||||
|
|
||||||
memcpy(list,list_init,sizeof(list_init));
|
memcpy(list,list_init,sizeof(list_init));
|
||||||
set_vram_update(6,list);
|
set_vram_update(list);
|
||||||
|
|
||||||
ppu_on_all();//enable rendering
|
ppu_on_all();//enable rendering
|
||||||
|
|
||||||
|
@ -66,7 +72,7 @@ void main(void)
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
ppu_waitnmi();//wait for next TV frame
|
ppu_wait_nmi();//wait for next TV frame
|
||||||
|
|
||||||
oam_spr(x,y,0x41,0,0);//put sprite
|
oam_spr(x,y,0x41,0,0);//put sprite
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
|
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
|
||||||
|
#pragma bss-name (push,"ZEROPAGE")
|
||||||
|
unsigned char oam_off;
|
||||||
|
#pragma bss-name (pop)
|
||||||
|
|
||||||
|
#pragma data-name (push,"CHARS")
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
//#link "tileset1.c"
|
//#link "tileset1.c"
|
||||||
|
|
||||||
// tile set, two planes for 4 colors
|
// tile set, two planes for 4 colors
|
||||||
|
@ -54,7 +61,8 @@ const unsigned char metaCat2[]={
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
//copy tileset to RAM
|
//copy tileset to RAM
|
||||||
vram_write((unsigned char*)TILESET, 0x0, sizeof(TILESET));
|
vram_adr(0x0);
|
||||||
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
|
|
||||||
ppu_on_all();//enable rendering
|
ppu_on_all();//enable rendering
|
||||||
|
|
||||||
|
@ -74,7 +82,7 @@ void main(void)
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
ppu_waitnmi();//wait for next TV frame
|
ppu_wait_nmi();//wait for next TV frame
|
||||||
|
|
||||||
//flashing color for touch
|
//flashing color for touch
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,13 @@
|
||||||
|
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
|
||||||
|
#pragma bss-name (push,"ZEROPAGE")
|
||||||
|
unsigned char oam_off;
|
||||||
|
#pragma bss-name (pop)
|
||||||
|
|
||||||
|
#pragma data-name (push,"CHARS")
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
const unsigned char test[308]={
|
const unsigned char test[308]={
|
||||||
0x01,0x00,0x01,0xa3,0x10,0x01,0x04,0x00,0x10,0x01,0x04,0x00,0x10,0x01,0x04,0x00,
|
0x01,0x00,0x01,0xa3,0x10,0x01,0x04,0x00,0x10,0x01,0x04,0x00,0x10,0x01,0x04,0x00,
|
||||||
0x10,0x01,0x04,0x00,0x01,0x0a,0x10,0x00,0x01,0x02,0x10,0x00,0x01,0x04,0x10,0x00,
|
0x10,0x01,0x04,0x00,0x01,0x0a,0x10,0x00,0x01,0x02,0x10,0x00,0x01,0x04,0x10,0x00,
|
||||||
|
@ -41,10 +48,12 @@ void main(void)
|
||||||
pal_bg(palette);//set background palette from an array
|
pal_bg(palette);//set background palette from an array
|
||||||
|
|
||||||
//copy tileset to RAM
|
//copy tileset to RAM
|
||||||
vram_write((unsigned char*)TILESET, 0x0, sizeof(TILESET));
|
vram_adr(0x0);
|
||||||
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
|
|
||||||
//unpack nametable into the VRAM
|
//unpack nametable into the VRAM
|
||||||
unrle_vram(test,0x2000);
|
vram_adr(0x2000);
|
||||||
|
vram_unrle(test);
|
||||||
|
|
||||||
//enable rendering
|
//enable rendering
|
||||||
ppu_on_all();
|
ppu_on_all();
|
||||||
|
|
808
presets/nes/shoot2.c
Normal file
808
presets/nes/shoot2.c
Normal file
|
@ -0,0 +1,808 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <nes.h>
|
||||||
|
#include <joystick.h>
|
||||||
|
|
||||||
|
#include "neslib.h"
|
||||||
|
|
||||||
|
#pragma bss-name (push,"ZEROPAGE")
|
||||||
|
unsigned char oam_off;
|
||||||
|
#pragma bss-name (pop)
|
||||||
|
|
||||||
|
#pragma data-name (push,"CHARS")
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
|
#pragma static-locals (1);
|
||||||
|
|
||||||
|
#define COLS 32
|
||||||
|
#define ROWS 28
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
typedef signed char sbyte;
|
||||||
|
typedef unsigned short word;
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
const char PALETTE[32] = {
|
||||||
|
0x0f,
|
||||||
|
|
||||||
|
0x11,0x24,0x3c, 0,
|
||||||
|
0x01,0x15,0x25, 0,
|
||||||
|
0x01,0x10,0x20, 0,
|
||||||
|
0x06,0x16,0x26, 0,
|
||||||
|
|
||||||
|
0x11,0x24,0x3c, 0,
|
||||||
|
0x01,0x15,0x25, 0,
|
||||||
|
0x31,0x35,0x3c, 0,
|
||||||
|
0x01,0x17,0x30
|
||||||
|
};
|
||||||
|
|
||||||
|
#define COLOR_PLAYER 3
|
||||||
|
#define COLOR_FORMATION 1
|
||||||
|
#define COLOR_ATTACKER 1
|
||||||
|
#define COLOR_MISSILE 3
|
||||||
|
#define COLOR_BOMB 2
|
||||||
|
#define COLOR_SCORE 2
|
||||||
|
#define COLOR_EXPLOSION 3
|
||||||
|
|
||||||
|
const char TILESET[128*8*2] = {/*{w:8,h:8,bpp:1,count:128,brev:1,np:2,pofs:8,remap:[0,1,2,4,5,6,7,8,9,10,11,12]}*/
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x7C,0x7C,0x7C,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x6C,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0xFE,0x6C,0xFE,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xFE,0xD0,0xFE,0x16,0xFE,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCE,0xDC,0x38,0x76,0xE6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x6C,0x7C,0xEC,0xEE,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x70,0x70,0x70,0x70,0x70,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x38,0x38,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x38,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0xFE,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x1E,0x3C,0x78,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x7C,0xEE,0xEE,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x78,0x38,0x38,0x38,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x0E,0x7C,0xE0,0xEE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0E,0x3C,0x0E,0x0E,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7E,0xEE,0xEE,0xFE,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xE0,0xFC,0x0E,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xE0,0xFC,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xEE,0x1C,0x1C,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0x7C,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xEE,0x7E,0x0E,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x38,0x70,0x70,0x38,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x1C,0x1C,0x38,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0x1C,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x7C,0xEE,0xEE,0xEE,0xE0,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xEE,0xEE,0xFE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xEE,0xFC,0xEE,0xEE,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xE0,0xE0,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEC,0xEE,0xEE,0xEE,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xE0,0xF0,0xE0,0xE0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xE0,0xF8,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xE0,0xEE,0xEE,0xEE,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xFE,0xEE,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x38,0x38,0x38,0x38,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E,0x0E,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xFC,0xF8,0xEC,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0xE0,0xEE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCE,0xEE,0xFE,0xFE,0xEE,0xE6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xEE,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0xFC,0xEE,0xEE,0xEE,0xFC,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xEE,0xEE,0xEE,0xEC,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xEE,0xEE,0xEE,0xFC,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xE0,0x7C,0x0E,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x38,0x38,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xEE,0xEE,0xEE,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xEE,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xFE,0xFE,0xEE,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x7C,0x38,0x7C,0xEE,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xEE,0xEE,0x7C,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x1C,0x38,0x70,0xE0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
// formation enemy (66)
|
||||||
|
0x0C,0x13,0x03,0x03,0x03,0x01,0x01,0x00,0x0C,0x10,0x01,0x0C,0x30,0x02,0x04,0x18,
|
||||||
|
0x18,0x64,0xE0,0xE0,0xE0,0xC0,0xC0,0x80,0x18,0x04,0x40,0x18,0x06,0x20,0x10,0x0C,
|
||||||
|
// attackers (68)
|
||||||
|
0x00,0x00,0x04,0x08,0x04,0x00,0x01,0x0C,0x00,0x00,0x04,0x08,0x04,0x03,0x03,0x03,
|
||||||
|
0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x30,0x02,0x04,0x18,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x10,0x08,0x10,0x60,0xE0,0xE0,0x00,0x00,0x10,0x08,0x10,0x00,0x40,0x18,
|
||||||
|
0xE0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x06,0x20,0x10,0x0C,0x00,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x02,0x04,0x04,0x03,0x03,0x03,0x00,0x00,0x02,0x04,0x04,0x20,0x11,0x0C,
|
||||||
|
0x03,0x07,0x03,0x03,0x02,0x00,0x00,0x00,0x00,0x20,0x1C,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x08,0x08,0x10,0xE0,0xE0,0x00,0x00,0x00,0x08,0x08,0x10,0x00,0x40,
|
||||||
|
0xE0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x10,0x0C,0x02,0x20,0x10,0x0C,0x00,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x0C,0x04,0x02,0x03,0x07,0x27,0x00,0x00,0x0C,0x04,0x00,0x00,0x01,0x20,
|
||||||
|
0x3F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x04,0x08,0x10,0x01,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0x00,0x00,0x00,0x20,0x40,0x84,0x08,0x10,
|
||||||
|
0xE0,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x07,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x18,0x21,0x44,0x08,0x08,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x20,0x40,0x80,0x98,0x20,0x00,
|
||||||
|
0xE0,0xFC,0xC4,0x80,0x80,0x80,0xC0,0x00,0x40,0x0C,0x04,0x00,0x00,0x80,0xC0,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x02,0x11,0x08,0x04,
|
||||||
|
0x03,0x03,0x07,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x30,0x20,0x60,0xF0,0xFC,0x00,0x00,0x00,0x30,0x20,0x00,0x40,0x04,
|
||||||
|
0xFC,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x2C,0x00,0x20,0x18,0x80,0x40,0x60,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x00,0x00,0x00,0x10,0x10,0x08,0x04,0x00,
|
||||||
|
0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x08,0x34,0xE0,0xE0,0xF0,0x00,0x80,0x80,0x88,0x94,0x00,0x40,0x00,
|
||||||
|
0xFA,0xE4,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x04,0x80,0x40,0x20,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x00,0x00,0x01,0x09,0x08,0x04,0x02,0x00,
|
||||||
|
0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x08,0x09,0x01,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x08,0x14,0xE0,0xE0,0x00,0x00,0x00,0x00,0x88,0x94,0x00,0x40,
|
||||||
|
0xC0,0xE0,0xE0,0x14,0x08,0x00,0x00,0x00,0x00,0x40,0x00,0x94,0x88,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x01,0x01,0x01,0x00,0x00,0x01,0x11,0x11,0x01,0x01,0x02,0x07,0x01,0x21,0x21,0x2B,
|
||||||
|
0x11,0x16,0x1E,0x15,0x10,0x10,0x10,0x10,0x3F,0x3F,0x3F,0x3D,0x3B,0x3C,0x28,0x28,
|
||||||
|
0x40,0x40,0xC0,0x00,0x00,0x40,0x44,0x44,0xC0,0xC0,0x20,0xF0,0xC0,0xC2,0xC2,0xEA,
|
||||||
|
0x44,0x34,0x3C,0x54,0x04,0x04,0x04,0x04,0xFE,0xFE,0xFE,0xDE,0xEE,0x1E,0x0A,0x0A,
|
||||||
|
|
||||||
|
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x08,0x18,0x08,0x18,0x08,0x18,0x18,0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
// explosions
|
||||||
|
0x00,0x00,0x00,0x08,0x04,0x03,0x06,0x05,0x00,0x00,0x00,0x0C,0x06,0x04,0x00,0x18,
|
||||||
|
0x05,0x06,0x07,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x08,0x09,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x08,0x90,0xE0,0x90,0xD0,0x00,0x00,0x00,0x18,0x30,0x10,0x00,0x0C,
|
||||||
|
0xF0,0x20,0xE0,0x80,0x00,0x00,0x00,0x00,0x0C,0x10,0x18,0xC8,0x00,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x00,0x04,0x12,0x0C,0x42,0x30,0x00,0x19,0x00,0x00,0x00,0x0A,0x00,0x06,0x08,0x00,
|
||||||
|
0x11,0x04,0x0C,0x00,0x21,0x46,0x00,0x00,0x04,0x10,0x02,0x0C,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x40,0x08,0x91,0xA2,0x04,0x80,0xCC,0x00,0x00,0x00,0x20,0x00,0x30,0x08,0x00,
|
||||||
|
0xC4,0x10,0x1A,0x80,0x20,0x10,0x00,0x00,0x10,0x04,0xA0,0x98,0x80,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x61,0x20,0x00,0x04,0x00,0xC4,0x08,0x10,0x00,0x00,0x04,0x06,0x09,0x02,0x10,0x14,
|
||||||
|
0x10,0x00,0x42,0xC8,0x80,0x00,0x10,0x30,0x34,0x10,0x11,0x02,0x00,0x00,0x00,0x00,
|
||||||
|
0x86,0xC4,0x00,0x10,0x01,0x10,0x08,0x04,0x00,0x00,0x10,0x30,0x48,0x20,0x04,0x14,
|
||||||
|
0x04,0x00,0x20,0x89,0x00,0x84,0xC6,0x43,0x16,0x04,0x44,0xA0,0x00,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
0x00,0x00,0x02,0x08,0x00,0x06,0x02,0x00,0x00,0x00,0x08,0x01,0x11,0x15,0x00,0x38,
|
||||||
|
0x30,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x20,0x08,0x00,0x30,0x20,0x00,0x00,0x00,0x08,0x40,0x44,0x54,0x00,0x0E,
|
||||||
|
0x06,0x20,0x80,0x80,0x00,0x00,0x00,0x00,0x0C,0x80,0x04,0x80,0x00,0x00,0x00,0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CHAR(x) ((x)-' ')
|
||||||
|
#define BLANK 0
|
||||||
|
|
||||||
|
// VRAM UPDATE BUFFER
|
||||||
|
|
||||||
|
#define VBUFSIZE 64
|
||||||
|
byte updbuf[VBUFSIZE];
|
||||||
|
byte updptr = 0;
|
||||||
|
|
||||||
|
void cendbuf() {
|
||||||
|
updbuf[updptr] = NT_UPD_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cflushnow() {
|
||||||
|
cendbuf();
|
||||||
|
ppu_wait_nmi();
|
||||||
|
flush_vram_update(updbuf);
|
||||||
|
updptr = 0;
|
||||||
|
cendbuf();
|
||||||
|
vram_adr(0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vdelay(byte count) {
|
||||||
|
while (count--) cflushnow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void putchar(byte x, byte y, char ch) {
|
||||||
|
word addr = NTADR_A(x,y);
|
||||||
|
if (updptr >= VBUFSIZE-4) cflushnow();
|
||||||
|
updbuf[updptr++] = addr >> 8;
|
||||||
|
updbuf[updptr++] = addr & 0xff;
|
||||||
|
updbuf[updptr++] = ch;
|
||||||
|
cendbuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void putbytes(byte x, byte y, char* str, byte len) {
|
||||||
|
word addr = NTADR_A(x,y);
|
||||||
|
if (updptr >= VBUFSIZE-4-len) cflushnow();
|
||||||
|
updbuf[updptr++] = (addr >> 8) | NT_UPD_HORZ;
|
||||||
|
updbuf[updptr++] = addr & 0xff;
|
||||||
|
updbuf[updptr++] = len;
|
||||||
|
while (len--) {
|
||||||
|
updbuf[updptr++] = *str++;
|
||||||
|
}
|
||||||
|
cendbuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void putstring(byte x, byte y, char* str) {
|
||||||
|
putbytes(x, y, str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void clrscr() {
|
||||||
|
updptr = 0;
|
||||||
|
cendbuf();
|
||||||
|
ppu_off();
|
||||||
|
vram_adr(0x2000);
|
||||||
|
vram_fill(BLANK, 32*28);
|
||||||
|
vram_adr(0x0);
|
||||||
|
ppu_on_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////
|
||||||
|
|
||||||
|
char in_rect(byte x, byte y, byte x0, byte y0, byte w, byte h) {
|
||||||
|
return ((byte)(x-x0) < w && (byte)(y-y0) < h); // unsigned
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_bcd_word(byte col, byte row, word bcd) {
|
||||||
|
byte j;
|
||||||
|
static char buf[5];
|
||||||
|
buf[4] = CHAR('0');
|
||||||
|
for (j=3; j<0x80; j--) {
|
||||||
|
buf[j] = CHAR('0'+(bcd&0xf));
|
||||||
|
bcd >>= 4;
|
||||||
|
}
|
||||||
|
putbytes(col, row, buf, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
word bcd_add(word a, word b) {
|
||||||
|
word result = 0;
|
||||||
|
byte c = 0;
|
||||||
|
byte shift = 0;
|
||||||
|
while (shift < 16) {
|
||||||
|
byte d = (a & 0xf) + (b & 0xf) + c;
|
||||||
|
c = 0;
|
||||||
|
while (d >= 10) {
|
||||||
|
c++;
|
||||||
|
d -= 10;
|
||||||
|
}
|
||||||
|
result |= d << shift;
|
||||||
|
shift += 4;
|
||||||
|
a >>= 4;
|
||||||
|
b >>= 4;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GAME CODE
|
||||||
|
|
||||||
|
#define NSPRITES 16
|
||||||
|
#define NMISSILES 8
|
||||||
|
#define YOFFSCREEN 239
|
||||||
|
|
||||||
|
#define SPRI_SHIP 96
|
||||||
|
#define SPRI_MISSILE 100
|
||||||
|
#define SPRI_BOMB 104
|
||||||
|
#define SPRI_EXPLODE 112
|
||||||
|
#define SPRI_ENEMY 68
|
||||||
|
|
||||||
|
#define SSRC_FORM1 66
|
||||||
|
#define SDST_FORM1 128
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
byte shape;
|
||||||
|
} FormationEnemy;
|
||||||
|
|
||||||
|
// should be power of 2 length
|
||||||
|
typedef struct {
|
||||||
|
byte findex;
|
||||||
|
byte shape;
|
||||||
|
word x;
|
||||||
|
word y;
|
||||||
|
byte dir;
|
||||||
|
byte returning;
|
||||||
|
} AttackingEnemy;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
signed char dx;
|
||||||
|
byte xpos;
|
||||||
|
signed char dy;
|
||||||
|
byte ypos;
|
||||||
|
} Missile;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
byte name;
|
||||||
|
byte tag;
|
||||||
|
byte x;
|
||||||
|
byte y;
|
||||||
|
} Sprite;
|
||||||
|
|
||||||
|
#define ENEMIES_PER_ROW 8
|
||||||
|
#define ENEMY_ROWS 4
|
||||||
|
#define MAX_IN_FORMATION (ENEMIES_PER_ROW*ENEMY_ROWS)
|
||||||
|
#define MAX_ATTACKERS 6
|
||||||
|
|
||||||
|
FormationEnemy formation[MAX_IN_FORMATION];
|
||||||
|
AttackingEnemy attackers[MAX_ATTACKERS];
|
||||||
|
Missile missiles[NMISSILES];
|
||||||
|
Sprite vsprites[NSPRITES];
|
||||||
|
|
||||||
|
byte formation_offset_x;
|
||||||
|
signed char formation_direction;
|
||||||
|
byte current_row;
|
||||||
|
byte player_x;
|
||||||
|
const byte player_y = 190;
|
||||||
|
byte player_exploding;
|
||||||
|
byte enemy_exploding;
|
||||||
|
byte enemies_left;
|
||||||
|
word player_score;
|
||||||
|
byte framecount;
|
||||||
|
|
||||||
|
void copy_sprites() {
|
||||||
|
byte i;
|
||||||
|
byte oamid = 0;
|
||||||
|
for (i=0; i<NSPRITES; i++) {
|
||||||
|
Sprite* spr = &vsprites[i];
|
||||||
|
if (spr->y != YOFFSCREEN) {
|
||||||
|
byte y = spr->y;
|
||||||
|
byte x = spr->x;
|
||||||
|
byte chr = spr->name;
|
||||||
|
byte attr = spr->tag;
|
||||||
|
if (attr & 0x40) chr += 2; // horiz flip, swap tiles
|
||||||
|
oamid = oam_spr(x, y, chr, attr, oamid);
|
||||||
|
oamid = oam_spr(x+8, y, chr^2, attr, oamid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// copy all "shadow missiles" to video memory
|
||||||
|
for (i=0; i<NMISSILES; i++) {
|
||||||
|
Missile* mis = &missiles[i];
|
||||||
|
if (mis->ypos != YOFFSCREEN) {
|
||||||
|
oamid = oam_spr(mis->xpos, mis->ypos, SPRI_MISSILE,
|
||||||
|
(i==7)?COLOR_MISSILE:COLOR_BOMB,
|
||||||
|
oamid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oam_hide_rest(oamid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_score(word bcd) {
|
||||||
|
player_score = bcd_add(player_score, bcd);
|
||||||
|
draw_bcd_word(1, 1, player_score);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clrobjs() {
|
||||||
|
byte i;
|
||||||
|
memset(vsprites, 0, sizeof(vsprites));
|
||||||
|
for (i=0; i<NSPRITES; i++) {
|
||||||
|
vsprites[i].y = YOFFSCREEN;
|
||||||
|
}
|
||||||
|
for (i=0; i<NMISSILES; i++) {
|
||||||
|
missiles[i].ypos = YOFFSCREEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_formation() {
|
||||||
|
byte i;
|
||||||
|
memset(formation, 0, sizeof(formation));
|
||||||
|
memset(attackers, 0, sizeof(attackers));
|
||||||
|
for (i=0; i<MAX_IN_FORMATION; i++) {
|
||||||
|
byte flagship = i < ENEMIES_PER_ROW;
|
||||||
|
formation[i].shape = flagship ? SDST_FORM1 : SDST_FORM1;
|
||||||
|
}
|
||||||
|
enemies_left = MAX_IN_FORMATION;
|
||||||
|
formation_offset_x = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_row(byte row) {
|
||||||
|
static char buf[32];
|
||||||
|
byte i;
|
||||||
|
byte x = formation_offset_x / 8;
|
||||||
|
byte xd = (formation_offset_x & 7) * 3;
|
||||||
|
byte y = 3 + row * 2;
|
||||||
|
for (i=0; i<x; i++)
|
||||||
|
buf[i] = BLANK;
|
||||||
|
for (i=0; i<ENEMIES_PER_ROW; i++) {
|
||||||
|
byte shape = formation[i + row*ENEMIES_PER_ROW].shape;
|
||||||
|
if (shape) {
|
||||||
|
shape += xd;
|
||||||
|
buf[x] = shape;
|
||||||
|
buf[x+1] = shape+1;
|
||||||
|
buf[x+2] = shape+2;
|
||||||
|
} else {
|
||||||
|
buf[x] = buf[x+1] = buf[x+2] = BLANK;
|
||||||
|
}
|
||||||
|
x += 3;
|
||||||
|
}
|
||||||
|
for (; x<COLS; x++)
|
||||||
|
buf[x] = BLANK;
|
||||||
|
putbytes(0, y, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_next_row() {
|
||||||
|
draw_row(current_row);
|
||||||
|
if (++current_row == ENEMY_ROWS) {
|
||||||
|
current_row = 0;
|
||||||
|
formation_offset_x += formation_direction;
|
||||||
|
if (formation_offset_x == 63) {
|
||||||
|
formation_direction = -1;
|
||||||
|
}
|
||||||
|
else if (formation_offset_x == 8) {
|
||||||
|
formation_direction = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FLIPX 0x40
|
||||||
|
#define FLIPY 0x80
|
||||||
|
#define FLIPXY 0xc0
|
||||||
|
|
||||||
|
const byte DIR_TO_CODE[32] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 6,
|
||||||
|
6|FLIPXY, 6|FLIPXY, 5|FLIPXY, 4|FLIPXY, 3|FLIPXY, 2|FLIPXY, 1|FLIPXY, 0|FLIPXY,
|
||||||
|
0|FLIPX, 1|FLIPX, 2|FLIPX, 3|FLIPX, 4|FLIPX, 5|FLIPX, 6|FLIPX, 6|FLIPX,
|
||||||
|
6|FLIPY, 6|FLIPY, 5|FLIPY, 4|FLIPY, 3|FLIPY, 2|FLIPY, 1|FLIPY, 0|FLIPY,
|
||||||
|
};
|
||||||
|
|
||||||
|
const byte SINTBL[32] = {
|
||||||
|
0, 25, 49, 71, 90, 106, 117, 125,
|
||||||
|
127, 125, 117, 106, 90, 71, 49, 25,
|
||||||
|
0, -25, -49, -71, -90, -106, -117, -125,
|
||||||
|
-127, -125, -117, -106, -90, -71, -49, -25,
|
||||||
|
};
|
||||||
|
|
||||||
|
signed char isin(byte dir) {
|
||||||
|
return SINTBL[dir & 31];
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char icos(byte dir) {
|
||||||
|
return isin(dir+8);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FORMATION_X0 0
|
||||||
|
#define FORMATION_Y0 19
|
||||||
|
#define FORMATION_XSPACE 24
|
||||||
|
#define FORMATION_YSPACE 16
|
||||||
|
|
||||||
|
byte get_attacker_x(byte formation_index) {
|
||||||
|
byte column = (formation_index % ENEMIES_PER_ROW);
|
||||||
|
return FORMATION_XSPACE*column + FORMATION_X0 + formation_offset_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte get_attacker_y(byte formation_index) {
|
||||||
|
byte row = formation_index / ENEMIES_PER_ROW;
|
||||||
|
return FORMATION_YSPACE*row + FORMATION_Y0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_attacker(byte i) {
|
||||||
|
AttackingEnemy* a = &attackers[i];
|
||||||
|
if (a->findex) {
|
||||||
|
byte code = DIR_TO_CODE[(a->dir)&31];
|
||||||
|
vsprites[i].name = SPRI_ENEMY + (code&7)*4; // tile
|
||||||
|
vsprites[i].tag = code & 0xc0; // flip h/v
|
||||||
|
vsprites[i].x = a->x >> 8;
|
||||||
|
vsprites[i].y = a->y >> 8;
|
||||||
|
} else {
|
||||||
|
vsprites[i].y = YOFFSCREEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_attackers() {
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<MAX_ATTACKERS; i++) {
|
||||||
|
draw_attacker(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void return_attacker(AttackingEnemy* a) {
|
||||||
|
byte fi = a->findex-1;
|
||||||
|
byte destx = get_attacker_x(fi);
|
||||||
|
byte desty = get_attacker_y(fi);
|
||||||
|
byte ydist = desty - (a->y >> 8);
|
||||||
|
// are we close to our formation slot?
|
||||||
|
if (ydist == 0) {
|
||||||
|
// convert back to formation enemy
|
||||||
|
formation[fi].shape = a->shape;
|
||||||
|
a->findex = 0;
|
||||||
|
} else {
|
||||||
|
a->dir = (ydist + 16) & 31;
|
||||||
|
a->x = destx << 8;
|
||||||
|
a->y += 128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fly_attacker(AttackingEnemy* a) {
|
||||||
|
a->x += isin(a->dir) * 2;
|
||||||
|
a->y += icos(a->dir) * 2;
|
||||||
|
if ((a->y >> 8) == 0) {
|
||||||
|
a->returning = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_attackers() {
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<MAX_ATTACKERS; i++) {
|
||||||
|
AttackingEnemy* a = &attackers[i];
|
||||||
|
if (a->findex) {
|
||||||
|
if (a->returning)
|
||||||
|
return_attacker(a);
|
||||||
|
else
|
||||||
|
fly_attacker(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void think_attackers() {
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<MAX_ATTACKERS; i++) {
|
||||||
|
AttackingEnemy* a = &attackers[i];
|
||||||
|
if (a->findex) {
|
||||||
|
// rotate?
|
||||||
|
byte x = a->x >> 8;
|
||||||
|
byte y = a->y >> 8;
|
||||||
|
// don't shoot missiles after player exploded
|
||||||
|
if (y < 112 || player_exploding) {
|
||||||
|
if (x < 128) {
|
||||||
|
a->dir++;
|
||||||
|
} else {
|
||||||
|
a->dir--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// lower half of screen
|
||||||
|
// shoot a missile?
|
||||||
|
if (missiles[i].ypos == YOFFSCREEN) {
|
||||||
|
missiles[i].ypos = y+16;
|
||||||
|
missiles[i].xpos = x;
|
||||||
|
missiles[i].dy = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void formation_to_attacker(byte formation_index) {
|
||||||
|
byte i;
|
||||||
|
// out of bounds? return
|
||||||
|
if (formation_index >= MAX_IN_FORMATION)
|
||||||
|
return;
|
||||||
|
// nobody in formation? return
|
||||||
|
if (!formation[formation_index].shape)
|
||||||
|
return;
|
||||||
|
// find an empty attacker slot
|
||||||
|
for (i=0; i<MAX_ATTACKERS; i++) {
|
||||||
|
AttackingEnemy* a = &attackers[i];
|
||||||
|
if (a->findex == 0) {
|
||||||
|
a->x = get_attacker_x(formation_index) << 8;
|
||||||
|
a->y = get_attacker_y(formation_index) << 8;
|
||||||
|
a->shape = formation[formation_index].shape;
|
||||||
|
a->findex = formation_index+1;
|
||||||
|
a->dir = 0;
|
||||||
|
a->returning = 0;
|
||||||
|
formation[formation_index].shape = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_player() {
|
||||||
|
vsprites[7].x = player_x;
|
||||||
|
vsprites[7].y = player_y;
|
||||||
|
vsprites[7].name = SPRI_SHIP;
|
||||||
|
vsprites[7].tag = COLOR_PLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_player() {
|
||||||
|
byte joy = joy_read(JOY_1);
|
||||||
|
// move left/right?
|
||||||
|
if ((joy & JOY_LEFT_MASK) && player_x > 16) player_x--;
|
||||||
|
if ((joy & JOY_RIGHT_MASK) && player_x < 224) player_x++;
|
||||||
|
// shoot missile?
|
||||||
|
if ((joy & JOY_BTN_A_MASK) && missiles[7].ypos == YOFFSCREEN) {
|
||||||
|
missiles[7].ypos = player_y-8; // must be multiple of missile speed
|
||||||
|
missiles[7].xpos = player_x; // player X position
|
||||||
|
missiles[7].dy = -4; // player missile speed
|
||||||
|
}
|
||||||
|
vsprites[7].x = player_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_missiles() {
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
if (missiles[i].ypos != YOFFSCREEN) {
|
||||||
|
// hit the bottom or top?
|
||||||
|
if ((byte)(missiles[i].ypos += missiles[i].dy) > YOFFSCREEN) {
|
||||||
|
missiles[i].ypos = YOFFSCREEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void blowup_at(byte x, byte y) {
|
||||||
|
vsprites[6].tag = COLOR_EXPLOSION;
|
||||||
|
vsprites[6].name = SPRI_EXPLODE; // TODO
|
||||||
|
vsprites[6].x = x;
|
||||||
|
vsprites[6].y = y;
|
||||||
|
enemy_exploding = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void animate_enemy_explosion() {
|
||||||
|
if (enemy_exploding) {
|
||||||
|
// animate next frame
|
||||||
|
if (enemy_exploding >= 8) {
|
||||||
|
enemy_exploding = 0; // hide explosion after 4 frames
|
||||||
|
vsprites[6].y = YOFFSCREEN;
|
||||||
|
} else {
|
||||||
|
vsprites[6].name = SPRI_EXPLODE + (enemy_exploding += 4); // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void animate_player_explosion() {
|
||||||
|
byte z = player_exploding;
|
||||||
|
if (z <= 3) {
|
||||||
|
if (z == 3) {
|
||||||
|
vsprites[7].y = YOFFSCREEN;
|
||||||
|
} else {
|
||||||
|
vsprites[7].name = SPRI_EXPLODE + z*4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hide_player_missile() {
|
||||||
|
missiles[7].ypos = YOFFSCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void does_player_shoot_formation() {
|
||||||
|
byte mx = missiles[7].xpos + 8;
|
||||||
|
byte my = missiles[7].ypos;
|
||||||
|
signed char row = (my - FORMATION_Y0) / FORMATION_YSPACE;
|
||||||
|
if (row >= 0 && row < ENEMY_ROWS) {
|
||||||
|
// ok if unsigned (in fact, must be due to range)
|
||||||
|
byte xoffset = mx - FORMATION_X0 - formation_offset_x;
|
||||||
|
byte column = xoffset / FORMATION_XSPACE;
|
||||||
|
byte localx = xoffset - column * FORMATION_XSPACE;
|
||||||
|
if (column < ENEMIES_PER_ROW && localx < 16) {
|
||||||
|
char index = column + row * ENEMIES_PER_ROW;
|
||||||
|
if (formation[index].shape) {
|
||||||
|
formation[index].shape = 0;
|
||||||
|
enemies_left--;
|
||||||
|
blowup_at(get_attacker_x(index), get_attacker_y(index));
|
||||||
|
hide_player_missile();
|
||||||
|
add_score(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void does_player_shoot_attacker() {
|
||||||
|
byte mx = missiles[7].xpos + 8;
|
||||||
|
byte my = missiles[7].ypos;
|
||||||
|
byte i;
|
||||||
|
for (i=0; i<MAX_ATTACKERS; i++) {
|
||||||
|
AttackingEnemy* a = &attackers[i];
|
||||||
|
if (a->findex && in_rect(mx, my, a->x >> 8, a->y >> 8, 16, 16)) {
|
||||||
|
blowup_at(a->x >> 8, a->y >> 8);
|
||||||
|
a->findex = 0;
|
||||||
|
enemies_left--;
|
||||||
|
hide_player_missile();
|
||||||
|
add_score(5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void does_missile_hit_player() {
|
||||||
|
byte i;
|
||||||
|
if (player_exploding)
|
||||||
|
return;
|
||||||
|
for (i=0; i<MAX_ATTACKERS; i++) {
|
||||||
|
if (missiles[i].ypos != YOFFSCREEN &&
|
||||||
|
in_rect(missiles[i].xpos + 8, missiles[i].ypos + 16,
|
||||||
|
player_x, player_y, 16, 16)) {
|
||||||
|
player_exploding = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void new_attack_wave() {
|
||||||
|
byte i = rand();
|
||||||
|
byte j;
|
||||||
|
// find a random slot that has an enemy
|
||||||
|
for (j=0; j<MAX_IN_FORMATION; j++) {
|
||||||
|
i = (i+1) & (MAX_IN_FORMATION-1);
|
||||||
|
// anyone there?
|
||||||
|
if (formation[i].shape) {
|
||||||
|
formation_to_attacker(i);
|
||||||
|
formation_to_attacker(i+1);
|
||||||
|
formation_to_attacker(i+ENEMIES_PER_ROW);
|
||||||
|
formation_to_attacker(i+ENEMIES_PER_ROW+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void new_player_ship() {
|
||||||
|
player_exploding = 0;
|
||||||
|
player_x = 120;
|
||||||
|
draw_player();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_sounds() {
|
||||||
|
/*
|
||||||
|
byte i;
|
||||||
|
// missile fire sound
|
||||||
|
if (missiles[7].ypos != YOFFSCREEN) {
|
||||||
|
cv_set_frequency(CV_SOUNDCHANNEL_0, 2000-missiles[7].ypos*4);
|
||||||
|
cv_set_attenuation(CV_SOUNDCHANNEL_0, 18);
|
||||||
|
} else {
|
||||||
|
cv_set_attenuation(CV_SOUNDCHANNEL_0, 32);
|
||||||
|
}
|
||||||
|
// enemy explosion sound
|
||||||
|
if (enemy_exploding) {
|
||||||
|
cv_set_frequency(CV_SOUNDCHANNEL_1, 500+enemy_exploding*64);
|
||||||
|
cv_set_attenuation(CV_SOUNDCHANNEL_1, 14);
|
||||||
|
} else {
|
||||||
|
cv_set_attenuation(CV_SOUNDCHANNEL_1, 32);
|
||||||
|
}
|
||||||
|
cv_set_attenuation(CV_SOUNDCHANNEL_2, 32);
|
||||||
|
// player explosion
|
||||||
|
if (player_exploding && player_exploding < 15) {
|
||||||
|
cv_set_frequency(CV_SOUNDCHANNEL_2, player_exploding*256);
|
||||||
|
cv_set_attenuation(CV_SOUNDCHANNEL_NOISE, 4+player_exploding);
|
||||||
|
cv_set_noise(true, 3);
|
||||||
|
} else {
|
||||||
|
// set diving sounds for spaceships
|
||||||
|
cv_set_attenuation(CV_SOUNDCHANNEL_NOISE, 32);
|
||||||
|
for (i=0; i<3; i++) {
|
||||||
|
byte y = attackers[i].y >> 8;
|
||||||
|
if (y >= 0x80) {
|
||||||
|
cv_set_frequency(CV_SOUNDCHANNEL_2, 4000+y*8);
|
||||||
|
cv_set_attenuation(CV_SOUNDCHANNEL_2, 28);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_for_frame() {
|
||||||
|
ppu_wait_nmi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void play_round() {
|
||||||
|
byte end_timer = 255;
|
||||||
|
player_score = 0;
|
||||||
|
add_score(0);
|
||||||
|
putstring(0, 0, "PLAYER 1");
|
||||||
|
setup_formation();
|
||||||
|
clrobjs();
|
||||||
|
formation_direction = 1;
|
||||||
|
framecount = 0;
|
||||||
|
new_player_ship();
|
||||||
|
while (end_timer) {
|
||||||
|
if (player_exploding) {
|
||||||
|
if ((framecount & 7) == 1) {
|
||||||
|
animate_player_explosion();
|
||||||
|
if (++player_exploding > 32 && enemies_left) {
|
||||||
|
new_player_ship();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((framecount & 0x7f) == 0 || enemies_left < 8) {
|
||||||
|
new_attack_wave();
|
||||||
|
}
|
||||||
|
move_player();
|
||||||
|
does_missile_hit_player();
|
||||||
|
}
|
||||||
|
if ((framecount & 3) == 2) animate_enemy_explosion();
|
||||||
|
move_attackers();
|
||||||
|
move_missiles();
|
||||||
|
if (framecount & 1)
|
||||||
|
does_player_shoot_formation();
|
||||||
|
else
|
||||||
|
does_player_shoot_attacker();
|
||||||
|
draw_next_row();
|
||||||
|
draw_attackers();
|
||||||
|
if ((framecount & 0xf) == 0) think_attackers();
|
||||||
|
set_sounds();
|
||||||
|
framecount++;
|
||||||
|
if (!enemies_left) end_timer--;
|
||||||
|
cflushnow();
|
||||||
|
copy_sprites();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_shifted_pattern(const byte* src, word dest, byte shift) {
|
||||||
|
static byte buf[16*3];
|
||||||
|
byte y;
|
||||||
|
for (y=0; y<16; y++) {
|
||||||
|
byte a = src[y];
|
||||||
|
byte b = src[y+16];
|
||||||
|
buf[y] = a>>shift;
|
||||||
|
buf[y+16] = b>>shift | a<<(8-shift);
|
||||||
|
buf[y+32] = b<<(8-shift);
|
||||||
|
}
|
||||||
|
vram_adr(dest);
|
||||||
|
vram_write(buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_tileset() {
|
||||||
|
byte i;
|
||||||
|
word src;
|
||||||
|
word dest;
|
||||||
|
// copy background
|
||||||
|
vram_adr(0x0);
|
||||||
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
|
// copy sprites
|
||||||
|
vram_adr(0x1000);
|
||||||
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
|
// write shifted versions of formation ships
|
||||||
|
src = SSRC_FORM1*16;
|
||||||
|
dest = SDST_FORM1*16;
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
set_shifted_pattern(&TILESET[src], dest, i);
|
||||||
|
dest += 3*16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
joy_install (joy_static_stddrv);
|
||||||
|
setup_tileset();
|
||||||
|
pal_all(PALETTE);
|
||||||
|
oam_clear();
|
||||||
|
oam_size(1); // 8x16 sprites
|
||||||
|
clrscr();
|
||||||
|
play_round();
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
|
|
@ -1,21 +1,28 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <conio.h>
|
|
||||||
#include <nes.h>
|
#include <nes.h>
|
||||||
#include <joystick.h>
|
#include <joystick.h>
|
||||||
|
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
|
||||||
|
#pragma bss-name (push,"ZEROPAGE")
|
||||||
|
unsigned char oam_off;
|
||||||
|
#pragma bss-name (pop)
|
||||||
|
|
||||||
|
#pragma data-name (push,"CHARS")
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
//#link "tileset1.c"
|
//#link "tileset1.c"
|
||||||
|
|
||||||
extern unsigned char palSprites[16];
|
extern unsigned char palSprites[16];
|
||||||
extern unsigned char TILESET[8*256];
|
extern unsigned char TILESET[8*256];
|
||||||
|
|
||||||
|
|
||||||
#define COLS 32
|
#define COLS 32
|
||||||
#define ROWS 28
|
#define ROWS 28
|
||||||
|
|
||||||
|
#define NTADR(x,y) ((0x2000|((y)<<5)|(x)))
|
||||||
|
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
typedef signed char sbyte;
|
typedef signed char sbyte;
|
||||||
typedef unsigned short word;
|
typedef unsigned short word;
|
||||||
|
@ -27,25 +34,68 @@ typedef unsigned short word;
|
||||||
// back to the start of the frame.
|
// back to the start of the frame.
|
||||||
byte getchar(byte x, byte y) {
|
byte getchar(byte x, byte y) {
|
||||||
// compute VRAM read address
|
// compute VRAM read address
|
||||||
word addr = 0x2020+x+y*32;
|
word addr = NTADR(x,y);
|
||||||
byte rd;
|
byte rd;
|
||||||
// wait for VBLANK to start
|
// wait for VBLANK to start
|
||||||
waitvsync();
|
waitvsync();
|
||||||
// set VRAM read address in PPU
|
vram_adr(addr);
|
||||||
PPU.vram.address = addr>>8;
|
vram_read(&rd, 1);
|
||||||
PPU.vram.address = addr&0xff;
|
vram_adr(0x0);
|
||||||
// read the char from PPUDATA
|
return rd + 0x20;
|
||||||
rd = PPU.vram.data; // discard
|
}
|
||||||
rd = PPU.vram.data; // keep this one
|
|
||||||
// reset the VRAM address to start of frame
|
// VRAM UPDATE BUFFER
|
||||||
PPU.vram.address = 0x00;
|
|
||||||
PPU.vram.address = 0x00;
|
byte updbuf[64];
|
||||||
// return result
|
byte updptr = 0;
|
||||||
return rd;
|
|
||||||
|
void cendbuf() {
|
||||||
|
updbuf[updptr] = NT_UPD_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cflushnow() {
|
||||||
|
cendbuf();
|
||||||
|
waitvsync();
|
||||||
|
flush_vram_update(updbuf);
|
||||||
|
updptr = 0;
|
||||||
|
cendbuf();
|
||||||
|
vram_adr(0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vdelay(byte count) {
|
void vdelay(byte count) {
|
||||||
while (count--) waitvsync();
|
while (count--) cflushnow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cputcxy(byte x, byte y, char ch) {
|
||||||
|
word addr = NTADR(x,y);
|
||||||
|
if (updptr >= 60) cflushnow();
|
||||||
|
updbuf[updptr++] = addr >> 8;
|
||||||
|
updbuf[updptr++] = addr & 0xff;
|
||||||
|
updbuf[updptr++] = ch - 0x20;
|
||||||
|
cendbuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cputsxy(byte x, byte y, char* str) {
|
||||||
|
word addr = NTADR(x,y);
|
||||||
|
byte len = strlen(str);
|
||||||
|
if (updptr >= 60 - len) cflushnow();
|
||||||
|
updbuf[updptr++] = (addr >> 8) | NT_UPD_HORZ;
|
||||||
|
updbuf[updptr++] = addr & 0xff;
|
||||||
|
updbuf[updptr++] = len;
|
||||||
|
while (len--) {
|
||||||
|
updbuf[updptr++] = *str++ - 0x20;
|
||||||
|
}
|
||||||
|
cendbuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clrscr() {
|
||||||
|
updptr = 0;
|
||||||
|
cendbuf();
|
||||||
|
ppu_off();
|
||||||
|
vram_adr(0x2000);
|
||||||
|
vram_fill(0, 32*28);
|
||||||
|
vram_adr(0x0);
|
||||||
|
ppu_on_bg();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////// GAME DATA
|
////////// GAME DATA
|
||||||
|
@ -63,7 +113,8 @@ typedef struct {
|
||||||
|
|
||||||
Player players[2];
|
Player players[2];
|
||||||
|
|
||||||
byte credits = 0;
|
byte attract;
|
||||||
|
byte gameover;
|
||||||
byte frames_per_move;
|
byte frames_per_move;
|
||||||
|
|
||||||
#define START_SPEED 12
|
#define START_SPEED 12
|
||||||
|
@ -72,7 +123,7 @@ byte frames_per_move;
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
|
|
||||||
const char BOX_CHARS[8] = { 17, 8, 20, 18, 11, 11, 14, 14 };
|
const char BOX_CHARS[8] = { '+','+','+','+','-','-','!','!' };
|
||||||
|
|
||||||
void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) {
|
void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) {
|
||||||
byte x1 = x;
|
byte x1 = x;
|
||||||
|
@ -91,11 +142,15 @@ void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_playfield() {
|
void draw_playfield() {
|
||||||
draw_box(0,1,COLS-1,ROWS-1,BOX_CHARS);
|
draw_box(1,2,COLS-2,ROWS-1,BOX_CHARS);
|
||||||
cputsxy(0,0,"Plyr1:");
|
cputcxy(9,1,players[0].score+'0');
|
||||||
cputsxy(20,0,"Plyr2:");
|
cputcxy(28,1,players[1].score+'0');
|
||||||
cputcxy(7,0,players[0].score+'0');
|
if (attract) {
|
||||||
cputcxy(27,0,players[1].score+'0');
|
cputsxy(5,ROWS-1,"ATTRACT MODE - PRESS 1");
|
||||||
|
} else {
|
||||||
|
cputsxy(1,1,"PLYR1:");
|
||||||
|
cputsxy(20,1,"PLYR2:");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } dir_t;
|
typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } dir_t;
|
||||||
|
@ -106,8 +161,8 @@ void init_game() {
|
||||||
memset(players, 0, sizeof(players));
|
memset(players, 0, sizeof(players));
|
||||||
players[0].head_attr = '1';
|
players[0].head_attr = '1';
|
||||||
players[1].head_attr = '2';
|
players[1].head_attr = '2';
|
||||||
players[0].tail_attr = 1;
|
players[0].tail_attr = '#';
|
||||||
players[1].tail_attr = 9;
|
players[1].tail_attr = '*';
|
||||||
frames_per_move = START_SPEED;
|
frames_per_move = START_SPEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +191,12 @@ void move_player(Player* p) {
|
||||||
void human_control(Player* p) {
|
void human_control(Player* p) {
|
||||||
byte dir = 0xff;
|
byte dir = 0xff;
|
||||||
byte joy;
|
byte joy;
|
||||||
if (!p->human) return;
|
|
||||||
joy = joy_read (JOY_1);
|
joy = joy_read (JOY_1);
|
||||||
|
// start game if attract mode
|
||||||
|
if (attract && (joy & JOY_START_MASK))
|
||||||
|
gameover = 1;
|
||||||
|
// do not allow movement unless human player
|
||||||
|
if (!p->human) return;
|
||||||
if (joy & JOY_LEFT_MASK) dir = D_LEFT;
|
if (joy & JOY_LEFT_MASK) dir = D_LEFT;
|
||||||
if (joy & JOY_RIGHT_MASK) dir = D_RIGHT;
|
if (joy & JOY_RIGHT_MASK) dir = D_RIGHT;
|
||||||
if (joy & JOY_UP_MASK) dir = D_UP;
|
if (joy & JOY_UP_MASK) dir = D_UP;
|
||||||
|
@ -175,8 +234,6 @@ void ai_control(Player* p) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte gameover;
|
|
||||||
|
|
||||||
void flash_colliders() {
|
void flash_colliders() {
|
||||||
byte i;
|
byte i;
|
||||||
// flash players that collided
|
// flash players that collided
|
||||||
|
@ -219,13 +276,13 @@ void declare_winner(byte winner) {
|
||||||
gameover = 1;
|
gameover = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define AE(a,b,c,d) (((a)<<0)|((b)<<2)|((c)<<4)|((d)<<6))
|
#define AE(tl,tr,bl,br) (((tl)<<0)|((tr)<<2)|((bl)<<4)|((br)<<6))
|
||||||
|
|
||||||
// this is attribute table data,
|
// this is attribute table data,
|
||||||
// each 2 bits defines a color palette
|
// each 2 bits defines a color palette
|
||||||
// for a 16x16 box
|
// for a 16x16 box
|
||||||
const unsigned char Attrib_Table[0x40]={
|
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(3,3,1,0),AE(3,3,0,0),AE(3,3,0,0),AE(3,3,0,0), AE(2,2,0,0),AE(2,2,0,0),AE(2,2,0,0),AE(2,2,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,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),
|
||||||
|
@ -235,24 +292,37 @@ 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,
|
||||||
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),
|
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),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this is palette data
|
||||||
|
const unsigned char Palette_Table[16]={
|
||||||
|
0x02,
|
||||||
|
0x31,0x31,0x31,0x00,
|
||||||
|
0x34,0x34,0x34,0x00,
|
||||||
|
0x39,0x39,0x39,0x00,
|
||||||
|
};
|
||||||
|
|
||||||
// put 8x8 grid of palette entries into the PPU
|
// put 8x8 grid of palette entries into the PPU
|
||||||
void setup_attrib_table() {
|
void setup_attrib_table() {
|
||||||
byte index;
|
vram_adr(0x23c0);
|
||||||
waitvsync(); // wait for VBLANK
|
vram_write(Attrib_Table, 0x40);
|
||||||
PPU.vram.address = 0x23;
|
}
|
||||||
PPU.vram.address = 0xc0;
|
|
||||||
for( index = 0; index < 0x40; ++index ){
|
void setup_palette() {
|
||||||
PPU.vram.data = Attrib_Table[index];
|
int i;
|
||||||
}
|
// only set palette entries 0-15 (background only)
|
||||||
|
for (i=0; i<15; i++)
|
||||||
|
pal_col(i, Palette_Table[i] ^ attract);
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_round() {
|
void play_round() {
|
||||||
reset_players();
|
ppu_off();
|
||||||
clrscr();
|
|
||||||
setup_attrib_table();
|
setup_attrib_table();
|
||||||
|
setup_palette();
|
||||||
|
clrscr();
|
||||||
draw_playfield();
|
draw_playfield();
|
||||||
|
reset_players();
|
||||||
while (1) {
|
while (1) {
|
||||||
make_move();
|
make_move();
|
||||||
|
if (gameover) return; // attract mode -> start
|
||||||
if (players[0].collided || players[1].collided) break;
|
if (players[0].collided || players[1].collided) break;
|
||||||
}
|
}
|
||||||
flash_colliders();
|
flash_colliders();
|
||||||
|
@ -273,14 +343,21 @@ void play_round() {
|
||||||
void play_game() {
|
void play_game() {
|
||||||
gameover = 0;
|
gameover = 0;
|
||||||
init_game();
|
init_game();
|
||||||
players[0].human = 1;
|
if (!attract)
|
||||||
|
players[0].human = 1;
|
||||||
while (!gameover) {
|
while (!gameover) {
|
||||||
play_round();
|
play_round();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vram_write((unsigned char*)TILESET, 0x0, sizeof(TILESET));
|
vram_adr(0x0);
|
||||||
|
vram_write((unsigned char*)TILESET, sizeof(TILESET));
|
||||||
joy_install (joy_static_stddrv);
|
joy_install (joy_static_stddrv);
|
||||||
play_game();
|
while (1) {
|
||||||
|
attract = 1;
|
||||||
|
play_game();
|
||||||
|
attract = 0;
|
||||||
|
play_game();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
46
presets/nes/skeleton.dasm
Normal file
46
presets/nes/skeleton.dasm
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
include "nesdefs.asm"
|
||||||
|
|
||||||
|
;;;;; VARIABLES
|
||||||
|
|
||||||
|
seg.u RAM
|
||||||
|
org $0
|
||||||
|
|
||||||
|
;;;;; NES CARTRIDGE HEADER
|
||||||
|
|
||||||
|
NES_HEADER 0,2,1,0 ; mapper 0, 2 PRGs, 1 CHR, vertical
|
||||||
|
|
||||||
|
;;;;; START OF CODE
|
||||||
|
|
||||||
|
Start:
|
||||||
|
NES_INIT ; set up stack pointer, turn off PPU
|
||||||
|
jsr WaitSync ; wait for VSYNC
|
||||||
|
jsr ClearRAM ; clear RAM
|
||||||
|
jsr WaitSync ; wait for VSYNC (and PPU warmup)
|
||||||
|
|
||||||
|
lda #$3f ; $3F -> A register
|
||||||
|
ldy #$00 ; $00 -> Y register
|
||||||
|
sta PPU_ADDR ; write high byte first
|
||||||
|
sty PPU_ADDR ; $3F00 -> PPU address
|
||||||
|
lda #$1c ; $1C = light blue color
|
||||||
|
sta PPU_DATA ; $1C -> PPU data
|
||||||
|
lda #CTRL_NMI
|
||||||
|
sta PPU_CTRL ; enable NMI
|
||||||
|
lda #MASK_COLOR
|
||||||
|
sta PPU_MASK ; enable rendering
|
||||||
|
.endless
|
||||||
|
jmp .endless ; endless loop
|
||||||
|
|
||||||
|
;;;;; COMMON SUBROUTINES
|
||||||
|
|
||||||
|
include "nesppu.asm"
|
||||||
|
|
||||||
|
;;;;; INTERRUPT HANDLERS
|
||||||
|
|
||||||
|
NMIHandler:
|
||||||
|
rti
|
||||||
|
|
||||||
|
;;;;; CPU VECTORS
|
||||||
|
|
||||||
|
NES_VECTORS
|
||||||
|
|
135
presets/vicdual/asmtest.s
Normal file
135
presets/vicdual/asmtest.s
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
.area _HOME
|
||||||
|
.area _CODE
|
||||||
|
.area _INITIALIZER
|
||||||
|
.area _DATA
|
||||||
|
.area _INITIALIZED
|
||||||
|
.area _BSEG
|
||||||
|
.area _BSS
|
||||||
|
.area _HEAP
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; File Created by SDCC : free open source ANSI-C Compiler
|
||||||
|
; Version 3.6.5 # (UNIX)
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.module minimal
|
||||||
|
.optsdcc -mz80
|
||||||
|
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; Public variables in this module
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.globl _start
|
||||||
|
.globl _tileram
|
||||||
|
.globl _cellram
|
||||||
|
.globl _main
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; special function registers
|
||||||
|
;--------------------------------------------------------
|
||||||
|
_palette = 0x0040
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; ram data
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.area _DATA
|
||||||
|
_cellram = 0xe000
|
||||||
|
_tileram = 0xe800
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; ram data
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.area _INITIALIZED
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; absolute external ram data
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.area _DABS (ABS)
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; global & static initialisations
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.area _HOME
|
||||||
|
.area _GSINIT
|
||||||
|
.area _GSFINAL
|
||||||
|
.area _GSINIT
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; Home
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.area _HOME
|
||||||
|
.area _HOME
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; code
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.area _CODE
|
||||||
|
;<stdin>:15:
|
||||||
|
; ---------------------------------
|
||||||
|
; Function start
|
||||||
|
; ---------------------------------
|
||||||
|
_start::
|
||||||
|
;<stdin>:19:
|
||||||
|
LD SP,#0xE800 ; set up stack pointer
|
||||||
|
DI ; disable interrupts
|
||||||
|
;<stdin>:20:
|
||||||
|
jp _main
|
||||||
|
;<stdin>:23:
|
||||||
|
; ---------------------------------
|
||||||
|
; Function main
|
||||||
|
; ---------------------------------
|
||||||
|
_main::
|
||||||
|
;<stdin>:26:
|
||||||
|
ld a,#0x01
|
||||||
|
out (_palette),a
|
||||||
|
;<stdin>:27:
|
||||||
|
ld hl,#_tileram
|
||||||
|
ld (hl), #0xfe
|
||||||
|
ld e, l
|
||||||
|
ld d, h
|
||||||
|
inc de
|
||||||
|
ld bc, #0x07ff
|
||||||
|
ldir
|
||||||
|
;<stdin>:28:
|
||||||
|
ld hl,#_cellram
|
||||||
|
ld (hl), #0x00
|
||||||
|
ld e, l
|
||||||
|
ld d, h
|
||||||
|
inc de
|
||||||
|
ld bc, #0x07ff
|
||||||
|
ldir
|
||||||
|
;<stdin>:29:
|
||||||
|
ld c,#0x00
|
||||||
|
;<stdin>:30:
|
||||||
|
00112$:
|
||||||
|
ld a,c
|
||||||
|
rlca
|
||||||
|
rlca
|
||||||
|
rlca
|
||||||
|
and a,#0xf8
|
||||||
|
ld e,a
|
||||||
|
ld d,#0x00
|
||||||
|
00106$:
|
||||||
|
;<stdin>:31:
|
||||||
|
ld l,d
|
||||||
|
ld h,#0x00
|
||||||
|
add hl, hl
|
||||||
|
add hl, hl
|
||||||
|
add hl, hl
|
||||||
|
add hl, hl
|
||||||
|
add hl, hl
|
||||||
|
ld a,#<(_cellram)
|
||||||
|
add a, l
|
||||||
|
ld l,a
|
||||||
|
ld a,#>(_cellram)
|
||||||
|
adc a, h
|
||||||
|
ld h,a
|
||||||
|
ld b,#0x00
|
||||||
|
add hl, bc
|
||||||
|
ld (hl),e
|
||||||
|
;<stdin>:30:
|
||||||
|
inc d
|
||||||
|
ld a,d
|
||||||
|
sub a, #0x20
|
||||||
|
jr C,00106$
|
||||||
|
;<stdin>:29:
|
||||||
|
inc c
|
||||||
|
ld a,c
|
||||||
|
sub a, #0x20
|
||||||
|
jr C,00112$
|
||||||
|
;<stdin>:34:
|
||||||
|
00104$:
|
||||||
|
jr 00104$
|
||||||
|
.area _CODE
|
||||||
|
.area _INITIALIZER
|
||||||
|
.area _CABS (ABS)
|
|
@ -332,6 +332,7 @@ function convertBytesToImages(bytes, fmt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertImagesToBytes(images, fmt) {
|
function convertImagesToBytes(images, fmt) {
|
||||||
|
if (fmt.destfmt) fmt = fmt.destfmt;
|
||||||
var width = fmt.w;
|
var width = fmt.w;
|
||||||
var height = fmt.h;
|
var height = fmt.h;
|
||||||
var count = fmt.count || 1;
|
var count = fmt.count || 1;
|
||||||
|
|
|
@ -12,6 +12,7 @@ var JSNES_PRESETS = [
|
||||||
{id:'neslib4.c', name:'Metasprites'},
|
{id:'neslib4.c', name:'Metasprites'},
|
||||||
{id:'neslib5.c', name:'RLE Unpack'},
|
{id:'neslib5.c', name:'RLE Unpack'},
|
||||||
{id:'siegegame.c', name:'Siege Game'},
|
{id:'siegegame.c', name:'Siege Game'},
|
||||||
|
{id:'shoot2.c', name:'Solarian Game'},
|
||||||
];
|
];
|
||||||
|
|
||||||
var NES_NESLIB_PRESETS = [
|
var NES_NESLIB_PRESETS = [
|
||||||
|
|
|
@ -92,9 +92,10 @@ export class CodeProject {
|
||||||
var linkfiles = this.parseLinkDependencies(text);
|
var linkfiles = this.parseLinkDependencies(text);
|
||||||
var allfiles = includes.concat(linkfiles);
|
var allfiles = includes.concat(linkfiles);
|
||||||
this.loadFiles(allfiles, (err:string, result?:Dependency[]) => {
|
this.loadFiles(allfiles, (err:string, result?:Dependency[]) => {
|
||||||
|
// set 'link' property on files that are link dependencies (must match filename)
|
||||||
if (result)
|
if (result)
|
||||||
for (var dep of result)
|
for (var dep of result)
|
||||||
dep.link = linkfiles.indexOf(dep.filename) >= 0;
|
dep.link = linkfiles.indexOf(dep.filename) >= 0 || linkfiles.indexOf('local/'+dep.filename) >= 0; //TODO!!!
|
||||||
callback(err, result);
|
callback(err, result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
14
src/views.ts
14
src/views.ts
|
@ -184,6 +184,7 @@ export class SourceEditor implements ProjectView {
|
||||||
var insnstr = info.insns.length > 9 ? ("...") : info.insns;
|
var insnstr = info.insns.length > 9 ? ("...") : info.insns;
|
||||||
this.setGutter("gutter-bytes", info.line-1, insnstr);
|
this.setGutter("gutter-bytes", info.line-1, insnstr);
|
||||||
if (info.iscode) {
|
if (info.iscode) {
|
||||||
|
// TODO: labels trick this part?
|
||||||
var opcode = parseInt(info.insns.split(" ")[0], 16);
|
var opcode = parseInt(info.insns.split(" ")[0], 16);
|
||||||
if (platform.getOpcodeMetadata) {
|
if (platform.getOpcodeMetadata) {
|
||||||
var meta = platform.getOpcodeMetadata(opcode, info.offset);
|
var meta = platform.getOpcodeMetadata(opcode, info.offset);
|
||||||
|
@ -415,7 +416,18 @@ export class DisassemblerView implements ProjectView {
|
||||||
bytes += hex(platform.readAddress(a+i));
|
bytes += hex(platform.readAddress(a+i));
|
||||||
while (bytes.length < 14)
|
while (bytes.length < 14)
|
||||||
bytes += ' ';
|
bytes += ' ';
|
||||||
var dline = hex(parseInt(a)) + "\t" + bytes + "\t" + disasm.line + "\n";
|
var dstr = disasm.line;
|
||||||
|
if (addr2symbol) {
|
||||||
|
dstr = dstr.replace(/([^#])[$]([0-9A-F]+)/, (substr:string, ...args:any[]):string => {
|
||||||
|
var addr = parseInt(args[1], 16);
|
||||||
|
var sym = addr2symbol[addr];
|
||||||
|
if (sym) return (args[0] + sym);
|
||||||
|
sym = addr2symbol[addr+1];
|
||||||
|
if (sym) return (args[0] + sym + "+1");
|
||||||
|
return substr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var dline = hex(parseInt(a)) + "\t" + bytes + "\t" + dstr + "\n";
|
||||||
s += dline;
|
s += dline;
|
||||||
if (a == pc) selline = curline;
|
if (a == pc) selline = curline;
|
||||||
curline++;
|
curline++;
|
||||||
|
|
BIN
src/worker/lib/nes/crt0.o
Normal file
BIN
src/worker/lib/nes/crt0.o
Normal file
Binary file not shown.
|
@ -105,7 +105,13 @@ var PLATFORM_PARAMS = {
|
||||||
'nes': { //TODO
|
'nes': { //TODO
|
||||||
define: '__NES__',
|
define: '__NES__',
|
||||||
cfgfile: 'neslib.cfg',
|
cfgfile: 'neslib.cfg',
|
||||||
libargs: ['neslib.lib', 'nes.lib'],
|
libargs: ['crt0.o', 'nes.lib',
|
||||||
|
'-D', 'NES_MAPPER=0',
|
||||||
|
'-D', 'NES_PRG_BANKS=2',
|
||||||
|
'-D', 'NES_CHR_BANKS=0', // TODO: >0 doesn't seem to work
|
||||||
|
'-D', 'NES_MIRRORING=0',
|
||||||
|
],
|
||||||
|
extrafiles: ['crt0.o'],
|
||||||
},
|
},
|
||||||
'nes-conio': {
|
'nes-conio': {
|
||||||
cfgfile: 'nes.cfg',
|
cfgfile: 'nes.cfg',
|
||||||
|
@ -247,6 +253,28 @@ function populateFiles(step, fs, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function populateExtraFiles(step, fs) {
|
||||||
|
// TODO: cache extra files
|
||||||
|
var extrafiles = step.params.extrafiles;
|
||||||
|
if (extrafiles) {
|
||||||
|
for (var i=0; i<extrafiles.length; i++) {
|
||||||
|
var xfn = extrafiles[i];
|
||||||
|
var xpath = "lib/" + step.platform + "/" + xfn;
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.responseType = 'arraybuffer';
|
||||||
|
xhr.open("GET", xpath, false); // synchronous request
|
||||||
|
xhr.send(null);
|
||||||
|
if (xhr.response && xhr.status == 200) {
|
||||||
|
var data = new Uint8Array(xhr.response);
|
||||||
|
fs.writeFile(xfn, data, {encoding:'binary'});
|
||||||
|
console.log(":::",xfn);
|
||||||
|
} else {
|
||||||
|
throw Error("Could not load extra file " + xpath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function staleFiles(step, targets) {
|
function staleFiles(step, targets) {
|
||||||
if (!step.maxts) throw "call populateFiles() first";
|
if (!step.maxts) throw "call populateFiles() first";
|
||||||
// see if any target files are more recent than inputs
|
// see if any target files are more recent than inputs
|
||||||
|
@ -698,6 +726,7 @@ function linkLD65(step) {
|
||||||
var cfgfile = '/' + platform + '.cfg';
|
var cfgfile = '/' + platform + '.cfg';
|
||||||
setupFS(FS, '65-'+platform.split('-')[0]);
|
setupFS(FS, '65-'+platform.split('-')[0]);
|
||||||
populateFiles(step, FS);
|
populateFiles(step, FS);
|
||||||
|
populateExtraFiles(step, FS);
|
||||||
var libargs = params.libargs;
|
var libargs = params.libargs;
|
||||||
var args = ['--cfg-path', '/share/cfg',
|
var args = ['--cfg-path', '/share/cfg',
|
||||||
'--lib-path', '/share/lib',
|
'--lib-path', '/share/lib',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user