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 - devkitSMS - develop your homebrew in C

Reply to topic Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8  Next
Author Message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 11824
  • Location: London
Reply with quote
Post Posted: Wed Jun 29, 2016 7:36 am
It depends if you can pass alignment hints to the underlying bits. It complicates the code packing so fixed addresses may be easier. The compiler probably still needs some help to make use of that alignment.

For reference, looking up is ld h,<lookup; ld l,index; ld a,(hl). If you're walking through the table, using pointers will be better - inc hl; ld a,(hl).
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Wed Jun 29, 2016 7:54 am
I haven't yet tried using 256-bytes address aligned LUTs, but you can shave an instruction off in your case using an unsigned int index (thus you will at least save the zeroing of the high byte).

About the PSGSilenceChannels and PSGRestoreVolumes, yes, they work on all the PSG channels. It's meant for creating a silenced pause in the game, as when you press the 'pause' button. When you 'un-pause' you'll then restore the volumes and continue on hearing the music and SFXs that were going on before the pause.
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 105
Reply with quote
Post Posted: Wed Jun 29, 2016 8:55 am
sverx wrote
I haven't yet tried using 256-bytes address aligned LUTs, but you can shave an instruction off in your case using an unsigned int index (thus you will at least save the zeroing of the high byte).


Are you saying that using a 16 bits index would be faster than using a 8 bits index in an 8 bit system? That sounds odd. Specially when you have to increment the index, or operate with it, later on. Of course, I'm not an expert in SDCC and the code it generates, so it just strikes me a bit.

I can try and align some structures to bench mark - but I haven't been able to find documentation on this. All I found is instructions to manually specify addresses for variables, but that's not what I'm looking for.

I've been thinking that maybe allocating the SpriteTableY and SpriteTableXN arrays in SMSlib in a fixed RAM address on a 256 byte boundary would maybe speed up things a bit? Do you have any thoughts on this? Both arrays are < 256 bytes. Does SDCC notice this and performs the required optimization (as in increasing only "L" disregarding "H" in the pointer)?

Wouldn't sprite definition functions benefit from a rewrite using pure, hand optimized assembly and fixed RAM addresses? In a game you spend quite a bit fiddling with the SAT, maybe this would bring big improvements to the library in terms of speed.


Quote
About the PSGSilenceChannels and PSGRestoreVolumes, yes, they work on all the PSG channels. It's meant for creating a silenced pause in the game, as when you press the 'pause' button. When you 'un-pause' you'll then restore the volumes and continue on hearing the music and SFXs that were going on before the pause.


Yes, that's how I will be using it, but I used to have a "PAUSE sound" which would be silenced as well using this method. Nothing major, though, but if you are thinking on enhancing the lib, a pause/resume function just for the music will come up handy.

Also for the dead sequence, where you play a sound when the player gets hit and pause the action (without music playing) for a split second.

~~

As for the aligning issue,
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Wed Jun 29, 2016 9:14 am
na_th_an wrote
Are you saying that using a 16 bits index would be faster than using a 8 bits index in an 8 bit system? That sounds odd.


Well, no, I'm not pushing it that far :) I was just saying that if the index you're using it's an unsigned int you'll save an instruction. Of course there are downsides, as you suggested. Let's say that if you need to access many LUTs using the same index that you'll increment just once every frame, then the cost of incrementing that unsigned int will be soon canceled by the saving you'll have when accessing the LUTs ;)

As for the alignment, I need to check a bit more but so far I haven't seen anything like that, yet, in SDCC. We might suggest an improvement, thou, they might consider that and eventually add it (as they did with preserve_regs function attribute).

edit: SDCC manual, page 42:
Quote
For some architectures (mcs51) array accesses are more efficient if an (xdata/far) array starts at a block (256 byte) boundary.

