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 ... 11, 12, 13, 14, 15, 16, 17  Next
Author Message
  • Joined: 06 Mar 2022
  • Posts: 657
  • Location: London, UK
Reply with quote
Post Posted: Sun Sep 17, 2023 2:41 pm
cireza wrote
Edit : I tried but it seems it is still not going at the expected place :(
Stays at 3F00

Just looking at the code for makesms and I think I can see how this might be happening.

Out of interest, do you still see a log line of "Info: SEGA header found, checksum updated" when you run it?
  View user's profile Send private message Visit poster's website
  • Joined: 27 Feb 2023
  • Posts: 133
  • Location: France
Reply with quote
Post Posted: Sun Sep 17, 2023 2:56 pm
willbritton wrote
Out of interest, do you still see a log line of "Info: SEGA header found, checksum updated" when you run it?

Yes, I do get this log.
  View user's profile Send private message
  • Joined: 06 Mar 2022
  • Posts: 657
  • Location: London, UK
Reply with quote
Post Posted: Sun Sep 17, 2023 3:19 pm
So I'm wondering if the problem is with the interaction between the header macro(s) and how makesms treats banked segments.

You might just try either modifying SMSlib.h directly or else writing your own copy of the macro to test this out, but basically what I'm thinking is that instead of


#define SMS_EMBED_SEGA_ROM_HEADER(productCode,revision)                                        \
 const __at (0x7ff0) unsigned char __SMS__SEGA_signature[16]= //...snip


it might work better with


#define SMS_EMBED_SEGA_ROM_HEADER(productCode,revision)                                        \
 const __at (0x17ff0) unsigned char __SMS__SEGA_signature[16]= //...snip


Note the modified offset to specify bank 1.

If that helps, then I think we might be onto something, but not sure what the most appropriate "proper" fix would be in that case.
  View user's profile Send private message Visit poster's website
  • Joined: 27 Feb 2023
  • Posts: 133
  • Location: France
Reply with quote
Post Posted: Mon Sep 18, 2023 5:57 pm
So it seems I have things working now, I made this change :

#define SMS_EMBED_SEGA_ROM_HEADER(productCode,revision)                                        \
 const __at (0x17ff0) unsigned char __SMS__SEGA_signature[16]={'T','M','R',' ','S','E','G','A', \
                                                                          0xFF,0xFF,0xFF,0xFF, \
                  SMS_BYTE_TO_BCD((productCode)%100),SMS_BYTE_TO_BCD(((productCode)/100)%100), \
           (((productCode)/10000)<<4)|((revision)&0x0f),SMS_EMBED_SEGA_ROM_HEADER_REGION_CODE}

#define SMS_EMBED_SDSC_HEADER(verMaj,verMin,dateYear,dateMonth,dateDay,author,name,descr)      \
                          const __at (0x17fe0-sizeof(author)) char __SMS__SDSC_author[]=author; \
                 const __at (0x17fe0-sizeof(author)-sizeof(name)) char __SMS__SDSC_name[]=name; \
 const __at (0x17fe0-sizeof(author)-sizeof(name)-sizeof(descr)) char __SMS__SDSC_descr[]=descr; \
                          const __at (0x17fe0) char __SMS__SDSC_signature[16]={'S','D','S','C', \
                                              SMS_BYTE_TO_BCD(verMaj),SMS_BYTE_TO_BCD(verMin), \
                                          SMS_BYTE_TO_BCD(dateDay),SMS_BYTE_TO_BCD(dateMonth), \
                              SMS_BYTE_TO_BCD((dateYear)%100),SMS_BYTE_TO_BCD((dateYear)/100), \
                                                                  (0x7fe0-sizeof(author))%256, \
                                                                   (0x7fe0-sizeof(author))>>8, \
                                                     (0x7fe0-sizeof(author)-sizeof(name))%256, \
                                                      (0x7fe0-sizeof(author)-sizeof(name))>>8, \
                                       (0x7fe0-sizeof(author)-sizeof(name)-sizeof(descr))%256, \
                                        (0x7fe0-sizeof(author)-sizeof(name)-sizeof(descr))>>8}


I added the 1 in front of the address at several places, but not the final ones as they lead to a char overflow. Not too sure if this is correct.
  View user's profile Send private message
  • Joined: 06 Mar 2022
  • Posts: 657
  • Location: London, UK
Reply with quote
Post Posted: Tue Sep 19, 2023 8:11 am
Ah yeah okay that makes sense that there are a few more places than the one I highlighted, but principle's the same.

You're right that it won't work with the final ones, since they are pointers within the SDSC header which are relative to the real memory space, so in fact they do need to refer to a base of 0x7fe0 rather than 0x17fe0.

Great that you've got it working! But as I said, this is just a hack really - at least it proves the problem, which is that the header code is being emitted to real addresses, not virtual ones and so when the final ROM is assembled they get lost.

I suppose one potential fix is to change makesms to detect the header code and force it to be written to bank 1. There is already code in makesms which detects the SMS header, in order to calculate the checksum, so maybe it could go there.

EDIT: just another thought, perhaps it's simpler than this - the problem in makesms is that it masks all source addresses within a segment with 0x3fff which perhaps is just not the right thing to do. I'll have a think and if I feel like I've got a solid fix in mind I'll maybe make a PR.

Without having time to look much more into it at the moment, I wonder whether ihx2sms suffers from the same problem and at a glance I would guess that it does; but since the usual way to do non-code banking is in slot 2 the issue rarely comes up.

Let's maybe see what sverx thinks when he's back in the neighbourhood!
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Sep 21, 2023 10:06 am
Last edited by sverx on Thu Sep 21, 2023 10:13 am; edited 1 time in total
when using banked code, you likely want your ROM signature (and SDSC signature) at the end of bank0, so you should use:

SMS_EMBED_SEGA_ROM_HEADER_16KB(productCode,revision)

and

SMS_EMBED_SDSC_HEADER_16KB(verMaj,verMin,dateYear,dateMonth,dateDay,author,name,descr)

or if you want the SDSC date to be 'automatic' (set by makesms)

SMS_EMBED_SDSC_HEADER_AUTO_DATE_16KB(verMaj,verMin,author,name,descr)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Sep 21, 2023 10:11 am
pw wrote
When looking at the SMS_add****AdjoiningSprites_f functions, I've noticed that at the beginning it does a check to see if there are enough sprites free to draw the row and exits early if it doesn't. Yet later on in the function, it checks the limit for every sprite and returns if it does. Did I read that right?


Well, no. At the beginning, they check if there are enough sprites available to draw the entire strip (say 3 sprites) and won't draw anything if the available number of sprites isn't sufficient. But then, depending on the X position of the leftmost sprite, there could be sprites that will be completely clipped out of the right screen border, so the function in the end updates how many sprites were actually used.

I hope this explanation makes sense! :)
  View user's profile Send private message Visit poster's website
  • Joined: 06 Mar 2022
  • Posts: 657
  • Location: London, UK
