Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Beginners question [C and SMSDevKit]

Reply to topic Goto page 1, 2, 3  Next
Author Message
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Beginners question [C and SMSDevKit]
Post Posted: Mon Jun 24, 2019 11:14 am
Hello SMS-Power-Forum,

I'm new to this forum and... well I registered here because I have some noob questions about programming the SEGA Master System with the SMSDevKit and SDCC. I really love the Master System! Especially the Model 1 - that is why I want to develop for it :3

Anyway... So I tried getting into developing SMS games, read fantastic tutorials here and used interesting tools - especially the SMSDevKit. But yesterday I hit a big blockade and I'm not sure if I can solve it without an answer of experts. I'm already sorry for asking those beginners questions...

1.) Scrolling Backgrounds
So I learned, that I have a virtual screen, that is slightly higher then the actual screen of the SMS. I also was able to fill the visible screen with a tilemap - but! If I think about Sonic or Alexx Kid, then I see, that there maps are bigger then the screen and even the virtual screen. So I started to think about this.

Well... I thought about falling into a pit, what would I need? I could create two 'screen sized' maps, one with the start of the pit, and the second one being the pit. I could load the first map and the beginning of the second map into the non visible area of the screen.
I could use SMS_loadTileMapArea for loading the part of the second map and with SMS_setBGScrollY I could scroll into the 'non-visible' area of the screen and then at a certain point quickly load the full map with no overlapping. Sounds doable to me.

But then again, how can I do this when going left or right? The virtual screen only expands in height, not in width - and if I go with SMS_setBGScrollX then the screen starts to wrap. So I see no way in doing that, but Alexx Kid and Sonic do both of that scrolling! How do I achieve that?

Also... If go for compressed tile maps, I lack the ability to load only a part of the tilemap. I tried solving that by using SMS_loadSTMcompressedTileMapatAdr, trying to uncompress the map to a local buffer - but then I noticed, that 'unsigned int dest' references to the VDR - so... I have no idea...

2.) Timing
Is there any function or way to get some kind of timer? Like CPU cycles? Or passed Milliseconds since the start up of the system?

I hope somebody here can answer my questions ^o^
  View user's profile Send private message
  • Joined: 14 Apr 2013
  • Posts: 623
Reply with quote
Post Posted: Mon Jun 24, 2019 11:25 am
Jaberwocky wrote
Hello SMS-Power-Forum,

I'm new to this forum and... well I registered here because I have some noob questions about programming the SEGA Master System with the SMSDevKit and SDCC. I really love the Master System! Especially the Model 1 - that is why I want to develop for it :3

Anyway... So I tried getting into developing SMS games, read fantastic tutorials here and used interesting tools - especially the SMSDevKit. But yesterday I hit a big blockade and I'm not sure if I can solve it without an answer of experts. I'm already sorry for asking those beginners questions...

1.) Scrolling Backgrounds
So I learned, that I have a virtual screen, that is slightly higher then the actual screen of the SMS. I also was able to fill the visible screen with a tilemap - but! If I think about Sonic or Alexx Kid, then I see, that there maps are bigger then the screen and even the virtual screen. So I started to think about this.

Well... I thought about falling into a pit, what would I need? I could create two 'screen sized' maps, one with the start of the pit, and the second one being the pit. I could load the first map and the beginning of the second map into the non visible area of the screen.
I could use SMS_loadTileMapArea for loading the part of the second map and with SMS_setBGScrollY I could scroll into the 'non-visible' area of the screen and then at a certain point quickly load the full map with no overlapping. Sounds doable to me.

But then again, how can I do this when going left or right? The virtual screen only expands in height, not in width - and if I go with SMS_setBGScrollX then the screen starts to wrap. So I see no way in doing that, but Alexx Kid and Sonic do both of that scrolling! How do I achieve that?

