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 ... 7, 8, 9, 10, 11 ... 14, 15, 16  Next
Author Message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Nov 30, 2017 4:52 pm
Last edited by sverx on Tue May 29, 2018 11:21 am; edited 1 time in total
Kagesan wrote
So, what does that mean for us oldschoolers who wish to keep using PSGlib from within our assembler code?


I suggest you keep the current version of PSGlib library, tools and assets with your existing projects (and current projects possibly) and switch to the new version with your next project - this is the "zero burden" approach.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Tue Dec 19, 2017 10:25 am
I thought that I saw somewhere in this topic an estimate about how many cycles functions like SMS_setNextTileatXY, SMS_setTile take, and how it compares to SMS_loadTiles. But I've not found it anywhere.

I'll explain what I want to know with an example: what would be faster? Changing six non contiguous positions in the tilemap or loading three non contiguos tiles to VRAM? (because each tile I want to change, it's repeated twice)

In my first thought, I think It'll be faster to update the nametable, but just to be sure...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 19, 2017 10:33 am
ah, nice question! I will run a few tests and tell you later :)

(I'd guess it's "changing six non contiguous positions in the tilemap" given they're at fixed locations, thus no math required to find the spot)
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Tue Dec 19, 2017 10:43 am
I'll clarify my need as:
+I need to update some tiles of a background, not always the same ones, but usually no more than 4-5 pairs per frame.
+I use the word pair because when I change a tile in the upper part of the screen, there's always another equal tile to change in the bottom part.
+Computing the tiles to update is not a big deal, but they're quite random.
+I can just update the nametable, or use a fixed nametable when the bottom part is the upper part flipped vertically, and just update a tile loading it to VRAM.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 19, 2017 10:55 am
SMS_setNextTileatXY(x,y)

which is in fact
SMS_setAddr(XYtoADDR((x),(y)))

which becomes an RST 08h, takes 39 cycles, according to Calindro's wonderful Emulicious profiler [this doesn't include the time taken to set HL to the desired value, the RST and RET opcode cycles]

41 cycles needed for
SMS_setTile(tile)

which becomes an RST 18h, again according to Emulicious profiler [once more this doesn't include the time taken to set HL to the desired value, the RST and RET opcode cycles]

Thus I would say it'll take you:
(39+41+(10+11+10)*2)*6=
(39+41+62)*6=
852 cycles

Loading 4 contiguous tiles to VRAM using
UNSAFE_SMS_load4Tiles()

takes 2249 cycles plus overhead, loading 3 noncontinuous tiles would take more than 3/4 of this surely, thus more than 1687 cycles.

Updating the tilemap seems to be the faster option by a tad :)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 19, 2017 11:00 am
kusfo wrote
I'll clarify my need as:
+I need to update some tiles of a background, not always the same ones, but usually no more than 4-5 pairs per frame.
+I use the word pair because when I change a tile in the upper part of the screen, there's always another equal tile to change in the bottom part.
+Computing the tiles to update is not a big deal, but they're quite random.
+I can just update the nametable, or use a fixed nametable when the bottom part is the upper part flipped vertically, and just update a tile loading it to VRAM.


if your update of the tilemap may become too heavy in some situation, and cause a slowdown, then the other option may be preferable, as it would always cost the same number of cycles, making the whole thing somehow easier to manage, if you get what I mean.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Tue Dec 19, 2017 11:01 am
wow! thanks for trying it so fast! :-D

I was expecting nametable updating to be faster, but that it's a clear win :-)

However, I'll test my particular case, to see which one is the best option!

Thank you sverx!
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14687
  • Location: London
Reply with quote
Post Posted: Tue Dec 19, 2017 1:14 pm
Loading a tile is two address writes and 32 data writes. Setting a name table entry is two address writes and two data writes. The tile writing will always dominate, and the VDP access dominates the other logic.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 19, 2017 1:32 pm
@Maxim: surely you push to VRAM much more data updating a tile compared to setting a few entries in the map, anyway I suspect that there's a point where the math needed to calculate the tilemap addresses, the call overheads and the set-address-then-set-data work itself could cost more than just pushing a bunch of bytes to VRAM during vblank. In short then I guess the only correct answer it's "it depends".
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14687
  • Location: London
