|
ForumsSega Master System / Mark III / Game GearSG-1000 / SC-3000 / SF-7000 / OMV |
Home - Forums - Games - Scans - Maps - Cheats - Credits Music - Videos - Development - Hacks - Translations - Homebrew |
Goto page Previous 1, 2, 3 ... 15, 16, 17 |
Author | Message |
---|---|
|
Posted: Fri Apr 05, 2024 9:09 am |
Out of interest as maybe another example for you @tibone, here's how I just did this for Land on my Base: source. As sverx suggests, I've taken the approach here of keeping the game config in working RAM (it's passed into these functions by reference), and then at the point of loading from / saving to SRAM, which is very infrequently, I do a memcpy operation of the entire structure. Because the level code is part of the structure and because it has an inherent checksum component, it's also possible to use this to effectively detect whether SRAM is present, since valid SRAM data must have a valid checksum. If SRAM is not present, the write operations will not modify the memory in slot 2, so the save will silently fail. (N.B. I'm not sure why I hand wrote my own memcpys here instead of using the standard library - I really should have used the library, maybe I was just playing around with stuff and forgot to come back and tidy up) void game_save_config(game_config_t *config) { SMS_enableSRAM(); // cast: game_config_t *save_config = (game_config_t *)SMS_SRAM; // memcpy: for (int i = 0; i < sizeof(game_config_t); i++) save_config[i] = config[i]; SMS_disableSRAM(); } bool game_load_config(game_config_t *config) { // default settings (in case no SRAM data) for (int i = 0; i < sizeof(config->level_code); i++) config->level_code[i] = DEFAULT_START_LEVEL[i]; config->difficulty = 1; config->invert_controls = false; SMS_enableSRAM(); // cast game_config_t *save_config = (game_config_t *)SMS_SRAM; // check if SRAM data exists and has valid checksum bool loaded = random_deserialize_seed(save_config->level_code); if (loaded) { // memcpy for (int i = 0; i < sizeof(game_config_t); i++) config[i] = save_config[i]; } SMS_disableSRAM(); return loaded; } |
|
|
Posted: Mon Apr 08, 2024 2:46 am |
Hey sverx, trying to get back into the swing of things. I think the meta sprite tool was the last thing I was working on. I'm getting around to outputting c code, but I may have missed a thing or two since coming back.
Below is sample output (Tall sprite) from the Konami sprite I have done previously: // Your MetaSpriteBaseTile offset is 317
unsigned char const konami_star_00[] = { 0, 0, 0, 8, 0, 2, METASPRITE_END }; unsigned char const konami_star_01[] = { 0, 0, 4, 8, 0, 6, METASPRITE_END }; unsigned char const konami_star_02[] = { 0, 0, 8, 8, 0, 10, METASPRITE_END }; unsigned char const konami_star_03[] = { 0, 0, 12, 8, 0, 14, METASPRITE_END }; unsigned char const *konami_star_frames[] = { konami_star_00, konami_star_01, konami_star_02, konami_star_03 }; How is the tile id offset applied? I have the tiles for the sprite loaded at tile 317. Since that value is larger than 256, I would imagine it couldn't be simply added as the sprite base tile id. The tool does have the option to define your tile id offset. Also, having potential negative values for the x and y. Would that not trigger a compiler warning? Thanks in advance. |
|
|
Posted: Mon Apr 08, 2024 9:07 am |
Sprite tile IDs are always 8 bit, as you can only have sprites in the first OR in the second half of VRAM - so your 317 becomes 317-256.
But you can use 317 as base and ignore the warning, as you would ignore them anyway if you use negative values for x and y - or you could used signed char const arrays, and have warnings each time your tile ID is 128 or more. Really, it's quite hard to avoid warnings as you can't easily have an array in C where some are signed and some are unsigned, you should have structs for that but here it would complicate matters too much with no real gain. |
|
|
Posted: Mon Apr 08, 2024 1:20 pm |
Padding the rom to 64KB and casting the value of my hiscore variable to a char seemed to have worked. :)
Thanks sverx and willbritton I did something a lot simpler than your examples, but it seems it worked correctly, on my first test. I'll check everything and probably update my rom today or tomorrow. Thanks for the help! |
|
|
Posted: Yesterday at 9:27 pm |
A couple of questions about banking code if anyone can help please.
In the assets2banks it reads:
Does this mean code has to go before assets or is the above just for preference? Another question: what's the easiest way for me to get the size of my code bank? Similar to how assets2banks outputs the size of each bank in it's summary. I mean I might not hit 16Kb but it would be good to know. EDIT: Nevermind I can see it tells me this in the output.map. Also sorry a final question, the only code I'm putting on a separate bank is large constant arrays (enemy paths, events etc) but no functions. Is this the best way for me to store this data or should I be doing it another way? |
|
|
Posted: Today at 5:51 am |
For Stygian Quest, my static arrays of data are put in .bin binary files and threated as data. Much more easy to use on my opinion.
For order of banks I dont know. |
|
|
Posted: Today at 7:42 am |
Constant arrays are not "code" in this sense, they can be banked as assets like any other without needing to use the code banking mechanism - the output of assets2banks can produce constant arrays as a comparison.
Note that there's a compiler directive you can put in a C file to indicate what bank it targets. Afk right now but I think it's #pragma bank n. I use this one rather than specifying on the command line. |
|
|
Posted: Today at 7:59 am |
I suppose my only thought is how to get my constant array data (mostly unsigned chars) into binary so assets2banks can bank it for me, or is there another way?
Regarding the order of banks, I've seen open source examples using code banks at the end of a list of asset banks, so I don't think the order matters. |
|
|
Posted: Today at 8:23 am |
I assume your constant array data is already in C? If so, what I'm saying is that you don't need to use assets2banks at all for those, just put it straight in a C or H file and use the #pragma to say which bank it should go into. (NB it's e.g. #pragma constseg bank2) I guess one issue is that assets2banks also tries to pack your banks efficiently. One way is to reserve a bank or so at the beginning for your const arrays, but maybe there's a better way that @sverx can suggest to reserve a specific number of bytes. |
|
|
Posted: Today at 8:54 am |
Sorry I should've explained, that's what I'm already doing. I have one bank for constant arrays. But I was thinking about Naarshakta's suggestion to put it in binary and let assets2banks convert to the arrays organise it. I'm assuming that Naarshakta has an external tool or something to arrange binary data though. I don't have much problem doing what I'm doing now and adding arrays manually to my code bank source file but as it's the first time I'm banking "code" just wondering if it's the right way. |
|
|
Posted: Today at 9:02 am |
In fact, all my game data ( boards, strings, items, etcs.. ) are in a json file, easy to edit for me while I work on the game design itself.
So I have written a script In python that transform that json file into a brunch of binary files that are threated as any asset file :) For types of data you Can use an assets2bank.cfg to tell assets2bank to generate arrays of int, or char or whatever struct you want... |
|
|
Posted: Today at 11:44 am |
As often happens, there are several ways to solve this.
One, as suggested, is to treat static data as binary asset, and put that into the assets folder and leave it for assets2banks to handle it. It's a very good suggestion, but sometimes your data is not just made of constants and needs to be compiled so another solution could be to have a data bank (or more than one if necessary) where you put all your static const arrays, then you compile that and link it as a data bank (address 0xn8000). Of course you then need to map that data bank before accessing the arrays defined there, just like you would do with 'regular' assets. Another possible approach is to keep this data with the functions that uses that in a 'code' bank. As an example, one could have a few math functions (that uses data LUTs) and create a math.c file where these functions are declared as banked function. Upon invocation of these, the code and the data will be mapped at the same time, being them together, and the result will be returned. Of course if you just need to read a value from a LUT this solution's performance won't be great, but if your functions performs trigonometric operations that require some work and you call them just a few times per frame, it might be a handy solution. Also, the order of banks doesn't really matter - I usually keep the code in the first banks because it's much easier to move the data further away (by changing assets2banks' --firstbank= parameter for my assets) in case I need one more banks for code. I don't usually use #pragmas in my sources because I prefer to handle everything from the makefile/build scripts but, once more, this is more about personal preferences - whatever floats your boat is a good approach ;) |
|
|
Posted: Today at 11:55 am |
it's possible, if you really want to put your own static data together with the first bank allocated to the assets, to tell assets2banks that the first bank is smaller than the regular size using --firstbank=n,size but I would say this is needed only if one is desperate to save one bank because of a ROM availability limit.
Another option would be to allocate that static data at the end of the last bank by just telling the linker to put that at the same address as the last assets2banks' generated bank. If it fits, it should work - but I never tried it. |
|
|
Posted: Today at 12:14 pm |
Actually I take a somewhat strange hybrid approach - I get assets2banks to generate C files and then in my makefile I use the filename of the generated files to inject the #pragma at the top of each one, meaning I don't need to manually specify the bank names on the SDCC command line - in other words, assets2banks is deciding on the banks automatically for the most part, but I can also create manual asset files and specify the banks in the file, all without needing to change the command line too much.
Ah that's a good point - if it fits in the remainder it saves on a bank, if it doesn't we would need a new one anyway. |
|
Goto page Previous 1, 2, 3 ... 15, 16, 17 |