Also... If go for compressed tile maps, I lack the ability to load only a part of the tilemap. I tried solving that by using SMS_loadSTMcompressedTileMapatAdr, trying to uncompress the map to a local buffer - but then I noticed, that 'unsigned int dest' references to the VDR - so... I have no idea...

2.) Timing
Is there any function or way to get some kind of timer? Like CPU cycles? Or passed Milliseconds since the start up of the system?

I hope somebody here can answer my questions ^o^

Quick answers to both questions:
1) You might want to take a look at psidum's General Scroll Library
2) In Emulicious's Debugger you can find the Profiler in the Tools menu. You can either use the procedure profiler to determine the cycles needed per procedure or use the General Profiler to determine the cycles of a specific range of code (from one address in your ROM to another)

If you're after more detailed answers feel free to ask.

Jaberwocky wrote
But then again, how can I do this when going left or right? The virtual screen only expands in height, not in width - and if I go with SMS_setBGScrollX then the screen starts to wrap. So I see no way in doing that, but Alexx Kid and Sonic do both of that scrolling! How do I achieve that?

You might have seen the option to hide/blank the left most column. Blanking the left most column reduces the virtual screen width by 8 pixels and opens up this column for preloading tiles for horizontal scroll.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Mon Jun 24, 2019 12:06 pm
Calindro wrote
Quick answers to both questions:
1) You might want to take a look at psidum's General Scroll Library
2) In Emulicious's Debugger you can find the Profiler in the Tools menu. You can either use the procedure profiler to determine the cycles needed per procedure or use the General Profiler to determine the cycles of a specific range of code (from one address in your ROM to another)

If you're after more detailed answers feel free to ask.

Woah! Thank you :3 This was quick and helpfull!

The libary is a cool thing, but I still wonder about how to get scrolling done, I would like to understand the basic approach of doing so - even though I will use the libary, I just want to understand those basics.

Calindro wrote
You might have seen the option to hide/blank the left most column. Blanking the left most column reduces the virtual screen width by 8 pixels and opens up this column for preloading tiles for horizontal scroll.

I can't follow you.... What do you mean?

Thank you for your answer so far x3
  View user's profile Send private message
  • Joined: 14 Apr 2013
  • Posts: 623
Reply with quote
Post Posted: Mon Jun 24, 2019 1:18 pm
Jaberwocky wrote
Calindro wrote
You might have seen the option to hide/blank the left most column. Blanking the left most column reduces the virtual screen width by 8 pixels and opens up this column for preloading tiles for horizontal scroll.

I can't follow you.... What do you mean?

Thank you for your answer so far x3

It's bit 5 of this register:
http://www.smspower.org/Development/VDPRegisters#Register00ModeControlNo1

In devkitSMS it's called
VDPFEATURE_LEFTCOLBLANK
which is defined here:
https://github.com/sverx/devkitSMS/blob/master/SMSlib/src/SMSlib.h#L25

It can be enabled using
SMS_VDPturnOnFeature(VDPFEATURE_LEFTCOLBLANK);


Using this, you can see in the Tilemap/Nametable Viewer of an emulator that the virtual screen is shrunk horizontally by 8 pixels.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Jun 24, 2019 1:37 pm
The hardware background is 32 tiles wide and 28 tiles tall and the part of it you see on the screen is 32x24 tiles, 256x192 pixels.
Of course many games have virtual backgrounds that expand that, the point is that the only option is to replace some data in the hardware background in the right moment, so for instance when you scroll right you replace the contents of the 1st column (column zero) of the hardware background with the data from the 33rd column from your virtual background.

Check this post: I'm scrolling vertically there but you get the point.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Mon Jun 24, 2019 3:50 pm
Or more simply: when scrolling, exactly on the frame where a new offscreen area would appear (showing the wrong tiles), rewrite it to be correct. Most games do this every 8px, even when scrolling vertically, because it's actually harder to do it in bigger chunks. Some games even do a secret scroll before enabling the screen to make the scrolling "paint" routine fill the initial screen.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Mon Jun 24, 2019 5:36 pm
Thank you Calindro!
I missed that special bit - that explains a lot to me :3