Reply with quote
Post Posted: Tue Dec 19, 2017 2:04 pm
It's true that for small numbers of tiles it may be the case that the logic gets more significant. I'd always kind of assumed that you start animating tiles after you run out of space to animate the references, but as you say it does depend on exactly what you're animating.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Jan 03, 2018 10:43 am
Happy 2018! :)

I just pushed the updated BMP2Tile's STM plugin (it requires BMP2Tile 0.43) - the file format has changed (a 1-byte header holding the map's width has been added) and the official name of this format is now ShrunkTileMap - I know it's silly but Sverx's TileMap was even worse)

The asm decompressor (for those that are using WLA-DX) is now interrupt and VRAM safe. [HL = compressed tilemap binary (source), DE = VRAM address (destination)]

The update on the devkitSMS side (on the functions to load STMcompressed maps) will happen ASAP.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Wed Jan 03, 2018 11:54 am
great news! :-D
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Jan 03, 2018 12:53 pm
devkitSMS updated - now SMS_loadSTMcompressedTileMap loads STM tilemaps of any width (and this info is now into STM file) - SMS_loadSTMcompressedTileMapArea so has been deprecated.

On a side note, calculation of the destination VRAM address turned into an
XYtoADDR(x,y)

macro call, thus if you use constants in your invocation, such as
SMS_loadSTMcompressedTileMap(0,0,bg__tilemap__stmcompr);

they'll turn into constant addresses such as
;main.c:243: SMS_loadSTMcompressedTileMap(0,0,bg__tilemap__stmcompr);
   ld   hl, #_bg__tilemap__stmcompr
   push   hl
   ld   hl, #0x7800
   push   hl
   call   _SMS_loadSTMcompressedTileMapatAddr
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 544
  • Location: Málaga, Spain
Reply with quote
Post Posted: Wed Jan 03, 2018 2:24 pm
Great!

Lets begin new project with the update!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Jan 03, 2018 2:31 pm
SDCC 3.6.9 (#10195) suggested - released Jan 1 :)
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 544
  • Location: Málaga, Spain
Reply with quote
Post Posted: Fri Jan 05, 2018 6:37 am
Why? 31/12/2017 or 2/1/2018 versions dont work???? Is there a crítical change on sdcc?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Jan 05, 2018 9:19 am
no, I just mean to suggest the snapshot I'm using, as it seems to work correctly (they patched a lot of bugs I encountered in the past months)
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 544
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sat Jan 13, 2018 9:16 am
Hi sverx!!!

I dont forget you' simple no Rush!

... Can you explained Us the functions sms_addtwoadjoiningsprites (It draws two sprites horizontally? If so, What happens if i have usetallsprites enabled?) And setclippingwindow and addspriteclipping?

The reason is that i have a function to draw an array of sprites and discard those rows/cols which are outside screen' but maybe your functions Will be faster than my plain ANSI c one.

Regards.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Jan 13, 2018 12:08 pm
As the name suggests, it places two sprites, the first at requested x,y and the second right at his side, at same y and at x+sprite_width.
It works with sprites of any size (normal, tall, even zoomed) and it's way faster than placing two sprites with two separate calls.
No window clipping is performed - but any sprite outside of screen won't be wasted thus for example if you place your two sprites at x=253, the 'left' sprite will be placed and will partially appear on screen while the 'right' sprite will just be skipped, as it x coordinate would overflow making it appear on the left of the screen
I hope this clears your doubts.
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 118
Reply with quote
Post Posted: Thu Jan 18, 2018 3:53 am
I don't know how to use the clipping window. Is it suppose to hide the sprite when it's not inside the boundaries? I placed sprites[1] in multiple areas and it's not working for me. Here is my code.




sprites[1] = SMS_addSpriteClipping(sprPos[2], sprPos[3], SPR_TILES+2);

SMS_setClippingWindow (8, 8, 96, 96);

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Jan 18, 2018 9:14 am
clipping is performed by software - thus you should *first* set the window, then place the sprite(s): those falling outside the defined window won't be placed.
mind that it can't hide *part* of the sprite, just ensure that no sprite falling *completely* outside the window will appear.
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 118
Reply with quote
Post Posted: Sun Feb 18, 2018 3:18 am
Might have found a bug. Your compression for tilemap is not working for maps larger then the screen. Using loadSTMcompressedTileMapArea, i can load a single screen, but a 3x3 screen is not working. Garbled or black screen.

Here is an example source attached. it loads my titlescreen to check if code is working. Go into the source and uncomment the other one to load the other map, and see the bug i'm talking about.
PotentialBug.zip (40.13 KB)

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 18, 2018 12:02 pm
I don't think it's a bug but... yes, you can't have tilemaps larger than the screen (you wouldn't be able to scroll them anyway if you did...)