which to me it means we haven't got this feature in z80 architecture, yet :|
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Sun Jul 03, 2016 12:36 pm
I posted an new topic in Open Discussions on SDCC forum about the array alignment/fast access... let's see if the guys there have some good ideas and/or they will consider of adding such a cool feature :)
  View user's profile Send private message Visit poster's website
  • Joined: 07 Oct 2015
  • Posts: 105
Reply with quote
Post Posted: Sun Jul 03, 2016 9:05 pm
Thank you. That would be a great feature :)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Thu Jul 07, 2016 12:45 pm
na_th_an wrote
is there a way to pause a song using psglib and then resume it from the same point it was paused, instead of having to stop it and restart it from the beginning?


I just realized that there's already a way to do what you're asking: you've got to use: PSGSetMusicVolumeAttenuation to silence the music, and avoid calling PSGFrame, so that it doesn't go on silently.
When resuming, you just call PSGSetMusicVolumeAttenuation again to restore the tune's desired volume and start calling PSGFrame again, as usual.
Well, it should work ;)
  View user's profile Send private message Visit poster's website
  • Joined: 01 Jul 2016
  • Posts: 55
Reply with quote
Post Posted: Fri Jul 15, 2016 5:43 pm
I saw some weeks ago a way to use WLA DX mixed with devkitSMS to handle the banks
Unfortunatly, I didn't bookmark it :(

Did someone read it somewhere ?
I'd like to get more controls with banks than with the folder2c tool (no offence)
  View user's profile Send private message Visit poster's website
  • Joined: 04 Jul 2010
  • Posts: 198
  • Location: Angers, France
Reply with quote
Post Posted: Fri Jul 15, 2016 7:02 pm
You certainly read that in my Cimmerian "diary" ;)
But unfortunately, I'm not using the Sverx's SDCC library.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Sat Jul 16, 2016 4:10 am
I would say folder2c doesn't handle banks at all, in fact you have to allocate assets yourself, placing them in different folders so that they get mapped to different banks. Of course the third option (bank number) can help later when referencing the asset's bank from your code, but that's everything you can do actually.
I am thinking about creating an additional tool, I'm curious what would be useful, beside having the equivalent of WLA-DX "superfree" assets. You need more control than that? You need other features? Let me know, as I still never faced serious problems with my tools (yes, I do allocate assets on banks 'by hand', by moving them to different folders, usually as soon as one folder's content reach 16KB...)
  View user's profile Send private message Visit poster's website
  • Joined: 30 Mar 2009
  • Posts: 205
Reply with quote
Post Posted: Tue Jul 19, 2016 3:47 pm
Hi, sorry to ask, but i need some help.

I'm trying to create a background image with looping music. So, i created this code:


void main(void) {
   SMS_displayOff();
   loadScreen(screen_1__tiles__psgcompr, screen_1__tilemap__stmcompr, screen_1__palette__bin);
   PSGPlay(ab_psg);
   SMS_displayOn();
   
   while(true) {
      PSGFrame();
   }


loadScreen is just a function that calls the tile/stm/palette loading..
The image is appearing fine, i even did some tests cycling palettes and changing screens on button presses, all worked fine.

So, i went to add music.

The song "plays", but it only loops the first half a second of so.
I tried a bunch of files, converted them to psg, tried to compress them, then i tried to use a commercial vgm (the ab one is from the afterburner pack here on sms). Same results.
So i remembered sverx entry for the rush comp last year. I downloaded that source, tried with that .psg, same results.

I'm trying to compile 'not-enough-time' but it doesn't work properly.

Any idea of what i did wrong?

Thanks.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 308
  • Location: Spain
Reply with quote
Post Posted: Tue Jul 19, 2016 3:49 pm
You need to have a waitVblank before calling each PSGFrame, otherwise, you're calling all the PSGFrames in less than half a second!! :-D
  View user's profile Send private message
  • Joined: 30 Mar 2009
  • Posts: 205
Reply with quote
Post Posted: Wed Jul 20, 2016 5:16 pm
Oh man, it was that simple. haha.

I completely ignored all the mentions of VBlank because i still haven't messed with sprites.

So, just to be clear.
My code as it was, was calling PSGFrame as fast as the cpu could manage at that point in time? (whatever that number would be..)

And waiting for vblank, means that i am only calling it 60 times per second?

Thanks kusfo. :)
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 308
  • Location: Spain