Also thank you sverx and Maxim!
With all your answers I have a pretty good impression how to make a game scroll now :3 Gonna try it when I'm allowed to programm again.

---
I still have questions though xO

Let's keep counting:

3.) More timing
What can I do if I want to wait 1sec for something? Like blocking player input for that long - how can I measure that period?
Can I simply relay on the VBlank, knowing it will call my loop 25 (PAL/50hz) times per sec? So I simply count up to 25 and that's it?

But then I would have difficulties with running the game on a NTSC target with 30 calls per sec - so... I would have to use some defines to adapt... Anyway, would I do a one second delay like that?

4.) Map compression
Even though I have a good idea about making my screen scroll, I'm worried about the memory I need. If I compress my various maps I have then I'm not able load them in a specified rectangle - SMSDevKit has only functions to directly load them to the VDR(?)

SO I would have to resolve the compression into a buffer - correct? But how can I do that? I looked at the SMS Power article about compression, but they all seem to target the VDR - also I failed understanding them. Any 'best practices' for that? Or ideas how I can get more familiar with that?

Thanks again for all your patiency x3
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Jun 24, 2019 5:50 pm
3) Yes, you basically count frames. As for 60Hz/50Hz, most games just don't care and leave seconds run slower or PAL systems (or faster on NTSC ones). Edit: note that it's either 50 or 60 fps, not 25 or 30.

4) Larger maps are usually using some meta-tiling. Compression basically depends on your data and how you use it (in a forward-only fashion? Easier. Freely? Harder)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Mon Jun 24, 2019 6:19 pm
Metatiles is the way to go. You can have multiple levels, depending on your scale and art style. The abstraction works as compression in its own right (it's a kind of dictionary coding), and you can apply an actual compression algorithm to the data at different levels if you can spare the RAM to store it decompressed. Metatiles also make sense to encode other information about the world (solidity, effects, portals, collectibles, etc).

Sonic has 32x32 tiles. Micro Machines has 96x96. Psycho Fox has something like 128x16, I seem to remember.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Tue Jun 25, 2019 5:30 am
Thank you sverx and Maxim!
Again this really helps me x3 Sorry for messing up the thing about the frame rate - I actually looked it up and somewhere it said 50hz would be 25fps and so on.

So Metatiles basically means increasing the original tile size? So that I say tile 0 is build up with tiles:
[0][0]
[0][0]

And tile 1 might be
[1][2]
[3][4]
?

I'm bad in explaining I hope you get what I mean >_x
Because I'm using C and the SMSDevKit - wouldn't I have troubles doing so? I could not use the 'mass loading' function like "SMS_loadTileMap" - it would not know about my metatiling.
So I would use SMS_setNextTileatXY and SMS_setTile - wouldn't that be to slow?

Well... Kinda question 5:

5.) Being to slow
What will actually happen if I'm to slow in my frame? If I miss the time frame I have per each frame?

6.) 'Loading a lot'
I mean... If I know, that I will miss my frames (/drop my frames?) for a while, can I simply turn off the screen, do what I need to do and turn it on again? While blocking my main-loop with that 'long loading'?
I expect that the player would just have a black screen for the time - and wondering what the game is doing.

I can't thank you enough with those information :3
I really want to program something small for the SMS soon - and knowing that stuff helps me getting a somewhat clear image about the situation.
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Tue Jun 25, 2019 5:52 am
Yes - take a look at most games and you can see they are built from blocks that are bigger than 8x8. The game engine is also treating each of those blocks as some thing it knows how to deal with - what's solid, what's breakable, etc.

That also means you never actually load a large tilemap, you are always drawing bits of small metatiles. It's not that slow, especially if you optimise the code.