If you need to handle big maps, there's Psidum wonderful GSLib, which includes a C wrapper so that you can use it from your project.
  View user's profile Send private message Visit poster's website
  • Joined: 28 May 2015
  • Posts: 118
Reply with quote
Post Posted: Sun Feb 18, 2018 5:52 pm
sverx wrote
I don't think it's a bug but... yes, you can't have tilemaps larger than the screen (you wouldn't be able to scroll them anyway if you did...)

If you need to handle big maps, there's Psidum wonderful GSLib, which includes a C wrapper so that you can use it from your project.



Ah okay, i was making sure. Yeah, i'm now using it.
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Mon Mar 05, 2018 12:57 pm
I'm writing here on behalf of one fellow member in a spanish forum, he's having problems trying to make a road effect using scanline interruptions.

The problem seems like the effect is happening sometimes in every scanline (the intended effect), sometimes every 2, sometimes every 3, and any possible combination of those. I supposed that maybe he was trying to do too much process in HBLANK, but he even has implemented stripped down versions of background scroll functions, to no avail.

He just posted the code and a screenshot, first screenshot has a very noticeable defect, while second is using the stripped down version of the background calls, and the defect is not so visible.

Maybe sverx would be able to see what's the problem.

Original post in:

https://www.elotrolado.net/hilo_tutorial-muy-basico-de-c-para-master-system_2208028_s370#p1745438338



inline void SS_write_VDPRegister (unsigned char VDPReg, unsigned char value)
{
   VDPControlPort=value;
   VDPControlPort=VDPReg|0x80;
}

void SS_setLineCounter (unsigned char count)
{
    SS_write_VDPRegister(0x0A,count);
}
void lineInterruptHandler(void)
{
    SS_write_VDPRegister(0x08,offsetVector[offsCounter++]);
}
void main()
{
   init_console();
   load_graphics2vram();
   SMS_enableLineInterrupt();
   SMS_setLineInterruptHandler(&lineInterruptHandler);
   SS_setLineCounter (0);

   while (1)
  {
     // Leo input del player.   
    SMS_waitForVBlank();
    SMS_disableLineInterrupt();
    // Calculo nuevos valores para el array offsetVector   
    LoadLevelPalette ();   
    SMS_enableLineInterrupt();
    SS_setLineCounter(0);
 }
}




  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Mar 05, 2018 1:37 pm
the code is basically correct - the point is to have the line handler as fast as possible if you want to scroll at each and every scanline.

for setting the line/interval you can use
SMS_setLineCounter (unsigned char count);

for the scroll, you can use
SMS_setBGScrollX (unsigned char scrollX);


your handler would be something like
void lineInterruptHandler(void)
{
    SMS_setBGScrollX(*offsetPointer++);
}


in your main, you can set the handler and the line/interval value and enable the lineIRQ outside the loop and start the loop when ready

SMS_setLineInterruptHandler(&lineInterruptHandler);
SMS_setLineCounter(0);
SMS_enableLineInterrupt();
while (1)
{
    SMS_waitForVBlank();
    // calculate new values for the offset Array here, reset offsetPointer to &offArray[1]
    do_your_math();
    offsetPointer=&offArray[1];
    //  set uppermost line value
    SMS_setBGScrollX(offArray[0]);
}