Reply with quote
Post Posted: Thu Sep 21, 2023 3:48 pm
sverx wrote
when using banked code, you likely want your ROM signature (and SDSC signature) at the end of bank0, so you should use:

SMS_EMBED_SEGA_ROM_HEADER_16KB(productCode,revision)

and

SMS_EMBED_SDSC_HEADER_16KB(verMaj,verMin,dateYear,dateMonth,dateDay,author,name,descr)

or if you want the SDSC date to be 'automatic' (set by makesms)

SMS_EMBED_SDSC_HEADER_AUTO_DATE_16KB(verMaj,verMin,author,name,descr)

I think that cireza was saying having the header in bank 0 was preventing it from being detected as GG on the Everdrive though.
  View user's profile Send private message Visit poster's website
  • Joined: 04 Jul 2010
  • Posts: 540
  • Location: Angers, France
Reply with quote
Post Posted: Thu Sep 21, 2023 3:58 pm
In fact, the header @0x7FF0 is completely empty

Look at Cireza's screenshot :
https://www.smspower.org/forums/files/compiled_with_makesms_180.png
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Sep 22, 2023 7:52 am
willbritton wrote
I think that cireza was saying having the header in bank 0 was preventing it from being detected as GG on the Everdrive though.


oh, wait, does the EverDrive-GG really checks any ROM header? I don't think so - and I guess it uses the file extension to decide if the ROM should run in GG mode or in SMS mode.