Reply with quote
Post Posted: Wed Jul 20, 2016 7:59 pm
tibone wrote
Oh man, it was that simple. haha.

I completely ignored all the mentions of VBlank because i still haven't messed with sprites.

So, just to be clear.
My code as it was, was calling PSGFrame as fast as the cpu could manage at that point in time? (whatever that number would be..)

And waiting for vblank, means that i am only calling it 60 times per second?

Thanks kusfo. :)


That's exactly the point!

One of the good things about waiting the Vblank is that it allows to sincronize all the game, then you don't need to mess with deltas or anything.
  View user's profile Send private message
  • Joined: 30 Mar 2009
  • Posts: 205
Reply with quote
Post Posted: Fri Jul 22, 2016 2:20 pm
I'm making some mistake creating tilemaps for sets that are smaller than full screen.

I'm trying to mixup two tile sets on the same screen.
One for fonts, using haroldo's putchar and load_font code.
It works fine.

Then i load my own tiles, starting on tile 96. I create the tiles and tilemap in bmp2tile using "start index at: 96". The tiles appear to be correct, according to the tileviewer on emulicious.
But the map is screwed up.
I'm trying to load a character portrait that is 64x64 pixels. But the tiles are spread across the entire screen. (in order, from left to right). Not following the map.

I tried using both compressed and uncompressed tiles and tilemap. Same result. If i manually place each tile, i can create the picture, without a problem, but that's a load of trouble, because tiles aren't created in order, so i can't just loop through the numbers.

I tried creating the tiles with and without removing duplicate and mirroring, but both created the same result.


void loadScreen(char* tileName, char* tilemapName, char* paletteName) {
   SMS_displayOff();
   SMS_loadPSGaidencompressedTiles(tileName, 96);
   SMS_loadSTMcompressedTileMap(5,10, tilemapName);
   SMS_loadBGPalette(paletteName);
   SMS_displayOn();
}

loadScreen(tileset1__tiles__psgcompr, tileset1__tilemap__stmcompr, tileset1__palette__bin);



Produces the attached result.
I also attached a zip with the converted assets.
tilemap_error.png (77.86 KB)
tilemap_error.png
bugged_tiles.zip (796 B)

  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 308
  • Location: Spain
Reply with quote
Post Posted: Fri Jul 22, 2016 2:32 pm
When you're loading a tilemap, it updates the tile positions sequentially. So in your case, it starts on the 5,10 position, and it follows with the 6,10, the 7,10 until it reaches the 32th column, when it restarts at 0,11.
  View user's profile Send private message
  • Joined: 30 Mar 2009
  • Posts: 205
Reply with quote
Post Posted: Fri Jul 22, 2016 3:34 pm
So, the tilemap is always sequential ?

I thought that reason behind having a tilemap was to place tiles out of sequence. Perhaps i overestimated tilemaps?

If it will always be displayed sequentially, what is the advantage of using a tilemap, instead of placing tiles manually, only for full screen scenes?
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 308
  • Location: Spain
Reply with quote
Post Posted: Fri Jul 22, 2016 3:43 pm
The advantage is not to build the tilemap by hand, as it fins repeated tiles, etc. And it's useful when it takes full rows (you can merge to different tilemaps if they are 32 column wide)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Sat Jul 23, 2016 5:00 am
tibone wrote
the map is screwed up.
I'm trying to load a character portrait that is 64x64 pixels. But the tiles are spread across the entire screen. (in order, from left to right). Not following the map.


