Version 3.1 of Nabu Games ** FIXED in v3.3 **

The author of CPM Tetris and Snake.
User avatar
productiondave
Posts: 117
Joined: Tue Mar 28, 2023 10:01 pm

Version 3.1 of Nabu Games ** FIXED in v3.3 **

Post by productiondave »

UPDATE: 07 April 2023, It works but snake has issues.
- Tetris seems to be fine, snake crashes in CPM when trying to save the high score. I am working on fixing it - but first I need to know why this happening.
UPDATE: 07 April 2023, It is fixed in version 3.2
- Download the LATEST HOTFIX HERE: https://github.com/linuxplayground/nabu ... s/tag/v3.2


Snake and Tetris now track high scores in CP/M on both the Nabu and the Z80-Retro. High score data is saved in a .dat file in the same disk and user area as the game.

Native Nabu versions of the games will track high scores for the duration of a play session. I have not implemented a storage solution for these as there are different network adapters with different methods of holding storage data.

Snake now has levels. The game works like this:
  • You level up every 10 apples.
  • Your snake resets its length every time you level up.
  • There are 5 levels in total. If you make it that far, the levels start at the beginning again.
  • Your snake starts to speed up after every level from the end of Level 2 onwards.
  • Because the snake length is reset with each level, the snake now grows by 4 segments each time you eat an apple.
Last edited by productiondave on Tue Apr 11, 2023 7:51 pm, edited 3 times in total.
User avatar
DJ Sures
Posts: 347
Joined: Tue Mar 28, 2023 8:36 pm
Location: nabu.ca
Contact:

Re: Version 3.1 of Nabu Games

Post by DJ Sures »

productiondave wrote: Thu Apr 06, 2023 7:06 am https://github.com/linuxplayground/nabu ... s/tag/v3.1

Snake and Tetris now track high scores in CP/M on both the Nabu and the Z80-Retro. High score data is saved in a .dat file in the same disk and user area as the game.
Keeping me busy :). I have a plan to make a website that allows ppl to upload programs that get put online - but I’m not sure how to filter users and programs yet. Could lead to some real big messes.
productiondave wrote: Thu Apr 06, 2023 7:06 am Native Nabu versions of the games will track high scores for the duration of a play session. I have not implemented a storage solution for these as there are different network adapters with different methods of holding storage data.
That’s too bad about the different protocols - one of the points to this forum was allow ppl to combine efforts and work together. Ie building on shoulders of giants, is the example saying - like you and I are doing with nabulib.

Unless the other internet adapters removed support for the RetroNET protocol extensions, the file commands should still work?

I wonder if i can make some convertor in nabulib to detect and support the other protocol - or maybe add it to my internet adapter. I’ll have to take a better look at it.
productiondave wrote: Thu Apr 06, 2023 7:06 am Snake now has levels. The game works like this:
  • You level up every 10 apples.
  • Your snake resets its length every time you level up.
  • There are 5 levels in total. If you make it that far, the levels start at the beginning again.
  • Your snake starts to speed up after every level from the end of Level 2 onwards.
  • Because the snake length is reset with each level, the snake now grows by 4 segments each time you eat an apple.
Hehe snake is becoming a real game - it’s come a long way from the first release. I’m glad it’s still getting attention from you. It’s fun thinking of unique approaches to make these games more strategic and different.
User avatar
productiondave
Posts: 117
Joined: Tue Mar 28, 2023 10:01 pm

Re: Version 3.1 of Nabu Games

Post by productiondave »

I will suggest to people that move snake.com and Tetris.com over to C drive to avoid loosing the dat files which contain your saved high scores. Or don't. Up to you.

There may retronet file extension support. I'll have to do a bit of digging. Until the next version of the nabu network dot com adapter is released I'll not be able to test very much.

I'm fairly sure the web serial adapter can't save files.
masto
Posts: 39
Joined: Wed Mar 29, 2023 10:15 pm

Re: Version 3.1 of Nabu Games

Post by masto »

productiondave wrote: Thu Apr 06, 2023 7:34 pm I'm fairly sure the web serial adapter can't save files.
A very true fact. I haven't tried yet, but I suspect this version will be unusable because I don't handle those file commands at all. Something I can look at fixing tonight.