You turn off the screen to do the bulkiest loads - loading all the tiles, drawing the full tilemap. (You can do it with the screen on but that's a special case.) Don't do it during the game - indeed a blank screen is very noticeable.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Jun 25, 2019 5:57 am
Jaberwocky wrote
So I would use SMS_setNextTileatXY and SMS_setTile - wouldn't that be to slow?


If you're updating a row of tiles, you can issue one single SMS_setNextTileatXY followed by as many SMS_setTile as you need, as the VDP would automatically advance to the next tile.
If you need to update a column of tiles, instead, there's basically no other way than to have a loop of SMS_setNextTileatXY and SMS_setTile. Yes, it is surely not so fast, but it's totally something the SMS can do.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Tue Jun 25, 2019 1:25 pm
As usally - thank you all alot x3
I'm almost done with my beginners question - I'm sure they will follow more when I try applying the things I learned today x3

sverx wrote
Yes, it is surely not so fast, but it's totally something the SMS can do.

Is there a way to speed up the process of updating a column of tiles - or is using the loop with the SMS_setNextTileatXY and SMS_setTile pair the best I can do? Would a function help to directly access the target memory? I thought SMSDevKit does provide functions for that...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Jun 25, 2019 1:41 pm
there's no way for the Z80 to directly access the Video RAM (VRAM) as that's 'behind' the VDP. So to write any data there, you should actually tell the VDP to do so, that's why it isn't fast at all.

Quote
[...]updating a column of tiles... is using the loop with the SMS_setNextTileatXY and SMS_setTile pair the best I can do?


without resorting to writing a *just slightly quicker* assembly function yourself, I would say so.

this isn't so slow after all:
  unsigned int addr = XYtoADDR(column,start_row);
  for (unsigned char i=0;i<height;i++) {
    SMS_setNextTileatAddr(addr);
    unsigned int metatile_offs=leveldata[data_offs++];
    unsigned int tile=metatiles[metatile_offs];
    SMS_setTile(tile);
    addr+=64;  // next line
  }
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Tue Jun 25, 2019 3:20 pm
Ahhh I see :3

Thank you! Gonna play around with that!
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Tue Jun 25, 2019 6:07 pm
Heyho...

So I'm already at my next question...

Can't I flip sprites? oo' I know it work for tiles - but how does it work for a sprite? Can't find a function for that....
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Tue Jun 25, 2019 8:35 pm
No, you can't flip sprites.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Tue Jun 25, 2019 8:53 pm
Maxim wrote
No, you can't flip sprites.

I... can't? But there are so many sprite sheets out there, where some frames are missing because they are a simple flip...

Well... another SMSDevKit related question...
In a tutorial I saw, that the 'teacher' was keeping track of the sprites x and y position. That makes sense to me. But when I peeked into the function SMS_updateSpritePosition I noticed, that it writes the position data into a buffer.

Why are there no functions to read those values back? I wrote one for my test game, but I wonder if it was a good idea. To me it seemed to be a duplication, that I have to keep track of those values, when SpriteTableY and SpriteTableXN do that... (I also noticed I have to do y + 1 when reading back that value)
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Tue Jun 25, 2019 9:42 pm
If you are streaming sprites into video memory for animation, then you can either flip them in software while streaming (slower) or store them both ways round. (The latter also allows you to redraw sprites asymmetrically so for example the hero keeps the gun in the same hand.)

For most games you need to translate world coordinates to screen coordinates for your sprites, so you have the former in RAM (for an entity consisting of multiple 8x8 sprites) and no need to read back the sprite table.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Wed Jun 26, 2019 5:12 am
Thanks once more x3

What exactly do you mean with streaming the animation? I just wanted to increase the tile number to make an animation go.

It seems like I focus so much on storing every possible byte, that I forget about gaining expierence... It is just so stressfull when you see the percent counter increase and you thinkg "Oh damn! I'm already at 10% and have not even animations yet" ~o~
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Jun 26, 2019 6:05 am
Jaberwocky wrote
What exactly do you mean with streaming the animation? I just wanted to increase the tile number to make an animation go.


there are basically two (main) ways to animate something on screen: one is to pre-load all the needed tiles into VRAM and use the tiles according to your frame, so for instance you load your animation from tiles 0 to 31 and you display tile 0 on one frame, then tile 1 on the next one, then tile 2... and so on.
the other approach (a.k.a. 'streaming animation') is to load just the tiles you need the next frame during the previous vblank, so you end up using always the same VRAM tile(s) (say tile 0 in our example) and you keep on updating the contents at that VRAM position. You're saving a lot on VRAM with this approach, but it requires you to spend a part of your precious vblank to copy data to VRAM (also: you can do that faster using UNSAFE functions during vblank)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Wed Jun 26, 2019 7:05 am
You have a limit of 256 different sprite tiles, or fewer if you put them in the same half of video memory as the tables. If you have a 16x24 character with 10 frames of animation facing both left and right then that's 120 tiles already before you add enemies - and most of those frames are rarely used. Many games stream in those 6 tiles for the main character, which costs a chunk of VBlank time (by which I mean offscreen area + VBlank - there's no difference between the two), but if you limit animation to say 30fps then you have every second frame to do some other video memory upload.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Jun 26, 2019 7:59 am
Maxim wrote
if you limit animation to say 30fps then you have every second frame to do some other video memory upload.