Please correct me if I'm wrong, I never used/had an EverDrive-GG myself...

edit: I just remembered that there is an (unresolved I guess?) issue with the EverDrive-GG software that appears when the ROM file name fits into the 8.3 format (such as ROM.gg) - so please make sure to give a sensible name such as game_test_ROM.gg or similar.

To the best of my knowledge, no EverDrive care about no header.
  View user's profile Send private message Visit poster's website
  • Joined: 14 Apr 2013
  • Posts: 624
Reply with quote
Post Posted: Fri Sep 22, 2023 1:11 pm
sverx wrote
Please correct me if I'm wrong, I never used/had an EverDrive-GG myself...

You can still test it by emulating the Everdrive in Emulicious. It does check the filename but it also checks a bit of the rom. Afaik the filename is used to determine GG vs. SMS and the rom contents are only checked to determine SEGA mapper vs. Codemasters mapper.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Mar 2022
  • Posts: 657
  • Location: London, UK
Reply with quote
Post Posted: Fri Sep 22, 2023 3:22 pm
Well here's what we know from cireza's original issue as reported:

cireza wrote
For some reason, I am not getting the expected information at address 0x7FF0 in my rom.
...
The result is that my Game Gear/Everdrive treats the rom as a SMS game instead of a GG game (the rom is named rom.gg).


and

cireza wrote
...my headers end up at the end of bank0.


Also that when he persuaded the header to appear at 0x7FF0 again the implication was that the problem was solved.

But I agree, it seems strange that it's not purely down to file extension. Cireza didn't say what Everdrive "treat[ing] the rom as a SMS game" actually means in practice - does that mean it ran on the GG in SMS compatibility mode?

@Calindro - do you know how the algorithm Everdrive uses to decide the mapper actually works? Could the wrong choice of mapper be causing the issue somehow?
  View user's profile Send private message Visit poster's website
  • Joined: 27 Feb 2023
  • Posts: 133
  • Location: France
Reply with quote
Post Posted: Fri Sep 22, 2023 4:18 pm
My rom was simply named rom.gg but it appeared in SMS mode indeed. The fact that the header was not present at 7FF0 is what I supposed caused the issue, but please keep in mind that you are all much more knowledgeable about these consoles than I am. I simply made the assumption because it was the only difference that I spotted.

I will try to use the 16KB header as suggested by sverx, thank you.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Sep 25, 2023 9:06 am
cireza wrote
I will try to use the 16KB header as suggested by sverx, thank you.


I would see if you can make it work correctly without any header first.

Also, are you using the 'legacy' EverDrive-GG or the 'newer' EverDrive GG X7? And are you using the latest available 'OS' version?
  View user's profile Send private message Visit poster's website
  • Joined: 27 Feb 2023
  • Posts: 133
  • Location: France
Reply with quote
Post Posted: Mon Sep 25, 2023 4:22 pm
sverx wrote
I would see if you can make it work correctly without any header first.

Also, are you using the 'legacy' EverDrive-GG or the 'newer' EverDrive GG X7? And are you using the latest available 'OS' version?

I am using the first Everdrive GG and not the latest OS as it introduced issues with saving, if I remember correctly. Support has been pretty poor for the OS of the original Everdrive GG.
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Little "bug" in smsdevkit
Post Posted: Mon Oct 30, 2023 9:14 pm
In devkitSMS/SMSlib/src/how to build this.txt:

the build instructions lack the reference to SMS_addthreesprites file

Regards
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Oct 31, 2023 7:33 am
eruiz00 wrote
the build instructions lack the reference to SMS_addthreesprites file


fixed! thanks :)
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Nov 01, 2023 9:20 am
I just pushed an update adding SMS_debugPrintf
void SMS_debugPrintf(const unsigned char *format, ...)
which (so far) works only with Emulicious, provided it's updated (at least to yesterday's release)

use it as the regular printf() so for instance:
SMS_debugPrintf("Player 1 HP = %d, Player 2 HP = %d\n", player1.HP, player2.HP);