ook ook
User avatar
productiondave
Posts: 117
Joined: Tue Mar 28, 2023 10:01 pm

Re: Version 3.1 of Nabu Games !! WAIT !!

Post by productiondave »

Hey - so i was testing again this morning and have come across a strange bug.

One of those it works in mame and not on real hardware type bugs. Snake crashes when it tries to save a file.
Tetris works ok.

I have a vague feeling I know where to look, but if anyone has tried the latest version and can let me know if snake freezes after hitting a wall, that would be great. (when playing on an actual nabu)

HINT: It's happening because CPM can't open the file. I think it might be a memory issue... Something with my code for sure.

Thanks
User avatar
DJ Sures
Posts: 347
Joined: Tue Mar 28, 2023 8:36 pm
Location: nabu.ca
Contact:

Re: Version 3.1 of Nabu Games !! WAIT !!

Post by DJ Sures »

Have you altered any of the code in interrupts? The file saving uses IY and IX registers. NABULIB does save them, so does cpm bios.

The other thing to check why it doesn't work on real hardware is to turn on vdp debugging. It'll flash the red led if there are too many cycles between screen updates. The nabulib.h explains a solution, which is to wait for another pass. That might be it because timing is everything for little bugs like this to rise.
User avatar
productiondave
Posts: 117
Joined: Tue Mar 28, 2023 10:01 pm

Re: Version 3.1 of Nabu Games ** FIXED **

Post by productiondave »

I haven't touched interrupt code at all. That stuff is all carefully crafted to work with your BIOS. I would not know what to do there.

The problem seemed to go away if I saved the score before hitting up the AY PSG to play the crash sound... I initially thought it might be a timing thing, but i wasn't doing any writes to the screen at that time. Just play a crash sound and then write some data to a file.

I turned on some printf debug statements and it literraly crashed on the FILE * fp = fopen("snake.dat", "w"); line.

If i moved the save score code to BEFORE playing the crash sounds, the issue went away.

Is that a useful clue.

I updated the code and pushed release 3.2. I also updated the Link in the origin post of this topic.
User avatar
productiondave
Posts: 117
Joined: Tue Mar 28, 2023 10:01 pm

Re: Version 3.1 of Nabu Games ** FIXED **

Post by productiondave »

So further testing has shown that this fix is not actually working.

So to be clear: Snake works until you want to save the high score.

Tetris manages to save the high score every time.

So something odd is going on with Snake. I need to find a way to reliably reproduce the problem in some simpler code. For now I am going to sleep on it.

the specific line of code that's failing is the fopen() statement. When it executes, the CHECK light is lit and never stops being lit. The system hangs at this point and needs to be reset.

Doesn't happen in tetris.

I would appreciate it if someone (DJ if you have time) could have quick look at the latest snake.c code in github. I am sure this is something dumb.

I have tried turning on VDP DEBUG and the red light flashes very briefly at the beginning and then never again.
I have added a vdpIsReady = false and a vdp_waitVDPReadyInt() call just before attempting to open the file. That made no difference.
I have tried moving the call to the setHighScore() function to the very end of the main function. IE: User hits escape to exit the game, save the high score and let mian() run it's course. This never helped either.

It works perfectly on the Z80-Retro CP/M. I have not tried it with Ishkur CP/M.

Something in Snake is messing with CloudCPM in some way. I am sure of it.

That or I just need to reconsider my life choices.

Thanks
User avatar
DJ Sures
Posts: 347
Joined: Tue Mar 28, 2023 8:36 pm
Location: nabu.ca
Contact:

Re: Version 3.1 of Nabu Games ** FIXED **

Post by DJ Sures »

I built it against the current nabulib and it runs great. Here's my build version with the latest nabulib:
Snake.zip
(267.71 KiB) Downloaded 423 times
Compare the isr_keyboard and vdp isr with the latest nabulib - see if there's a difference
Capture.JPG
The file is creates is also seen here...
Capture.JPG
User avatar
productiondave
Posts: 117
Joined: Tue Mar 28, 2023 10:01 pm

Re: Version 3.1 of Nabu Games ** FIXED **

Post by productiondave »

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.
Post Reply