Aladdin's animation (which I believe is smooth enough) is 12.5 fps - it updates its VRAM tiles every 4th frame, so does the guard that runs after him, they just don't update their tiles the same frame.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Wed Jun 26, 2019 6:43 pm
It is impressive how much you guys know >~< I feel like a little kid, not getting a slight gasp about what is even possible >o<
I still try to be motivated >~<

So ehm... The vblank time... Is this before or after the call to SMS_waitForVBlank? Or does that not matter?

Also... can I do malloc calls in SMS games? I guess not for some reason :o
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Jun 27, 2019 7:33 am
Jaberwocky wrote
It is impressive how much you guys know


You see, we're regulars here since some time, check Maxim's 'joined' date below his name...

Jaberwocky wrote
So ehm... The vblank time... Is this before or after the call to SMS_waitForVBlank? Or does that not matter?


SMS_waitForVBlank waits until vblank starts, so what you do next is (likely) update VRAM, as you're in vblank and you can do that fast with no screen corruption.

Jaberwocky wrote
Also... can I do malloc calls in SMS games? I guess not for some reason :o


Even if it seems to me that SDCC supports that, I wouldn't do it. Use global variables as they're usually faster.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Thu Jun 27, 2019 7:51 am
sverx wrote
You see, we're regulars here since some time, check Maxim's 'joined' date below his name...

True! But still... it is impressive :3

sverx wrote
SMS_waitForVBlank waits until vblank starts, so what you do next is (likely) update VRAM, as you're in vblank and you can do that fast with no screen corruption.

When is the vblank over? Do I really care about that actually?

sverx wrote
Even if it seems to me that SDCC supports that, I wouldn't do it. Use global variables as they're usually faster.

Will do that!

As usally, thanks! And I'm still not done with my questions (I'm sorry for that)

I want to give the animation streaming a go because it really made sense to me. Until now I used a compression from bmp2tile for storing the tiles - as a bigger set.

I would now take 4 tiles, make a frame out of them and compress it, same with the next frame and so on. Is that a sensefull approach?

In general I'm getting really stressed by those compressions, simply because I have no idea how to decompress them - are there no libaries for this?

I also saw that I can use the SMSDevKit and the SDCC to compile larger ROMs and map those - but I'm right now not sure how to do that. I tried once compiling a really big tile map, but as I understood it was bigger then 16KB and so it didn't worked quite well.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Jun 27, 2019 8:01 am
Jaberwocky wrote
When is the vblank over? Do I really care about that actually?


vblank lasts less when you're using a 60Hz console (NTSC) as there are 192 active lines of 262 total (70 lines for vblank) and lasts way more on a 50Hz console (PAL) as there are still 192 active lines but out of 313 total (121 lines for vblank).
You should totally care about that as you need to ensure you update the screen on time for next frame.