the output will appear in Emulicious' Console window.
  View user's profile Send private message Visit poster's website
  • Joined: 27 Feb 2023
  • Posts: 133
  • Location: France
Reply with quote
Post Posted: Sat Nov 04, 2023 7:26 pm
sverx wrote
I just pushed an update adding SMS_debugPrintf
void SMS_debugPrintf(const unsigned char *format, ...)
which (so far) works only with Emulicious, provided it's updated (at least to yesterday's release)

use it as the regular printf() so for instance:
SMS_debugPrintf("Player 1 HP = %d, Player 2 HP = %d\n", player1.HP, player2.HP);

the output will appear in Emulicious' Console window.

Thank you for this update. If I get into trouble debugging my new game I will use it.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
devkitSMS MetaSprites
Post Posted: Tue Dec 05, 2023 4:56 pm
Last edited by sverx on Thu Dec 07, 2023 10:34 am; edited 1 time in total
So I decided I could add some (basic) metasprite support after all.

What's a metasprite in devkitSMS? It is a list of sprites that have horizontal and vertical offsets from an origin point, so that placing a metasprite origin at some place, all the hardware sprites will be placed accordingly.

So to use metasprites you need definitions. A definition is a sequence of as many sprites as you need with an horizontal offset (signed byte), vertical offset (signed byte) and tile number for each one, followed by a METASPRITE_END marker. Example:

unsigned char const metasprite0[]={
// x_off, y_off, tile#
0, 0, SPRITES_START_TILE,
0, 16, SPRITES_START_TILE+1,
15, 5, SPRITES_START_TILE+2,
9, -13, SPRITES_START_TILE+6,
-9, -13, SPRITES_START_TILE+1,
-15, 5, SPRITES_START_TILE+1,
METASPRITE_END};

(SDCC may warn you about the mixed signedness and/or for data truncation, just ignore that...)

Then you call SMS_addMetaSprite(pos_x, pos_y, metasprite) and you get the sprites added, like regular sprites that you later will copy to SAT with SMS_copySpritestoSAT().

The function handles clipping - it won't draw sprites falling completely outside of the screen, but has a different behavior regarding how it handles the pos_x and pos_y origin point:


  • pos_x can only be 0-255, so you can't place the metasprite origin point horizontally outside of the screen.
  • pos_y can be any value -128 to 255, so the origin point can be placed vertically outside the screen: for instance a player can jump high over the top border or fall down in a pit and disappear below the bottom border. Note that there is vertical wrap on 8 bits anyway so you want to limit your range -k to 255-k.


SMS_addMetaSprite(hero_x, hero_y, metasprite0);


Then of course you can create arrays of metasprites definitions
unsigned char const *metasprites[]={metasprite0, metasprite1, metasprite2, metasprite3, metasprite4, metasprite5};
and use them as frames for your animations.

You can even skip some of the sprites in the list, provided you put them in the beginning - all you have to do is to skip 3 bytes for each sprite for example:

SMS_addMetaSprite(hero_x, hero_y, metasprite0+3);


Here's a little demo. I hope you like it :)
MetaSpriteDemo.sms.zip (1.77 KB)
devkitSMS MetaSpriteDemo

  View user's profile Send private message Visit poster's website
  • Joined: 19 Oct 2023
  • Posts: 122
Reply with quote
Post Posted: Tue Dec 05, 2023 9:30 pm
Interesting, I'll give this a go. Thanks for the update!
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 06, 2023 10:44 am
note that SMS_addTwoAdjoiningSprites and SMS_addThreeAdjoiningSprites in fact are sort of metasprites functions too, just better suited for a different job

which means sometimes you might find one better suited than the other, so SMS_addMetaSprite is basically opening in a different direction where you need sparse/unaligned sprites
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Thu Dec 07, 2023 10:07 am
That's great!!!

I found that, when the basic metasprite api is consolidated into the lib, an animation api could be implemented on top of that.

On other side, it could be of utility (not by you, sverx, by someone else) to have a little metasprite editor to load&save metaprite configurations.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 07, 2023 10:20 am
eruiz00 wrote
it could be of utility to have a little metasprite editor to load&save metaprite configurations.


