Nop90 Posted April 12, 2019 Share Posted April 12, 2019 (edited) 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 April 12, 2019 by Nop90 3 Quote Link to comment Share on other sites More sharing options...
Turbo Laser Lynx Posted April 12, 2019 Share Posted April 12, 2019 Hey, thanks for sharing! But I can't se the attachment :/ I will put up the enhanced template in the "tools and tutorials" post when I get it Quote Link to comment Share on other sites More sharing options...
Nop90 Posted April 12, 2019 Author Share Posted April 12, 2019 Added. 1 Quote Link to comment Share on other sites More sharing options...
Igor Posted April 12, 2019 Share Posted April 12, 2019 This is great. I'm in the process of building the programming section over at Atari Gamer so I'll definitely be including this. Great work! Quote Link to comment Share on other sites More sharing options...
Nop90 Posted May 1, 2019 Author Share Posted May 1, 2019 (edited) 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 May 1, 2019 by Nop90 Quote Link to comment Share on other sites More sharing options...
drludos Posted July 20, 2019 Share Posted July 20, 2019 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 Quote Link to comment Share on other sites More sharing options...
Nop90 Posted July 20, 2019 Author Share Posted July 20, 2019 Thank you. I'm going to fix it and add the play pcm from cart code in the next days, then I'll post an update. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted October 28, 2019 Author Share Posted October 28, 2019 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. 1 1 Quote Link to comment Share on other sites More sharing options...
+karri Posted October 28, 2019 Share Posted October 28, 2019 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? Quote Link to comment Share on other sites More sharing options...
+karri Posted October 28, 2019 Share Posted October 28, 2019 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 Quote Link to comment Share on other sites More sharing options...
Nop90 Posted October 28, 2019 Author Share Posted October 28, 2019 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). Quote Link to comment Share on other sites More sharing options...
Nop90 Posted October 28, 2019 Author Share Posted October 28, 2019 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 Quote Link to comment Share on other sites More sharing options...
+karri Posted October 28, 2019 Share Posted October 28, 2019 This might be a more generic approach. Lets use this in the template. Quote Link to comment Share on other sites More sharing options...
+karri Posted October 28, 2019 Share Posted October 28, 2019 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. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 2, 2019 Author Share Posted December 2, 2019 (edited) 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 December 2, 2019 by Nop90 1 Quote Link to comment Share on other sites More sharing options...
drludos Posted December 2, 2019 Share Posted December 2, 2019 Wonderful, thanks a lot! I'll use it to update both of my Lynx projects! Out of curiosity, how did you manage to prevent Handy to freeze while maintaining the new LynxGD version compatibility? Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 2, 2019 Author Share Posted December 2, 2019 Checking the fake register that returns 42 on handy and 0xff on real hw 1 Quote Link to comment Share on other sites More sharing options...
Nop90 Posted December 8, 2019 Author Share Posted December 8, 2019 (edited) 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 December 8, 2019 by Nop90 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.