Jaberwocky wrote
I would now take 4 tiles, make a frame out of them and compress it, same with the next frame and so on. Is that a sensefull approach?


If you want to stream tiles, you likely won't compress them. So just store all of them sequentially in ROM and load the ones you need. You'll likely need to learn about bank switching or you won't be able to create ROMs over 48 KB.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Thu Jun 27, 2019 8:46 am
sverx wrote
vblank lasts less when you're using a 60Hz console (NTSC) as there are 192 active lines of 262 total (70 lines for vblank) and lasts way more on a 50Hz console (PAL) as there are still 192 active lines but out of 313 total (121 lines for vblank).
You should totally care about that as you need to ensure you update the screen on time for next frame.

How do I notice that I was not in time? I can't do some time of time measurement?

sverx wrote
If you want to stream tiles, you likely won't compress them. So just store all of them sequentially in ROM and load the ones you need.

Wont I get into troubles doing that because of the limit ROM size?

sverx wrote
You'll likely need to learn about bank switching or you won't be able to create ROMs over 48 KB.

Is that a complex subject? I also thought that I only have 32KB... I always thought that "ihx2sms" tells me how much bytes out of the 32KB I used...
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Thu Jun 27, 2019 9:12 am
Most games of any graphical complexity are over 32KB. The next practical limit is 1MB which is a huge amount of space.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Jun 27, 2019 9:40 am
Basically if you keep on updating VRAM contents after vblank has completed you'll see screen tearing, or even VRAM corruption if you're loading data there using the UNSAFE devkitSMS functions. You can anyway update SAT (the sprites' data) and load a few tiles each frame with no problem even on NTSC machines.

About bank switching, I tried to make it as easy as possible with devkitSMS, but unfortunately it isn't automatic. If you use assets2banks, it will organize your data in ROM banks, 16 KB each, and you'll reference the bank number they're on using the [asset name]_bank define.

The point here is that you can see only one ROM bank at a time, apart from your program that will be in the first 32 KB, so you can have many ROM banks but you'd need to explicitly 'invoke' them

In your program, you'll use the provided SMS_mapROMBank(n) macro to map the bank you need, as in

SMS_mapROMBank(enemy_tiles_bin_bank);
SMS_loadTiles(enemy_tiles_bin,0,enemy_tiles_bin_size);
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Thu Jun 27, 2019 10:57 am
Maxim wrote
Most games of any graphical complexity are over 32KB. The next practical limit is 1MB which is a huge amount of space.

sverx wrote
The point here is that you can see only one ROM bank at a time, apart from your program that will be in the first 32 KB, so you can have many ROM banks but you'd need to explicitly 'invoke' them

So is 1MB the biggest possible size?

Ahhh! So I see, 32KB for the program + 16KB for the bank make 48KB...

With assets2bank I converted my few graphics to a bank2.h and bank2.c file. I just added them to the build process and linked the bank2.rel file later. So... I take the assest went directly into my 32KB programm memory?

If I would compile it with "--constseg BANK2" and then link it with "-Wl-b_BANK2=0x8000" I would not add it to the 32KB programm memory, is that somewhat correct?

But therefore I must use the SMS_mapROMBank function then - before using those values?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Jun 27, 2019 11:33 am
assets2banks can compile to .rel files directly so you don't need to do that yourself - yes, you can then link your bank#.rel files using one

-Wl-b_BANK#=0x8000


for each of the generated banks. That way your assets will end up *after* the 32 KB of space you won't be paging, that you'll likely use for your program.

4 MB is the theoretically biggest possible with this bank switching technique (SEGA Mapper), but Master EverDrives seems to do not support over 1 MB so you'll end up with a ROM you can't (easily) test on hardware if you go beyond that.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Fri Jun 28, 2019 9:53 am
Thanks to your answers and patience - I was able to make my player walk in all directions yesterday ^o^
That was quite amazing I thank you guys so much :3

So ehm...

More questions >_>

1.) Rand
Does the SMS support some form or random number generator? I would usally use srand and rand - but how would I generate a seed?