In such cases you could use uncompressed tilemaps (but you can use compressed tiles!) and the
void SMS_loadTileMapArea (unsigned char x, unsigned char y,  unsigned int *src, unsigned char width, unsigned char height);

so to place a map of width*height tiles at (x,y). 'src' parameter is the map :)

edit: STMcompressed maps can't (still?) be used for storing maps not using whole lines. My bad.
  View user's profile Send private message Visit poster's website
  • Joined: 30 Mar 2009
  • Posts: 205
Reply with quote
Post Posted: Mon Jul 25, 2016 12:21 pm
sverx wrote
In such cases you could use uncompressed tilemaps (but you can use compressed tiles!) and the
void SMS_loadTileMapArea (unsigned char x, unsigned char y,  unsigned int *src, unsigned char width, unsigned char height);

so to place a map of width*height tiles at (x,y). 'src' parameter is the map :)

edit: STMcompressed maps can't (still?) be used for storing maps not using whole lines. My bad.


Thanks sverx, using uncompressed tilemap, it worked perfectly. I just tested with the same 64x64 and it loaded it perfectly. This will allow me to reduce the number of tiles used, since i plan on loading of lots of pictures into my game. :)
  View user's profile Send private message Visit poster's website
  • Joined: 30 Mar 2009
  • Posts: 205
Reply with quote
Post Posted: Thu Aug 04, 2016 3:36 pm
sverx wrote
Standard libraries provide already a way to generate random numbers, as Maxim pointed out. BTW they're quite slow so you either use them only when it's not time-critical (e.g. when preparing the level) or you can use them to populate an array with values you'll use later.
As for me, I'm always fine enough with a very simple approach: a 256 bytes array in ROM, filled with random values (taken from here for instance) and a simple macro:

#define FAKE_RAND()  (LUT_fake_rand[fake_rand_index++])


edit: of course fake_rand_index is an unsigned char


Do you mind expanding a bit on this?
Every single use of rand() i find, rely on either using time, or using pid to seed.
Since the SMS doesn't have a internal clock nor a pid, i'm kinda of stuck here. What i did is create a int and increase it every frame, reseting it once it reaches 15000 (this could go up to 32766, right?). This allows me to create some random values. Since the seed would be changing each frame. It works for what i would need. But i'm wondering if there's a better way to do this, in the case of the SMS?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 11824
  • Location: London
Reply with quote
Post Posted: Thu Aug 04, 2016 4:34 pm
Your source of entropy is the user. Assuming your PRNG is fast and good, just pump numbers out of it during the title screen. The time the user takes to press start will pick probably different values each time. If you want to be more extreme, pump a different number of numbers out based on the user inputs, for every frame.

sverx was suggesting a way to get a fast PRNG, maybe a few dozen clock cycles.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Thu Aug 04, 2016 7:10 pm
Yes, no way to have a good random seed on a SMS. Maxim suggestion is surely the one I would choose.
Maybe additionally reading the Vcount register at start can lead to a little added variability, but I never tried that actually...
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 11824
  • Location: London
Reply with quote
Post Posted: Thu Aug 04, 2016 10:32 pm
The r register also has a bit of variation due to the power up reset warm up delay thing. Not in an emulator, though.
  View user's profile Send private message Visit poster's website
  • Joined: 01 Feb 2014
  • Posts: 347
Reply with quote
Post Posted: Fri Aug 05, 2016 3:54 pm
Maxim wrote
The r register also has a bit of variation due to the power up reset warm up delay thing. Not in an emulator, though.

Speaking of real hardware, does it make a different at which point the r register is read to seed the rnd? Does it have to be right at startup or can it be anytime later? And does it only produce different results on a hard reset or does pressing the reset button produce different results as well?

I'm asking because I'd like to have a somewhat random seed at a point in my program before there's any user interaction. It's not essential, so I couldn't care less if it's always the same in emulators, but it would be nice to have some variety nonetheless.
  View user's profile Send private message
  • Joined: 30 Mar 2009
  • Posts: 205