edit: you should disable the leftmost column too! Add:
SMS_VDPturnOnFeature (VDPFEATURE_LEFTCOLBLANK);

right at the beginning :)

edit 2:sorry, there was a * missing in the handler

edit 3:to be completely honest, devkitSMS/SMSlib isn't optimized for such a heavy use of line interrupts. If I had to do something like that, I'd probably tweak the ISR, in this part:

1$:                                         ; line interrupt
    push bc
    push de
    push iy
    ld hl,(_SMS_theLineInterruptHandler)
    call ___sdcc_call_hl
    pop iy
    pop de
    pop bc
2$:

putting there some Z80 ASM code that does the H-scrolling as fast as possible, maybe even just saving (push/pop) only the registers really used. After all, you've got only 228 CPU cycles per scanline, and the line interrupt overhead isn't negligible...
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Tue Feb 04, 2020 3:13 pm
Resurrecting quite old, but official devkitSMS topic just to ask about the best way to deal with something I'm fighting with:

What would be the best way to include LUT tables on a bank? (together with Graphics) I can compile the LUT to get a .rel, but how I can have as a .bin and then pack it with other assets using assets2banks?
PD: Maybe this is quite easy, but I'm not getting how to compile to pure bin.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Feb 04, 2020 4:08 pm
if you put all the LUTs together you can compile a .rel and have them all together in the same bank, by themselves - this is the easy approach and I mainly suggest this.

otherwise, if you want them handled by assets2banks, an approach could be either:

- have each single LUT in form of a binary file (but AFAIK you can't easily create a LUT in a C source file and compile that to some bin file that contains only the LUT) - which means you're probably going to edit some file with hex editor :(

edit: try googling txt2bin, there are a few interesting results!

- if LUT(s) is(are) small, you can abuse assets2banks' :append attribute and create an empty file in the assets folder, one for each LUT, name it the way you want the LUT to be called and then in assets2banks.cfg for each empty file you append the data for example as in:

test_char_LUT.bin
:append  0 1 2 3 4 5 6 7 8


or in

test_int_LUT.bin
:format unsigned int
:append  0x1234 0x5678
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Wed Feb 05, 2020 8:48 am
My problem is that I'm using also complex structures on some files I would like to put in a bank. For instance, an example of content I'll like to put ina bank together with its graphics is:
https://github.com/kusfo/mastersystembrawler/blob/master/playercharacter.h

This is not really easy to convert to bin (I know I'll also need to get rid of pointers and so, but it's an example).

I think I saw some people doing similar things and using assembly data to fill the structs...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Feb 05, 2020 11:36 am
yeah, those structures need a compiler (and also need to be output as RELs since you've got pointers that the linker should initialize)

so if you need to keep that data in the same bank as some graphics, you could move those graphics out of the general 'asset' folder to a specific folder, then use folder2c to turn the data in there into C sources

so you then merge (juxtapose) the generated C file with your source that contains those structures - and you finally compile this resulting file into a REL, that you will link with all the other code/data in the end.
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Wed Feb 05, 2020 1:18 pm
Mmm, the merge solution is not a bad solution at all!

Thanks, I'll think a bit about it!
  View user's profile Send private message
  • Joined: 11 Dec 2019
  • Posts: 30
  • Location: Finland
Reply with quote
Post Posted: Wed Oct 28, 2020 6:59 am
I'm experimenting with SDCC snapshot (v4.0.3) and devkitSMS.
I modified SGlib to suit the SC-3000 but now when I recompile SGlib it places an EI at the beginning of SG_isr screwing up everything during execution, eg. pushing stuff on stack forever.
The only thing I modified is crt0_sg.s stackpointer (pointing to c7f0) and VDP values in SGlib.c. What is causing this?


0038:  jp 08A1h
...
08A1: ei
08A2: push af
08A3: push bc
08A4: push de
...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Oct 28, 2020 10:26 am
According to the updated SDCC manual, with version 4.0.x they slightly changed how the interrupts are declared (it's on page 46).

So you might want to try switching from
void SG_isr (void) __interrupt {

to
void SG_isr (void)  __critical __interrupt(0) {

to signal that you don't want your interrupt routine to be interrupted (!)

Let me know if that works and generate correct code.
  View user's profile Send private message Visit poster's website
  • Joined: 11 Dec 2019
  • Posts: 30
  • Location: Finland
Reply with quote
Post Posted: Wed Oct 28, 2020 2:54 pm
sverx wrote
According to the updated SDCC manual, with version 4.0.x they slightly changed how the interrupts are declared (it's on page 46).

So you might want to try switching from
void SG_isr (void) __interrupt {

to
void SG_isr (void)  __critical __interrupt(0) {

to signal that you don't want your interrupt routine to be interrupted (!)

Let me know if that works and generate correct code.

Okay, didn't even imagine someone wanting the interrupt routine to be interrupted. But that solution indeed does work and generates correct code. Thanks sverx!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Oct 28, 2020 3:16 pm
helmha wrote
that solution indeed does work and generates correct code


I'm curious now... is there a single EI or two of them before the RETI in the generated code?
  View user's profile Send private message Visit poster's website
  • Joined: 11 Dec 2019
  • Posts: 30
  • Location: Finland
Reply with quote
Post Posted: Wed Oct 28, 2020 3:54 pm
sverx wrote

I'm curious now... is there a single EI or two of them before the RETI in the generated code?

This is how it looks before correcting SGlib.c:

;SGlib.c:384: void SG_isr (void) __interrupt {
;   ---------------------------------
; Function SG_isr
; ---------------------------------
_SG_isr::
   ei
   push   af
   push   bc
   push   de
   push   hl
   push   iy
   push   ix
   ld   ix,#0
   add   ix,sp
   dec   sp
;SGlib.c:385: volatile unsigned char VDPStatus=VDPStatusPort;  /* this also aknowledge interrupt at VDP */
   in   a, (_VDPStatusPort)
;SGlib.c:390: if (VDPStatus & 0x80) {
   ld   -1 (ix), a
   rlca
   jr   NC, 00102$
;SGlib.c:391: VDPBlank=true;             /* frame interrupt */
   ld   iy, #_VDPBlank
   ld   0 (iy), #0x01
;SGlib.c:393: PreviousKeysStatus=KeysStatus;
   ld   hl, (_KeysStatus)
   ld   (_PreviousKeysStatus), hl
;SGlib.c:394: KeysStatus=~(((IOPortH)<<8)|IOPortL);
   in   a, (_IOPortH)
   ld   b, a
   xor   a, a
   ld   c, #0x00
   in   a, (_IOPortL)
   ld   e, a
   ld   d, #0x00
   ld   a, c
   or   a, e
   ld   c, a
   ld   a, b
   or   a, d
   cpl
   ld   (_KeysStatus+1), a
   ld   a, c
   cpl
   ld   (_KeysStatus+0), a
00102$:
;SGlib.c:397: ENABLE_INTERRUPTS;
   ei   
;SGlib.c:398: }
   inc   sp
   pop   ix
   pop   iy
   pop   hl
   pop   de
   pop   bc
   pop   af
   reti


With the correction in place, there's only one EI at the end of routine.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Oct 28, 2020 4:02 pm
so it looks like they add EI at the beginning of the routine if they want to allow for an ISR that can be interrupted but they don't care to add EI before the RETI if one wants an ISR that can't be interrupted.

I'll ask them.
  View user's profile Send private message Visit poster's website
  • Joined: 25 Jul 2007
  • Posts: 716
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Sun Apr 11, 2021 11:55 pm
Is there a way to read the tile index at the current location? essentially SMS_getTile

Also more generally, since I need to track the status of each tile would you just create an array for the metadata, would that be the most efficient way?

eg

unsigned int tiles[32][24];


or alternatively

struct _tiledata {
    unsigned int index;
    unsigned int status;
};

struct _tiledata tiles[32][24];
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14687
  • Location: London
Reply with quote
Post Posted: Mon Apr 12, 2021 8:16 am
While you can read back from VRAM, it’s not very fast. As the game logic is usually not based on 8x8 metatiles (and may not have a 1:1 relationship between tiles and behaviour), it’s also not very useful in general.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Apr 12, 2021 11:12 am
well, what Maxim just said. But if you for some reason really need to read back from VRAM anyway, we can code a specific function
  View user's profile Send private message Visit poster's website
  • Joined: 25 Jul 2007
  • Posts: 716
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Tue Apr 13, 2021 9:14 am
If it serves no genuine purpose don't worry too much, I've found a better way to do what I need anyway.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Apr 01, 2022 11:16 am
Reviving this old thread just to mention I pushed a few updates to address the Game Gear timing issues. So newest SMSlib should no longer create SMS or GG code that could have VRAM issues on some Game Gears.
I also unified the different crt0s - there's now only a single crt0.rel for both SMS/GG and it's always VRAM safe and supports code banking.
Please let me know should you find bugs / have issues with something.
  View user's profile Send private message Visit poster's website
  • Joined: 18 Jul 2020
  • Posts: 367
Reply with quote
Post Posted: Sat Jun 18, 2022 12:20 am
Hi, I was mucking about with devkit sms, and I'm not quite clear on what SMS_loadTileMapArea does, and what the parameters do in detail. I found an example of it being used, and it only served to confuse me further XD I'm wondering if anyone could shed some light on it.

I'm using sdcc 4.2, and the devkit sms sdcc4.2 branch.

EDIT: I backed tracked this topic, and I found out information on it. The problem is that it doesn't seem to work correctly. Using SMS_loadTileMap works just fine however. When I swap that for the SMS_loadTileMapArea, things go very wrong. Not sure what the issue is. The image is 27 tiles wide, and 3 tiles high.

#include "lib\SMSlib.h"
#include "lib\PSGlib.h"
#include <stdio.h>
#include <stdlib.h>
#include "bank2.h"

SMS_EMBED_SEGA_ROM_HEADER(9999, 1);
SMS_EMBED_SDSC_HEADER_AUTO_DATE(1, 0, "test", "test", "test");

void LoadGraphics() {
    SMS_displayOff();
    SMS_mapROMBank(title_bg_pal_bin_bank);
    SMS_loadBGPalette(title_bg_pal_bin);
    SMS_loadSpritePalette(title_spr_pal_bin);
    SMS_loadTiles(title_tmn_tiles_bin, 0, title_tmn_tiles_bin_size);
    //SMS_loadTileMap(0, 1, title_tmn_map_bin, title_tmn_map_bin_size);
    SMS_loadTileMapArea(1, 1, title_tmn_map_bin, 27, 3);
    SMS_displayOn();
}

void main() {
    SMS_init();
    LoadGraphics();
    for (;;) {
        SMS_waitForVBlank();
    }
}
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Jun 18, 2022 8:17 pm
I agree SMS_loadTileMapArea isn't well described in the documentation - also it doesn't perform any clipping.

The way it is now, it simply loads a tilemap on an area of the screen, but the source image should match the area of the screen you want to update - so if you want to update an area 27 tiles wide and 3 tiles tall, your original image should be 27*8 pixel wide and 3*8 pixels tall to generate the correct title_tmn_map_bin file you will use.

I hope it's clearer now.

edit: you don't need to call
SMS_init();
if you're using the devkitSMS provided crt0.rel as that gets already done before going to your main.
  View user's profile Send private message Visit poster's website
  • Joined: 18 Jul 2020
  • Posts: 367
Reply with quote
Post Posted: Sat Jun 18, 2022 8:38 pm
sverx wrote
I agree SMS_loadTileMapArea isn't well described in the documentation - also it doesn't perform any clipping.

The way it is now, it simply loads a tilemap on an area of the screen, but the source image should match the area of the screen you want to update - so if you want to update an area 27 tiles wide and 3 tiles tall, your original image should be 27*8 pixel wide and 3*8 pixels tall to generate the correct title_tmn_map_bin file you will use.

I hope it's clearer now.

edit: you don't need to call
SMS_init();
if you're using the devkitSMS provided crt0.rel as that gets already done before going to your main.


See, that's the issue I'm having. The image is definitely 27 * 8 in width and 3 * 8 in height (I have attached it to this post). The function gets the bottom 2 rows fine, but the top one is all jarbbled.

So this should achieve that: SMS_loadTileMapArea(1, 1, title_tmn_map_bin, 27, 3), correct?

I did read about the crt0.rel before, I have it linked in the compile.bat file, probably a remnant of copy and pasting.
tmnt.png (4.24 KB)
The image in question
tmnt.png

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Jun 18, 2022 9:04 pm
xfixium wrote
The function gets the bottom 2 rows fine, but the top one is all jarbbled.


This is very weird, given it's a very simple loop of row transfers, see the source code.

So there should be something else going on. Can you isolate the issue in a separate source and see if it does it again? Are you handling the assets using assets2banks?
  View user's profile Send private message Visit poster's website
  • Joined: 18 Jul 2020
  • Posts: 367
Reply with quote
Post Posted: Sun Jun 19, 2022 3:58 am
sverx wrote
xfixium wrote
The function gets the bottom 2 rows fine, but the top one is all jarbbled.


This is very weird, given it's a very simple loop of row transfers, see the source code.

So there should be something else going on. Can you isolate the issue in a separate source and see if it does it again? Are you handling the assets using assets2banks?


Yes, I have put together a bare bones example of the issue. I understand what the code is achieving, but if you could just try and run the test (https://www.pyxosoft.com/projects/sms_tmnt/test.zip) using the lib versions I mentioned previously, that would be awesome. That way I can maybe see if it's environmental, an emulator issue, dumbass coding on my part etc.. etc.. some sort of trouble shooting. Everything else that I have used in the library has worked as expected, and very nice. This is a great thing you have put together, and very intuitive. I barely had to do any research in getting this up and running. Thank you for helping, and your time.
tmnt_thingy_0001.png (76.23 KB)
With normal sequential tile loading and tile mapping
tmnt_thingy_0001.png
tmnt_thingy_0002.png (10.27 KB)
Using SMS_loadTileMapArea results. I have tried it with Emulicious and Fusion emulators
tmnt_thingy_0002.png

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Jun 19, 2022 3:06 pm
I'm not sure what's going on here, looks like it's mixing calling convention which means you might be mixing compiler versions and/or files

What's your SDCC version? What devkitSMS branch did you download?
  View user's profile Send private message Visit poster's website
  • Joined: 18 Jul 2020
  • Posts: 367
Reply with quote
Post Posted: Sun Jun 19, 2022 5:55 pm
sverx wrote
I'm not sure what's going on here, looks like it's mixing calling convention which means you might be mixing compiler versions and/or files

What's your SDCC version? What devkitSMS branch did you download?


Hmmm, that may be it. I have sdcc v 4.2.0 #13081 (MINGW64) installed, and I believe the sdcc4.2 branch from github. Probably should have used the master branch when I think about it. I'll overwrite with master.

Edit: Oh wait, your instructions said to get sdcc 4.1.11 at the most lol, how did I miss that?

Edit Edit: That worked! I brought in sdcc 4.1 and devkit sms master branch, and now it functions as expected.

On one more question, is there a method/macro to clear the vram? Thank you so much for your help.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3761
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Jun 19, 2022 8:28 pm
yeah you can use the sdcc4.2 branch of devkitSMS only with SDCC 4.2.0 or the master branch with SDCC 4.1.0 -> 4.1.11.

If you were using SDCC 4.2.0 and the sdcc4.2 branch of devkitSMS it should have worked, or it means I've got a bug somewhere, but I've not experienced it.
  View user's profile Send private message Visit poster's website
Reply to topic Goto page Previous  1, 2, 3 ... 7, 8, 9, 10, 11 ... 14, 15, 16  Next



Back to the top of this page

Back to SMS Power!