2.) Turn display off
If I turn the display (with the specific function) off - then I can mess around with the VRAM for as long as I want, correct?

3.) Compression
Sorry for brining that subject up again, but... do I really need to pay so much attention on compression? I learned now, that I should not use compression for animation streaming and also should not use if for meta tiled maps.
So when do I use it then? @_@
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Jun 28, 2019 10:06 am
1 - SMS has no way to create a good seed. For what is worth I never had to use a real RNG, I just generate a LUT with some 256 entries and it's usually enough.

2 - Yes

3 - You can compress tiles data, for instance. Or you can compress static tilemaps. Check BMP2Tile options. The point is that compression can be useful - of course only when it's not impeding.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Fri Jun 28, 2019 10:47 am
1.) That website is awesome :O Thanks!
But a stupid question... How can I pick up a random number from the LUT? I can't generate a random index value, so I would always use the same pattern like LUT[0], LUT[3], LUT[45] and so on...

3.) I really have difficulties deciding this... Is it not a good approach to generaly compress maps and then decompress them fully to a big enough buffer when needed?

Also... are there no libaries out there to help with decompressing those compressions like the Sonic one and so on?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Jun 28, 2019 11:56 am
Jaberwocky wrote
How can I pick up a random number from the LUT?


you just take the 'next' from there as in
#define FAKE_RAND()  (LUT_fake_rand[fake_rand_index++])


As for decompression, devkitSMS currently supports only a few of them:

/* functions to load tiles into VRAM */
void SMS_loadPSGaidencompressedTiles (void *src, unsigned int Tilefrom);

/* UNSAFE macros to load compressed tiles into VRAM (can be safely used only when screen is off) */
UNSAFE_SMS_loadaPLibcompressedTiles(src,tilefrom);
UNSAFE_SMS_loadZX7compressedTiles(src,tilefrom);


and, honestly, I'd stick with those...
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Fri Jun 28, 2019 12:16 pm
sverx wrote
you just take the 'next' from there as in
#define FAKE_RAND()  (LUT_fake_rand[fake_rand_index++])

I understand that, but after restarting the console, I would get the same random values again right?


sverx wrote
/* functions to load tiles into VRAM */
void SMS_loadPSGaidencompressedTiles (void *src, unsigned int Tilefrom);

/* UNSAFE macros to load compressed tiles into VRAM (can be safely used only when screen is off) */
UNSAFE_SMS_loadaPLibcompressedTiles(src,tilefrom);
UNSAFE_SMS_loadZX7compressedTiles(src,tilefrom);


and, honestly, I'd stick with those...

But those uncompresse the data directly to the VRAM, when uncompressing my meta tiled map, I would have to target a local buffer...

So... Seems like I should not do compression?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Jun 28, 2019 12:32 pm
Jaberwocky wrote
I understand that, but after restarting the console, I would get the same random values again right?


The tricky part is still to find some way to seed it (initialize fake_rand_index). In Weka Invaders I'm counting frames in the menu screen, and I'm using that.
If you want something more complex, you could xor that with lower byte of SMS_getKeysStatus() at each frame so to add some more entropy...

You mean decompression to RAM? I've hardly seen that - RAM is quite small and LZ-based compression is a bit over-killing. You can create a custom compression tailored to your data... or we can try adding something to the library but I'm lacking good ideas atm.
  View user's profile Send private message Visit poster's website
  • Joined: 01 Feb 2014
  • Posts: 844
Reply with quote
Post Posted: Fri Jun 28, 2019 12:45 pm
Jaberwocky wrote
I understand that, but after restarting the console, I would get the same random values again right?