Reply with quote
Post Posted: Fri Aug 05, 2016 5:00 pm
Good to know, my idea of using the title screen as a way to creating some variety was not wrong. :)
I'm just updating a int, increasing it by 1 each frame. Then i use that number as my seed.

I haven't tested my code in the real hardware yet, but i assume it won't be too slow, since it doesn't slowdown in Emulicious ?
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Fri Aug 05, 2016 9:28 pm
tibone wrote
I haven't tested my code in the real hardware yet, but i assume it won't be too slow, since it doesn't slowdown in Emulicious ?


If you're not using UNSAFE functions at all (or at least when it's not safe to do so) then you should NOT see any difference on hardware. If you see some, I would like to know it, since it means there could be a bug in my devkit/lib

@Kagesan: it really doesn't change, but don't expect great variability from that register.
Also probably on the same hardware specimen I expect it won't likely never change anyway :|
  View user's profile Send private message Visit poster's website
  • Joined: 17 Nov 2015
  • Posts: 91
  • Location: Canada
Reply with quote
Post Posted: Mon Aug 15, 2016 1:32 pm
sverx wrote
Before even thinking about developing a devkit, I read some docs about how SDCC 'outperformed' z88dk. Also, when I started reading SDCC docs I had the impression I would obtain transparent ROM paging using that. Unfortunately that's (not) true but still very embryonic, so I choose not to use it.


The comparisons were written by someone unfamiliar with both compilers.

sdcc can be thought of as the gcc of the z80 world and z88dk can be thought of as the glibc of the z80 world.

The C library that comes with sdcc is a minimal subset expected by embedded programmers. It's written in C so that it's portable across all of sdcc's targets. The C library that z88dk provides tries to be complete and is implemented in assembly language. In terms of number of functions, it's several times larger than sdcc's library.

Because z88dk's library is written in assembly language it's faster and at least three times smaller than sdcc's library. The reason that things like z88dk_fastcall, z88dk_callee and register preservation info were added to sdcc was to make it compatible with the z88dk libraries.

sdcc has been taken on board as one of the compilers inside z88dk. z88dk's version, zsdcc, has been modified :- the peephole optimizer has been bug-fixed to properly identify registers in asm instructions and this has allowed a new set of ~800 peephole rules to be created to improve sdcc's output code. New --opt-code-size rules have been added to reduce size for code using 64-bit integers, 32-bit integers and floats. In addition to that all of sdcc's compiler primitives (integer multiply, divide and so on) have been written in asm to use callee linkage rather than standard. Besides compiler improvements, the libraries have been modified to accommodate sdcc's register preservation attribute and to use fastcall and callee linkage everywhere.

The modified sdcc together with z88dk's library results in programs anywhere from 5% to 50% smaller depending on the program. The high numbers come from significant use of library code (using floats is a quick way to achieve large comparable size reduction). Programs tend to be noticeably faster as well.

In terms of the backend tools, z88dk is much simpler to use and has a more flexible building chain. But it lacks documentation. You can have a look at some information on the generic embedded target here: http://www.z88dk.org/wiki/doku.php?id=libnew:target_embedded

These results are from collaboration between sdcc (Philip primarily) and z88dk. Anyway back to your regular programming :)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 11824
  • Location: London
Reply with quote
Post Posted: Mon Aug 15, 2016 4:15 pm
I think they were more about the original z88dk compiler, from the really old days. Things have come a long way since then. (I remember it from when it was a project to get TCP/IP on the Z88, which is rather a long time ago... My Z88 is still around here somewhere.)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Tue Aug 16, 2016 8:36 am
devkitSMS isn't tightly bound with SDCC... if z88dk can compile SMSlib sources out-of-the-box then probably I can make the whole project independent from SDCC...
Also, if it now generates smaller and faster code than SDCC, why not suggesting it as the compiler of choice? :)
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 55
Reply with quote
Post Posted: Tue Aug 16, 2016 7:36 pm
How do i load content from a text file, into an array?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Wed Aug 17, 2016 8:05 am
Orlan Rod wrote
How do i load content from a text file, into an array?