I seem to remember kusfo once showed me some tool for the Genesis/MegaDrive - it probably needs a mode where it uses either 8×8 or 8×16 sprites only, and an exporter...
  View user's profile Send private message Visit poster's website
  • Joined: 04 Jul 2010
  • Posts: 540
  • Location: Angers, France
Reply with quote
Post Posted: Thu Dec 07, 2023 11:02 am
I've made a fairly complex one for Paprium GG (boxes of any sizes (based on 8x16 multiples as the game is 8x16), obviously as many boxes as you need, can precise time of every frame, collisions boxes, point of reference, optimise/trim same tiles, export tiles and def separately...), but it will never be public.

xfixium seems to be the guy for asking, as he have already make great gui to edit games.
  View user's profile Send private message
  • Joined: 09 Aug 2021
  • Posts: 122
Reply with quote
Post Posted: Thu Dec 07, 2023 3:47 pm
eruiz00 wrote
On other side, it could be of utility (not by you, sverx, by someone else) to have a little metasprite editor to load&save metaprite configurations.

GBDK-2020 has nice metasprite support, including png2asset utility which allows to convert PNGs into the series of animations with deduplicated tiles and all necessary merasprite descriptors. Here is the example: https://github.com/gbdk-2020/gbdk-2020/tree/develop/gbdk-lib/examples/cross-plat...
slon.png (10.42 KB)
slon.png
metasprites.zip (3.39 KB)

  View user's profile Send private message
  • Joined: 18 Jul 2020
  • Posts: 372
Reply with quote
Post Posted: Sat Dec 09, 2023 9:26 pm
ichigobankai wrote
I've made a fairly complex one for Paprium GG (boxes of any sizes (based on 8x16 multiples as the game is 8x16), obviously as many boxes as you need, can precise time of every frame, collisions boxes, point of reference, optimise/trim same tiles, export tiles and def separately...), but it will never be public.

xfixium seems to be the guy for asking, as he have already make great gui to edit games.


I can put this together. What kind of data output/structure would be desired?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Dec 09, 2023 10:13 pm
xfixium wrote
I can put this together. What kind of data output/structure would be desired?


The basic requirement would be to create a single metasprite from an image by picking a reference point and placing all the 8×8 or 8×16 sprites positions regarding the reference point. The output data would be a sequence of X_offset, Y_offset, Tile# until it's terminated by a METASPRITE_END. Probably outputting a C file could be a good approach, something like this for example:

unsigned char const objectname_metasprite0[]={
// x_off, y_off, tile#
0, 0, SPRITES_START_TILE,
0, 16, SPRITES_START_TILE+1,
15, 5, SPRITES_START_TILE+2,
9, -13, SPRITES_START_TILE+6,
-9, -13, SPRITES_START_TILE+1,
-15, 5, SPRITES_START_TILE+1,
METASPRITE_END};


of course then supporting sequence of metasprites to create animations would be amazing - in that case multiple metasprite definitions would be needed (one per frame) and then there should be something to define the whole animation, similar to this for example:

unsigned char const *objectname_animation[ ]={objectname_metasprite0, objectname_metasprite1, objectname_metasprite2, objectname_metasprite3, objectname_metasprite4, objectname_metasprite5};


even with frame reuse, if needed.
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Sun Dec 10, 2023 12:50 am
So I've come back to SMS dev after a bit of a hiatus, and I'm getting some unusual warnings when adding a sprite. I've upgraded to SDCC 4.3.0, and am using the latest version of devkitSMS from GitHub.

If I have
SMS_addSprite(14 * 8, 5 * 8, 134);

Then it's fine. (x = 112)

But if I have
SMS_addSprite(16 * 8, 5 * 8, 134);

Then it complains. (x = 128, outside the range of an int but not uint) with "warning 158: overflow in implicit constant conversion"

In the SMS_addSprite I see it's doing a bit-shift/mask to add the tile so I'm guessing it maybe is upset with something I'm doing. What might I have missed?

Of course one can disable the warning with
#pragma disable_warning 158
but that feels a bit hacky?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Dec 10, 2023 3:11 pm
darkowl wrote
[...] it complains. (x = 128, outside the range of an int but not uint) with "warning 158: overflow in implicit constant conversion"