In my games I have a continuous frame counter that gets incremented once each vblank phase. This can be useful for many things, but it‘s also a good way to seed your rnd function. Simply read the counter value when the player hits the start button, and you‘re pretty much guaranteed to have a different seed each time.
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Fri Jun 28, 2019 2:32 pm
It's not unusual to decompress levels to RAM, especially if they can change (eg Sonic does this to store which metatiles contain rings). It's just a question of how much you use - it's actually really hard to use up 8KB, so Sonic uses 4KB for the level. Micro Machines uses a large chunk of RAM for code as well as decompressing the level data there (and it doesn't ever edit it). (But then Micro Machines is quite weird anyway.)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Jun 28, 2019 5:24 pm
I wonder... do we have a nice format that comes with compressors and z80 asm decompression routines already at hand? Yeah, I'm lazy.

aPLib maybe?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Fri Jun 28, 2019 5:57 pm
Huh? We have all that, in particular ZX7 seems to be a good general choice.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Jun 28, 2019 7:49 pm
ZX7decompression (to RAM) on the way...

@Jaberwocky: interested in beta testing that?
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Sat Jun 29, 2019 10:29 am
sverx wrote
ZX7decompression (to RAM) on the way...

@Jaberwocky: interested in beta testing that?

In general I would :3
But I would refuse for now, because I'm way to unexpierenced with all that stuff for my own liking. I noticed yesterday and today, that there is a lot I have to learn.

I failed miserably in making my screen scroll yesterday >~<

Well in the end it scrolled but only along the X-Axis and I disliked the code I wrote...

I'm actually a C++ programmer, so going to C is... more different then I remembered xO Overall I'm kinda frustrated currently, but that is normal when learning new things.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Jun 29, 2019 10:34 am
to code an 8-way scrolling background engine ins't an easy feat for sure

as for C... well, we got no classes here. But I would say it's a simple language to learn, after all.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Sat Jun 29, 2019 11:23 am
sverx wrote
to code an 8-way scrolling background engine ins't an easy feat for sure

But so many games I recall do support it... Or I think they do...
I mean there are those games where you can't go back - and I guess this is related to the scrolling


sverx wrote
as for C... well, we got no classes here. But I would say it's a simple language to learn, after all.

Well it effects how I design my program, but also I miss templates, overloading and link time optimization.
Also I'm more familiar with the Clang compiler, then SDCC - but all in all it is just practice
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Jun 29, 2019 12:57 pm
A forward only scroll engine is much easier, and you can even keep the data compressed in ROM and decompress them as you need them, as in Kagesan's Flight of Pigarus: it's a one-way scroll (vertical, scrolling down only) using meta-tiles and RLE compressed level data.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Sat Jun 29, 2019 1:58 pm
sverx wrote
A forward only scroll engine is much easier, and you can even keep the data compressed in ROM and decompress them as you need them, as in Kagesan's Flight of Pigarus: it's a one-way scroll (vertical, scrolling down only) using meta-tiles and RLE compressed level data.


Oh woah that game has some awesome graphics °O°
I should really keep trying, maybe I end up with uploading a game somewhen x3

I honestly need to do at least one background scroller myself, otherwise I will not bw happy :/ Because when I have done some code, it is easier for me to understand what others did...
But to be really honest, I also have to accept that I'm not good at the moment and need more practice xO

I hope it is accepteable to share my progress here x3
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Sat Jun 29, 2019 2:27 pm
You can take a look at how Psidum did his GSLib:

https://bitbucket.org/Psidum/gslib/src/master/

Although I've to say he has a v2 in the works
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Sat Jun 29, 2019 2:51 pm
Thank you kusfo :3

I noticed that basicly everyone uses inline assembly at one point for there project...
I wonder... am I actually capable to write a good SMS game with the SDCC or should I also focus on doing more stuff in assembly?
I already read a short post that C compiler have a hard time creating good code for the Z80...
  View user's profile Send private message
Reply to topic Goto page 1, 2, 3  Next



Back to the top of this page

Back to SMS Power!