Being the Master System "ROM based" (not "FileSystem based") there's no file loading at all. Said that, you can have your assets added to your ROM using the folder2c tool, for instance. That means: say you've got a 'level0.txt' file into your levels folder and you run folder2c on that folder: you'll get both a levels.c (containing the data - you'll compile this to levels.rel and link it later with your code and the library) and a levels.h (containing the declarations you need - you'll include this in your game's source file) ... and you'll have your declarations/defines ready:

extern const unsigned char level0_txt[];
#define level0_txt_size 165


and you'll simply have to read from the level0_txt array.
  View user's profile Send private message Visit poster's website
  • Joined: 01 Jul 2016
  • Posts: 55
Reply with quote
Post Posted: Wed Aug 17, 2016 11:15 am
Hi

I started for real 2 days ago (with the help of lovely GeanyIDE) and so, I'll probably come here for some questions if you don't mind ;)

My first one will be about the input.
Any idea why SMS_getKeysXXX() are functions and not macros ?
I ask because I learnt to avoid any unnecessary call / register save on genny the hard way ;)
I now use (too much?) macros and inline functions for few lines code.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Wed Aug 17, 2016 11:29 am
KanedaFr wrote
Any idea why SMS_getKeysXXX() are functions and not macros?


Well, it's a valid suggestion. Anyway given that you'll call these functions no more than once per frame (no use to call them more often) then it won't change that much, performance wise.
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 55
Reply with quote
Post Posted: Wed Aug 17, 2016 3:10 pm
Tried it, but the array is empty. I have a level1.txt file, with these values
"1 1 1 1 1 1" Its in the assets folder, and than i run the bat file. I see that i it is in the assets.rel.

I loaded the tiles in memory, and this is the bits of code i have for reading the array.

"
unsigned char aLoopX = 0;
extern const unsigned char level1_txt[];

#define level1_txt_size 64

for(aLoopX = 0; aLoopX<5; aLoopX++){
SMS_setNextTileatXY (aLoopX,0);
SMS_setTile(level1_txt[aLoopX]);
}
"

sverx wrote
Orlan Rod wrote
How do i load content from a text file, into an array?


Being the Master System "ROM based" (not "FileSystem based") there's no file loading at all. Said that, you can have your assets added to your ROM using the folder2c tool, for instance. That means: say you've got a 'level0.txt' file into your levels folder and you run folder2c on that folder: you'll get both a levels.c (containing the data - you'll compile this to levels.rel and link it later with your code and the library) and a levels.h (containing the declarations you need - you'll include this in your game's source file) ... and you'll have your declarations/defines ready:

extern const unsigned char level0_txt[];
#define level0_txt_size 165


and you'll simply have to read from the level0_txt array.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Wed Aug 17, 2016 3:21 pm
Orlan Rod wrote
Tried it, but the array is empty. I have a level1.txt file, with these values
"1 1 1 1 1 1" Its in the assets folder, and than i run the bat file. I see that i it is in the assets.rel.


Be aware that the binary content of your file has been added, so you actually have an array of ASCII chars in there, so values should be something like 0x31 (the '1') and 0x20 (the space) and so on... so you might want to map these values to the tiles in your VRAM.

Also, you should simply
#include "assets.h"

as you don't need to declare everything in your assets by hand here, that's what header files (.h) are for.
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 55
Reply with quote
Post Posted: Wed Aug 17, 2016 3:50 pm
Oh yeah, i see it in the .h. Right, i updated the code.

Ah okay, than i need some way to convert the binary.

