Jump to content
IGNORED

karri's cart template with some addons


Nop90

Recommended Posts

You can find attached the cart template updated by karri on Jan 21, 2019 (here) with some addons by me:

 

1) Input handling

 

in resident.c I added a function checkInput() to be used instead of joy_read(JOY_1). This function returns the value of joy_read(JOY_1), but it handles OPT1, OPT2, Pause keys (and their combination) with standard features.

 

The features in the template are:

 

- Pause: code execution is paused and the screen content is turned in grayscale. Music is paused too. Pressing Pause again revert everythig to the original state.

 

- Op2 + Pause: Flip the screeen

 

- Opt1 + Pause: Trigger a Reset event. Reset event can be handled by game code reading a global variable 'reset' that needs to be checked in every long run loop cycle, so to skip it's execution and make the code run fast to the end of the while(1) cycle usually defined in main. Remember that in every loop there must be a call to checkInput().

 

2) Game saves

 

The template supports Eeprom saves and SD saves without the need of two separate builds.

 

This has been achieved adding to LynxSD.c a custom function LynxSD_OpenFileTimeout(void *pBuffer) that has a trival timeout to avod to lock the code if there isn't an SD cart ready to answer to the OpenFile call.

 

In case of timeout the function returns FR_DISK_ERR that can be used to to decide if every next read/write to saved data have to be done on SD cart or EEPROM chip.

 

Trying to access an EEPROM chip on emulators not supporting it (or phisical cart not supporting it) is not blocking, so this is the default choice on FR_DISK_ERR. If the function returns FR_OK the sav file on SD can be accessed. Every other error returned by the SD meas that the SD is answering but the sav file can't be accessed. In this case both SD and EEPROM saves are disabled.

 

The data to be saved are stored in an array of 128 bytes that is the most common size for saves. In the first 3-5 bytes of this array is a good coding practice to put some character used to check if the content of the save is valid. Organizing in the array the game data to be saved is up to you.

 

Writing to the EEPROM is performed value by value (2 bytes lenght at a time), but only after checking if the value to be witten is different from that already stored in the EEPROM. This is a little slower (not noticeable in the game) but saves the life of the EEPROM.

 

To enable both SD and Eeprom use, in lnxhdr.s the eeprom value is set to 65 (1 for standard 128 bytes eeprom + 64 for SD access use)

 

 

 

That's all for now, if I find something useful to speedup the developement of a new game I'll add it to the template.

 

Credits

 

I used this code to make Xump for Lynx. Can't share the code of Xump because is Copyrighted, but can share all the lynx specific parts that I added to the code base.

 

Almost everything in this template is not my own work but has been collected lurking in this forum. I only mixed the ingredients to cook my recipe. Fell free to do the same changing the template as you like, but remeber to share it :)

 

The help of karri was absolutely precious for finding informations and code snippets, fixing bugs and testing everything on SD and real carts

 

Thanks to necrocia too, that helped me testing the Xump build and contributed to fix some things in this template.

 

And thanks to Sage, that seems to be tired to explain step by step all the lynx internals at avery noob that arrives on this forum, but he shared an invaluale amount of information in so many years of Lynx coding. You rocks guy.

 

template_karri_nop90.zip

Edited by Nop90
  • Like 3
Link to comment
Share on other sites

  • 3 weeks later...

Little note about the libs included in this template.

 

Fade in, fade out and the Chipper sound driver all use the Timer7. Don't use the the fading functons while playing music and reinitialize the sound driver after using the fading effects.

 

But if you need both (fading and sound) at the same time, you can change Timer7 in the fading functions code to another timer. In Griels Quest I changed it to Timer5.

Edited by Nop90
Link to comment
Share on other sites

  • 2 months later...

Thanks again Nop90 for this improved template, it was really really helpful to get me started on my first Lynx game project.

 

While developing, I've just found a tiny bug in the "resetSaveData" function.

The bug is located in the "resident.c" file (in the "resident" folder), line 130:

for(i=14;i<=64;i++)

Should actually be: (the <=64 become a <64)

for(i=14;i<64;i++)