Thanks for your feedback!
I could get rid of this warning just by writing better code, so I have posted an update a minute ago. Hopefully there'll be no other warnings :)
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Thu Dec 28, 2023 10:55 am
Thanks for updating that! Works a treat.

Okay so random question.

The SMS_setLineCounter function... when I use scroll interrupts, it seems to be off by one pixel row. Like it's skipping the first row, then starting counting from the second onwards

That is, if I set SMS_setLineCounter(15); it should update every two sets of tile rows. However, each interrupt grabs a one pixel slice of the row of the next tile.

In Emulicious, this can be seen in the Tilemap Viewer by the scroll field indicator being one pixel down.

Is this a limitation of the VDP? Or something in devkitSMS? Or me? Haha
clouds.png (16.03 KB)
clouds.png

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 28, 2023 11:03 am
The issue you're facing is due to the fact that there's very little time to update the VDP horizontal scroll register before it's to late to see the effect on the next line - so you should use some workaround to ensure your line interrupt handler gets its work done as fast as possible.

Can I see your line handler code? I think can help you :)
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Thu Dec 28, 2023 11:27 am
Sure. I'm just playing with ideas and I'm not a C or ASM programmer by trade so I just do my best with them.

I initialise a structure of uint16_t city_scroll_x[5]; because after 5 iterations I just want it to all be the same.

I use a simple unsigned char for the index offset. The main update is something like


void cityScrollHandler(void)
{
    if (++cityLineCnt > 4)
        cityLineCnt = 4;

    SMS_setBGScrollX(city_scroll_x[cityLineCnt] >> 3);
}


Each of those values is updated by some varying amount in a separate update loop.

Also yes I'm aware I'm mixing underscores and camelCase for no good reason haha.

The produced assembly is pretty gnarly. 227 cycles... I think I'm not allowed to have that much haha. Although I would have expected it to get exponentially worse, not consistently off by one row?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 28, 2023 11:33 am
Yes, that code takes too much to get to the point where the SMS_setBGScrollX function is called.

A possible workaround is to have something like this:

void cityScrollHandler(void)
{
   SMS_setBGScrollX(next_scroll_value);

    if (++cityLineCnt > 4)
        cityLineCnt = 4;

    next_scroll_value = city_scroll_x[cityLineCnt] >> 3;
}


of course you need to set the first next_scroll_value before you get to execute the line handler, so you probably should do that in your vblank, for instance after you've updated the SAT.

Now the SMS_setBGScrollX will run much earlier and it *should* make it on time :)
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Thu Dec 28, 2023 1:22 pm
Interesting... I tested out the change, but now the behaviour is quite radically different - the first bit scrolls way too fast, and the others not fast enough... and it's still got the off-by-1px issue.

I'll keep trying to pare it back to see if I can find a point where it's as-fast-as-it-can-be. It's a weird one.

I also tested it in Gearsystem and the behaviour is the same, suggesting that it's at least extremely unlikely to be an emulator issue.
still-off-by-1.png (1.73 KB)
still-off-by-1.png

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 28, 2023 3:31 pm
darkowl wrote
Interesting... I tested out the change, but now the behaviour is quite radically different - the first bit scrolls way too fast, and the others not fast enough... and it's still got the off-by-1px issue.


if you had set next_scroll_value to city_scroll_x[0], then you have to remember that you need to set cityLineCnt to 0 too as you increment it before using it as an index into the array.

As for the off by one pixel issue, it might be because it's still too slow.

Let's see if this fixes it:

void cityScrollHandler(void)
{
  __asm
    ld a,(next_scroll_value)
    out (#0xBF),a
    ld a,#0x88           // write to hscroll VDP register
    out (#0xBF),a
  __endasm;

    if (++cityLineCnt > 4)
        cityLineCnt = 4;

    next_scroll_value = city_scroll_x[cityLineCnt] >> 3;
}
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Fri Dec 29, 2023 12:28 am
sverx wrote

Let's see if this fixes it:


Yep, that works! It's no longer off by one. Amazing.

I had to make a small concession for SDCC in the C variable being _next_scroll_value with a leading underscore when inside the asm block. It gave me a somewhay obtuse warning about an unused variable which took a bit of head scratching as there was no line reference due to it being inline assembly.

I've pushed the compiled binary to https://github.com/mikehdt/sms-demo/blob/main/dist/demo.sms if you want to see it. Pressing the A/1 key will make it fade out and back in (I made a reverse of devkit's subtractive fade that uses additive for fading to/from white which was fun to figure out).

I'm interested in why the inline asm works - is it literally just the time for the function call to devkit is taking too many cycles during the hblank? That's pretty intense if that's it.

Thanks so much for your help! It's super appreciated.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Dec 29, 2023 2:48 pm
darkowl wrote
I had to make a small concession for SDCC in the C variable being _next_scroll_value with a leading underscore when inside the asm block.


Oh, my bad, I forgot it. :|

darkowl wrote
I'm interested in why the inline asm works - is it literally just the time for the function call to devkit is taking too many cycles during the hblank?


Yes, it's taking too much time and it's an issue here, as it ends up happening after the end of the short available window.
I will look into creating a forced inline version of the same function for these cases, so that it does turn into some code fast enough.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Dec 29, 2023 4:02 pm
OK so I went on and added the function (actually, a macro)

INLINE_SMS_setBGScrollX()

so you can remove the inline asm block and instead use

INLINE_SMS_setBGScrollX(next_scroll_value);

to get the same effect.
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Sat Dec 30, 2023 12:31 am
sverx wrote
OK so I went on and added the function (actually, a macro)


Nice! I implemented it and it works.

I do get VSCode not understanding the SMS_VDPControlPort line, as it shows:

identifier "SMS_VDPControlPort" is undefinedC/C++(20)

Even though it compiles and runs just fine. I tried looking up if you can disable Intellisense on a per-line (like disabling ESlint in JavaScript) basis but all I found was someone saying "why would you want to do that", which is not the best answer haha! I think it's just confused by the inline definition. Not sure if there's a way to "trick" it with a dummy definition or not. Hmm.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Dec 30, 2023 11:32 am
I'm not using VSCode or Intellisense so I can't offer any solution here.

Maybe there's a way to teach Intellisense that
__sfr __at(0x78) IoPort;

is a definition of the IoPort 'variable'? (it's not strictly a variable of course, but that would do...)
  View user's profile Send private message Visit poster's website
  • Joined: 06 Mar 2022
  • Posts: 657
  • Location: London, UK
Reply with quote
Post Posted: Sun Dec 31, 2023 12:18 am
@darkowl where are you seeing the VSCode issue, in SMSlib.h itself or in your code?

I've just tried with the latest commit to devkitsms and I get a single error in SMSlib.h, although not the one you mention — I get "expected a '{' C/C++(130) [Ln 22, Col 50]" which is due to __z88dk_fastcall being unrecognised.
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Sun Dec 31, 2023 3:03 am
willbritton wrote
@darkowl where are you seeing the VSCode issue, in SMSlib.h itself or in your code?


In my code. It's generally also that Intellisense dislikes inline z80 assembly; it gets very confused by the various pragma, code highlighting tries to interpret assembly as C, and I have to disable clang from trying to autoformat it. It's fine if it's a .asm file, just not a .c file.

I'm not sure of how to "teach" Intellisense about things that are legit. I did try poking with my own code highlighter plugin but thought better of it because trying to maintain that would be a nightmare heh.

Edit: Aha, there's a way around it.

@sverx, would it be okay to change the .h file slightly?
Instead of:

__sfr __at 0xBF SMS_VDPControlPort;


Adding brackets around the address:

__sfr __at(0xBF) SMS_VDPControlPort;


Allows people like me to add the following defines to the `.vscode/c_cpp_properties.json` file like so:

    "defines": [
        (...other defines...)
        "__sfr=unsigned char",
        "__at(a)="
    ],
(...rest of config...)


And that silences the error. Would that change to add brackets be okay? As far as I can tell, it's just syntactic, and shouldn't affect the output.

(ref: https://github.com/microsoft/vscode-cpptools/issues/2499#issuecomment-1834215280 )
untellisense.png (74.2 KB)
untellisense.png

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Dec 31, 2023 2:54 pm
darkowl wrote
would it be okay to change the .h file slightly?
Instead of:

__sfr __at 0xBF SMS_VDPControlPort;


Adding brackets around the address:

__sfr __at(0xBF) SMS_VDPControlPort;


sure, if everything still works after that change, I can indeed put those brackets in!
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Mon Jan 01, 2024 1:12 am
sverx wrote

sure, if everything still works after that change, I can indeed put those brackets in!


Well, it compiles and runs within the hblank time for me here, so I'd guess that it's the case! Heh.
  View user's profile Send private message
  • Joined: 15 Mar 2021
  • Posts: 31
Reply with quote
DEVKITSMS scrolling interruption
Post Posted: Mon Jan 01, 2024 12:43 pm
Last edited by Leopardcookies on Mon Jan 01, 2024 5:35 pm; edited 1 time in total
happy new year everyone, I resumed development on master system of my horizontal scrolling shoot em up with the sms devkit I forgot how to interrupt my scrolling I have been trying for several hours without success with the functions planned for this, could someone give me an example in concrete code to achieve this? for example I would not like scrolling from line 0 to 90.... and the bottom of the screen continues to scroll...
my code is organized like this
variable declaration:
Main :
while{
}
update {
}
Thank you and sorry if I ever got the wrong section
IMG_7502.jpeg (3.48 MB)
IMG_7502.jpeg

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Jan 01, 2024 1:59 pm
Leopardcookies wrote
for example I would not like scrolling from line 0 to 90.... and the bottom of the screen continues to scroll...


if you want to scroll only the bottom part of the screen you might want to set the horizontal scroll to 0 during vblank and have a line interrupt firing at line 90 that sets the horizontal scroll to the value you need

check this, there's also a small example provided.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Jan 01, 2024 2:06 pm
darkowl wrote
I made a reverse of devkit's subtractive fade that uses additive for fading to/from white which was fun to figure out.


this is interesting - can you provide a PR to the repository? :)
  View user's profile Send private message Visit poster's website
  • Joined: 15 Mar 2021
  • Posts: 31
Reply with quote
Post Posted: Mon Jan 01, 2024 9:54 pm
Thank you for your help but I was not able to stop the top of the scrolling, I made a function:(I degreased my code to make it more readable)

// fonction
void IRQ_Function(void){
SMS_setBGScrollX(Scrolling);
}
void main(void)
{

init_game();// loading tilset and sprite into VRAM

SMS_VDPturnOnFeature(VDPFEATURE_LOCKHSCROLL); //Block the top tiles for a HUB
SMS_VDPturnOnFeature(VDPFEATURE_HIDEFIRSTCOL);

// IRQ line test
SMS_setLineInterruptHandler(&IRQ_Function);
}
while(1)
{
SMS_enableLineInterrupt();

SMS_waitForVBlank();

SMS_setLineCounter(128);
Scrolling=Scrolling-1;
}
}
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3793
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Jan 02, 2024 8:42 am
you're almost there. I would do:

// fonction
void IRQ_Function(void){
INLINE_SMS_setBGScrollX(Scrolling);   //  <-- use INLINE version so that it works on the exact line
}



void main(void)
{

init_game();// loading tilset and sprite into VRAM

SMS_VDPturnOnFeature(VDPFEATURE_LOCKHSCROLL); //Block the top tiles for a HUB
SMS_VDPturnOnFeature(VDPFEATURE_HIDEFIRSTCOL);

// IRQ line test
SMS_setLineInterruptHandler(&IRQ_Function);
SMS_setLineCounter(128);
SMS_enableLineInterrupt();

while(1)
{
  SMS_waitForVBlank();
  Scrolling=Scrolling-1;

  SMS_setBGScrollX(0);    //  <-- make sure the top part has always scrolling at 0
}

}
  View user's profile Send private message Visit poster's website
Reply to topic Goto page Previous  1, 2, 3 ... 11, 12, 13, 14, 15, 16, 17  Next



Back to the top of this page

Back to SMS Power!