sverx wrote
Orlan Rod wrote
Tried it, but the array is empty. I have a level1.txt file, with these values
"1 1 1 1 1 1" Its in the assets folder, and than i run the bat file. I see that i it is in the assets.rel.


Be aware that the binary content of your file has been added, so you actually have an array of ASCII chars in there, so values should be something like 0x31 (the '1') and 0x20 (the space) and so on... so you might want to map these values to the tiles in your VRAM.

Also, you should simply
#include "assets.h"

as you don't need to declare everything in your assets by hand here, that's what header files (.h) are for.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Wed Aug 17, 2016 5:33 pm
If you need to create a (small) array 'by hand' you're probably better doing it the straightforward way:
const unsigned char my_array[6] = {1,1,1,1,1,1};

if instead this is a tilemap, you better draw an image and convert it to tiles and tilemap with BMP2Tile, as I did in my example/tutorial
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 55
Reply with quote
Post Posted: Wed Aug 17, 2016 8:39 pm
It's for a tilemap that is 3 screens wide. But yeah, i guess i could just manually type the tilemap data in for now. Loop through the first 32 tiles, than update as the player moves.

sverx wrote
If you need to create a (small) array 'by hand' you're probably better doing it the straightforward way:
const unsigned char my_array[6] = {1,1,1,1,1,1};

if instead this is a tilemap, you better draw an image and convert it to tiles and tilemap with BMP2Tile, as I did in my example/tutorial
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Wed Aug 17, 2016 9:19 pm
Orlan Rod wrote
It's for a tilemap that is 3 screens wide. But yeah, i guess i could just manually type the tilemap data in for now.


No, really you don't have to. Draw the whole background and convert it into PSGaiden compressed tiles and an uncompressed tilemap, then load 32 entries for each line from it.
To scroll, you then will have to load and update a column. See the tutorial thread, there's an example of how to do (a vertical) scroll. Horizontal isn't that much more complex anyway.
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 55
Reply with quote
Post Posted: Thu Aug 18, 2016 1:06 am
I tried the tutorial, but i think it was loading more than 32. I put the same info from the tutorial.

"SMS_loadTileMap(0, 0, moltaarea1__tilemap__bin, 32*25*2);"

sverx wrote
Orlan Rod wrote
It's for a tilemap that is 3 screens wide. But yeah, i guess i could just manually type the tilemap data in for now.


No, really you don't have to. Draw the whole background and convert it into PSGaiden compressed tiles and an uncompressed tilemap, then load 32 entries for each line from it.
To scroll, you then will have to load and update a column. See the tutorial thread, there's an example of how to do (a vertical) scroll. Horizontal isn't that much more complex anyway.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Thu Aug 18, 2016 7:50 am
If your tilemap is wider than 32 tiles (and it is) you should load 32 tiles a time as in this pseudocode:

for each line on screen:
  SMS_loadTileMap (0, the_current_line, &your__tilemap__bin[the_current_line * tilemap_width *2], 32*2)


that is getting only 32 tiles each 'tilemap_width' tiles.

Try this, when it works then we will discuss about how to properly h-scroll :)

edit: also note how we had to multiply by two both the array index (the array is declared as of unsigned char but it in fact contains unsigned int) and the amount of data we need to move (32 tiles of two bytes each)
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 55
Reply with quote
Post Posted: Thu Aug 18, 2016 3:53 pm
I DID IT SVERX! *dances* xD

Okay, now how do i update the columns for the second screen of tiles.

Also, how do i blank the right most column? I did it to left most.

sverx wrote
If your tilemap is wider than 32 tiles (and it is) you should load 32 tiles a time as in this pseudocode:

for each line on screen:
  SMS_loadTileMap (0, the_current_line, &your__tilemap__bin[the_current_line * tilemap_width *2], 32*2)


that is getting only 32 tiles each 'tilemap_width' tiles.

Try this, when it works then we will discuss about how to properly h-scroll :)