In the current state, reseting SaveData will nullify one extra byte out of the "saveBuf" array, that may modify any other variable (in my case, it was altering the first color of my main palette, that's how I noticed the issue).

 

It's really nothing dramatic though :)

Link to comment
Share on other sites

  • 3 months later...

Updated on github the template code with changes to RetroHQ SD code: https://github.com/nop90-atari-lynx/Cart-template

 

Changes are minimal, in LynxSD.c removed (commented out) the CART1 initialization in the LynxSD_Init() function

 

void LynxSD_Init()
{
	*IODIR = 0; // all input
//	*CART1 = 0xaa; // initialise cart comms
}

then added a call to LynxSD_Init() at the beginning of main() in resident.c

 

As a side effect the LynxSD_Init() makes hung Handy at the following call to LynxSD_OpenFileTimeout().

 

It works fine on Retropie (included the onine emulator o Atarigamer), Mednafen and real lynx. Not tested on a RetroHQ sd cart, but I should be ok.

 

Don't know what's the problem with Handi (the init only sets *IODIR = 0), any help to fix this will be apreciated.

 

For the moment I comment the Init call while developing, so  can test o Handy if needed, and restore it in the final build.

 

 

 

About adding PCM code to the template, it causes a lot of problems if not wisely used (in nutmeg ended playing 4khz instead of 8 to not slowdown the background music), so I'll wait to have something more stable before adding it in the template. If you want use it, the 4ttude sources are on my github as a reference.

 

 

Next addon I want to integrate in the template is a level map handling example: at the moment I'm designing rectangular maps with Tiled, export them as csv files and use a perl script in the called from the makefile to convert them in a compact binary file that I include in the build and read in the code as a char array.

 

The code is under optimization for my Silly Venture entry, so I'll publish it (probably) after the competition.

 

 

 

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

In OnDuty I used three different tile layers: outside, upstairs, tunnels. I also used polylines for guards walking patterns. And properties for tiles. The Python script created a C-file to be included.

 

buildmap.py

 

The resulting C-file looked like this:

 

forest.c

 

For tiles I just used tables like (a tile with 0 can be entered from all directions. Walls are up,right,down,left):
 

static unsigned char entertbl[] = {
15,15,15,15,15, 0, 0,
15,15,15, 0, 0, 0, 0,
15, 0, 8, 2, 9, 3, 1,
 0, 0,15, 0, 0, 0,15,
 0, 0, 0, 0,15, 0,15,
 8, 2,15,15, 8, 2,15,
15, 0,15, 0,15,15, 0,
 0, 0,15,15, 0, 0, 0, 4};

unsigned char get_enter(unsigned char i) {
    return entertbl[i-1];
}

Perhaps something along these lines could find their way to the template?

Link to comment
Share on other sites

1 hour ago, Nop90 said:

(in nutmeg ended playing 4khz instead of 8 to not slowdown the background music)

I had the same problem in On Duty. I solved it be removing all sei and cli instructions from interrupts. Without these guards if there is too much going on the Lynx just runs out of stack and finally crashes. So I had to reduce PCM screams at the same time with chopper sounds, shooting, explosions and background music. But without getting rid of these interrupt guards the performance sucks - big time. There is no slowdown with this approach. Just living dangerously ;) 

Link to comment
Share on other sites

4 minutes ago, karri said:

I had the same problem in On Duty. I solved it be removing all sei and cli instructions from interrupts. Without these guards if there is too much going on the Lynx just runs out of stack and finally crashes. So I had to reduce PCM screams at the same time with chopper sounds, shooting, explosions and background music. But without getting rid of these interrupt guards the performance sucks - big time. There is no slowdown with this approach. Just living dangerously ;) 

I disabled all the SEI and CLI calls as you did, and had to use no more than 4KHz samples to make the slowdown less noticeable (but it's there).

Link to comment
Share on other sites

Here is the perl script I use to convert maps made with Tiled and exported as csv.

 

The script writes in the first two bytes the x and y size of the map (limited to 1 byte each, but it's easy to change it if needed) than writes line by line all the tile index (one byte each).

 

I put each map in a different cart sector and every map starts from the same memory locaton, so after loading a sector I have only to read from the same pointer since the maps doesn't need any translations (I use the same tiles image in the editor and in the game).

 

This optimizes the memory allocation and the loading speed.

mapcsv2bin.pl

Link to comment
Share on other sites

57 minutes ago, Nop90 said:

I disabled all the SEI and CLI calls as you did, and had to use no more than 4KHz samples to make the slowdown less noticeable (but it's there).

But you are using Chipper at 240Hz - right?

 

My sound is 60Hz Handy Music. This could make a difference.

 

There is something wrong here. On Duty has all samples at 8000Hz and I have no slowdown on the bg music. Or gameplay.

thankyou.wav

unsigned8reads.py

 

Plus Handy Music streams out the PCM directly from the cart.

Link to comment
Share on other sites

  • 1 month later...

Updated on github (https://github.com/nop90-atari-lynx/Cart-template) the cart template with a workaround to avoid Handy to freeze after adding the LynxSD_Init() call to the template (caused by my modified lynxSD code with timeout not handled correctly by Handy).

 

Only Handy was affected by this problem, not real HW, Mednafen or the retroarch core, but since I use Handy for debugging I need this fix.

 

Also fixed the memory leak on the savebuf array reported some time ago.

Edited by Nop90
  • Thanks 1
Link to comment
Share on other sites

There is a problem with the patch: the LynxSD_Init() sets IODIR to 0  that prevents the emulator to read the emulated eeprom. Already found a fix for code running on Handy, but have to test if it works too on other emulators and on real HW.

 

If you want to test it , the fix is on github

 

 

Edited by Nop90
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...