Runs great on Mame. Did you test on a real nabu?
I checked the version of NABU-LIB.c you have in this zip file against the one I am using and besides the setPatternColor() function; there no other differences.
I also tried with the version of snake.c in your zip file and it worked perfectly in Mame, but when trying to exit the game on a NABU machine it crashed and the check light came on and didn't turn off.
I wonder if there is some minor difference between the handling of messages from the Nabu over serial vs those arriving over TCP.
The annoying thing is it works in Tetris. It also works without issue in the following sample app I made to try to reproduce the error:
Code: Select all
#define DISABLE_HCCA_RX_INT
#define DISABLE_CURSOR
#define DEBUG_VDP_INT
#define BIN_TYPE BIN_CPM
#include "NABU-LIB.h"
#include "NabuTracker.h"
#include "nabu-games-patterns.h"
#include "strings.h"
uint16_t music[] = {
0, NT_NOTE_ON, 0, 20, 10,
1, NT_NOTE_OFF, 0,
2, NT_NOTE_ON, 0, 10, 10,
3, NT_NOTE_OFF, 0,
4, NT_NOTE_ON, 0, 20, 10,
5, NT_NOTE_OFF, 0,
6, NT_NOTE_ON, 0, 10, 10,
7, NT_NOTE_OFF, 0,
8, NT_NOTE_ON, 0, 15, 10,
9, NT_NOTE_OFF, 0,
10, NT_NOTE_ON, 0, 20, 10,
11, NT_NOTE_OFF, 0,
12, NT_NOTE_ON, 0, 10, 10,
13, NT_NOTE_OFF, 0,
14, NT_NOTE_ON, 0, 30, 10,
15, NT_NOTE_OFF, 0,
16, NT_LOOP
};
//Set all values in the color table to color.
void vdp_setPatternColor(uint8_t color) {
vdp_setWriteAddress(_vdpColorTableAddr);
for (uint16_t i = 0; i < 0x1800; i++) {
IO_VDPDATA = color;
}
}
uint16_t getHighScore() {
uint16_t hs;
#if BIN_TYPE == BIN_CPM
FILE * fp = fopen("fileio.dat", "r");
if (fp) {
fscanf(fp, "%d", &hs);
} else {
hs = 0;
}
fclose(fp);
#else
hs = 0;
#endif
return hs;
}
void setHighScore(uint16_t hs) {
#if BIN_TYPE == BIN_CPM
FILE * fp = fopen("fileio.dat", "w");
fprintf(fp, "%d", hs);
fclose(fp);
#else
(void)hs;
#endif
}
void delay(uint8_t frames) {
uint8_t ticks = 0;
while(true) {
vdp_waitVDPReadyInt();
ticks ++;
if (ticks > frames)
break;
}
}
void centerText(char *text, uint8_t y) {
vdp_setCursor2(abs(15-(strlen(text)/2)),y);
vdp_waitVDPReadyInt();
vdp_print(text);
}
bool menu() {
vdp_clearScreen();
centerText("PRESS A KEY TO PLAY MUSIC", 10);
centerText("PRESS ESCAPE TO EXIT", 12);
while(1) {
if(isKeyPressed()) {
uint8_t key = getChar();
if(key == 0x1b) {
return false;
} else {
return true;
}
}
}
}
void main() {
initNABULib();
vdp_clearVRAM();
vdp_initG2Mode(1, false, false, false, false);
vdp_loadPatternTable(FAT,0x330);
uint16_t _vdpColorTableAddr = 0x2000;
uint16_t _vdpColorTableSize = 0x1800;
vdp_setWriteAddress(_vdpColorTableAddr);
vdp_setPatternColor(0x41);
initNABULIBAudio();
nt_init(music);
vdp_enableVDPReadyInt();
uint16_t high_score = getHighScore();
// This is roughly how the snake main loop works.
while(menu()) {
//play some music - whatever.
uint8_t played_notes = 0;
// load the vdp with activity.
char letter = 30;
while ( (played_notes ++) < 30) {
for(int i=0; i<24; i++) {
for(int j=0;j<32;j++) {
vdp_setCharAtLocationBuf(j, i, letter);
}
}
vdp_waitVDPReadyInt();
vdp_refreshViewPort();
letter ++;
nt_handleNote();
high_score ++;
}
}
// If we get to here, it means the user pressed escape on the main menu.
// So we want to do some final messing around with the high_score (just for kicks)
// and then call the setHighScore() function which will actually save the score back to disk.
// In snake the game crashes inside the setHighScore() function at the line, where it tries to
// open a file.
high_score = high_score + 301;
setHighScore(high_score);
vdp_disableVDPReadyInt();
nt_stopSounds();
}
Very confusing.