edit: also note how we had to multiply by two both the array index (the array is declared as of unsigned char but it in fact contains unsigned int) and the amount of data we need to move (32 tiles of two bytes each)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Thu Aug 18, 2016 7:22 pm
Blanking the leftmost column is the correct thing to do... also because it's the only option supported by hardware.
Now you should scroll using
void SMS_setBGScrollX (unsigned char scrollX);

and while scrolling you should update the column of tiles that it's going to appear when your scroll reach 8 pixels.
To update a column there's only one way: make a for cycle to update each tile in a column as in
for row
  SMS_setNextTileatXY (the_column, the_row);
  SMS_setTile (the_tile_that_should_go_there);

of course you should pick the correct tile from your map... you can check this post, fellow user zenac did something similar already :)
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 55
Reply with quote
Post Posted: Thu Aug 18, 2016 11:06 pm
Hmm. How would i setTile so it starts at the end of the first tile after the first 256px?

sverx wrote

To update a column there's only one way: make a for cycle to update each tile in a column as in
for row
  SMS_setNextTileatXY (the_column, the_row);
  SMS_setTile (the_tile_that_should_go_there);

of course you should pick the correct tile from your map... you can check this post, fellow user zenac did something similar already :)
  View user's profile Send private message
  • Joined: 17 Nov 2015
  • Posts: 91
  • Location: Canada
Reply with quote
Post Posted: Fri Aug 19, 2016 6:38 am
sverx wrote

devkitSMS isn't tightly bound with SDCC... if z88dk can compile SMSlib sources out-of-the-box then probably I can make the whole project independent from SDCC...


Some things would have to be changed because there are some low level aspects built into SMSlib's source.

I think I will have some time tomorrow so I may try to put together an adaptation of SMSlib and an SMS target based on what you have in your repo so anyone interested can test for themselves.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Fri Aug 19, 2016 8:10 am
Orlan Rod wrote
Hmm. How would i setTile so it starts at the end of the first tile after the first 256px?


Pardon? :| BTW SMS_setTile put a tile at the currently pointed location, what sets the location is SMS_setNextTileatXY.
The tilemap is 32x28 and it's wrapping, so the 33th (X=32) column is in fact the 1st one (X=0). Think of it as a modulus 32.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Fri Aug 19, 2016 8:12 am
Alcoholics Anonymous wrote
I think I will have some time tomorrow so I may try to put together an adaptation of SMSlib and an SMS target based on what you have in your repo so anyone interested can test for themselves.


Please do! I'll be very interested to see which changes are necessary... I can surely put in some conditional defines for supporting both compilers with the same source code.
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 55
Reply with quote
Post Posted: Fri Aug 19, 2016 7:46 pm
Sorry if i wasn't clear. I know what setNextTileatXY does. I mean with the setTile function, how would i go about choosing the column with level data positioned past the 32 tiles in width of the tilemap. Screen two's first column.

I don't think i get how to work with loading parts of the map data, and knowing what values will get me those exact group of tiles i want.

sverx wrote
Orlan Rod wrote
Hmm. How would i setTile so it starts at the end of the first tile after the first 256px?


Pardon? :| BTW SMS_setTile put a tile at the currently pointed location, what sets the location is SMS_setNextTileatXY.
The tilemap is 32x28 and it's wrapping, so the 33th (X=32) column is in fact the 1st one (X=0). Think of it as a modulus 32.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 1914
Reply with quote
Post Posted: Sat Aug 20, 2016 6:26 pm
If your map is, say, 96 tiles wide and 24 tiles tall, your tilemap is 96*24*2 bytes and the tiles are stored as successive lines, the way you read a book, you see.
So the tile at x,y in your map is stored at position y*width+x, and since we've got a byte array the address is (y*width+x)*2
That's what you need for your setTile
  View user's profile Send private message Visit poster's website
Reply to topic Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8  Next



Back to the top of this page

Back to SMS Power!