Sega Genesis Dev Kit (SGDK)

SGDK only sub forum

Moderator: Stef

Stef
Very interested
Posts: 3101
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Sega Genesis Dev Kit (SGDK)

Post by Stef » Sun Dec 05, 2021 9:32 pm

Hi,

Your code is correct :)
If your IMAGE isn't compressed then

Code: Select all

Map *mymap = unpackMap(background.map, NULL);
will still work as in case there is no compression unpackMap will do a simple copy and allocate destination if set to NULL so you should even keep the

Code: Select all

MEM_free(mymap);
But i'm speaking about current version and i know that older SGDK version weren't doing the copy so maybe that is not the case with your version.
Still to reply your initial question, if you didn't packed the IMAGE then you should just use :

Code: Select all

VDP_setMapEx(PLAN_A, background.map, ...);
And that's !

danibus
Very interested
Posts: 127
Joined: Sat Feb 03, 2018 12:41 pm

Re: Sega Genesis Dev Kit (SGDK)

Post by danibus » Mon Dec 06, 2021 4:10 am

Thanks Stef!

danibus
Very interested
Posts: 127
Joined: Sat Feb 03, 2018 12:41 pm

Re: Sega Genesis Dev Kit (SGDK)

Post by danibus » Tue Jan 04, 2022 5:11 am

Hi there!

Just playing with SRAM instructions and Genskmod to check with Klog, all seems to work well.
I just want to save some data, player name (i.e. "AAA\0") and its points. Doing this, maybe not best method.
Do you see anything wrong here?

Code: Select all


struct {
    char player_name[4];     
    u16 points;             
}Ranking[NUM_PLAYERS_RANKING];

[..]
    //data "by default" when 1st time game running
    strcpy( Ranking[0].player_name, "AAA\0" );
    Ranking[0].points=10000;
    strcpy( Ranking[1].player_name, "BBB\0" );
    Ranking[1].points=9000;
    strcpy( Ranking[2].player_name, "CCC\0" );
    Ranking[2].points=8000;
[..]


int save_ranking()
{
    u16 SRAMoffset = 0x0000;

    SRAM_enable();

    for(u8 i=0; i<NUM_PLAYERS_RANKING; i++)
    {
        SRAM_writeByte(SRAMoffset, Ranking[0].player_name[0]); SRAMoffset++;
        SRAM_writeByte(SRAMoffset, Ranking[0].player_name[1]); SRAMoffset++;
        SRAM_writeByte(SRAMoffset, Ranking[0].player_name[2]); SRAMoffset++;
        SRAM_writeByte(SRAMoffset, Ranking[0].player_name[3]); SRAMoffset++;

        SRAM_writeWord(SRAMoffset, Ranking[0].points);              SRAMoffset++;
    }

    SRAM_disable();

    return 1;
}


int read_ranking()
{
    u16 SRAMoffset = 0x0000;
    u16 temp = NULL;
    char ctemp[4], ctemp2[4];

    SRAM_enable();

    for(u8 i=0; i<NUM_PLAYERS_RANKING; i++)
    {
        ctemp[0] = SRAM_readByte(SRAMoffset); SRAMoffset++;
        ctemp[1] = SRAM_readByte(SRAMoffset); SRAMoffset++;
        ctemp[2] = SRAM_readByte(SRAMoffset); SRAMoffset++;
        ctemp[3] = SRAM_readByte(SRAMoffset); SRAMoffset++;
        sprintf(ctemp2, "%c%c%c%c", ctemp[0],ctemp[1],ctemp[2],ctemp[3]);
        strcpy( Ranking[0].player_name, ctemp2 );
        temp    = SRAM_readWord(SRAMoffset);  SRAMoffset++;
        Ranking[0].points= temp;
    }

    SRAM_disable();

    //update high score
    Game.high_score = (Ranking[0].points> 10000) ?  Ranking[0].points: 10000;

    return 1;
}
I think I don't understand is offset. I just make

Code: Select all

SRAMoffset++
after read/write a byte, this is logical. But also make the same when reading/writing a word... I mean... word=2 bytes... so why is this working if offset is "moving" just "1 byte"?

Another question is where I can found SRAM... is in BIN file? I tried to open BIN and look for AAA, BBB, CCC.
Only found this using HxD
Captura.PNG
Captura.PNG (5.64 KiB) Viewed 229 times
I honestly I don't know what to do... where are the points???

Stef
Very interested
Posts: 3101
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Sega Genesis Dev Kit (SGDK)

Post by Stef » Tue Jan 04, 2022 10:35 am

The first problem I see in your code is the way you handle string in C.
String requires a NULL ending character so you always need to allocate one extra character in your variable.
Also you don't need to specify it when using strxxx methods as it does add it for you, so correct code is as follow :

Code: Select all

    //data "by default" when 1st time game running
    strcpy( Ranking[0].player_name, "AAA" );
    strcpy( Ranking[1].player_name, "BBB" );
    strcpy( Ranking[2].player_name, "CCC" );
when using sprintf you can simply use the %s pattern to copy a string if it's correctly NULL terminated (which should be the case here):

Code: Select all

        
        sprintf(ctemp2, "%s", ctemp);
But here you can directly store the result in your Ranking array (I fixed a typo, you were always storing in Ranking[0] instead of Ranking) :

Code: Select all

for(u8 i=0; i<NUM_PLAYERS_RANKING; i++)
    {
        Ranking[i].player_name[0] = SRAM_readByte(SRAMoffset++);
        Ranking[i].player_name[1] = SRAM_readByte(SRAMoffset++);
        Ranking[i].player_name[2] = SRAM_readByte(SRAMoffset++);
        Ranking[i].player_name[3] = SRAM_readByte(SRAMoffset++);
        Ranking[i].points = SRAM_readWord(SRAMoffset);
        // we read a word so offset need to be increased by 2 (offset = address)
        SRAMoffset += 2;
    }
The offset is just the address where you read/write the data in SRAM so when you read/write a word it's important to add 2 to the address/offset.
I called it offset because SRAM by itself has a starting address (which is handled by SGDK).

The SRAM file is then saved by the emulator inside it's save directory (depend how you configured the emulator). Usually the file is named as the rom file but with a .sav or .sram extension.

danibus
Very interested
Posts: 127
Joined: Sat Feb 03, 2018 12:41 pm

Re: Sega Genesis Dev Kit (SGDK)

Post by danibus » Wed Jan 05, 2022 12:17 am

Stef wrote:
Tue Jan 04, 2022 10:35 am
The first problem I see in your code is the way you handle string in C.
String requires a NULL ending character so you always need to allocate one extra character in your variable.
Also you don't need to specify it when using strxxx methods as it does add it for you, so correct code is as follow :

Code: Select all

    //data "by default" when 1st time game running
    strcpy( Ranking[0].player_name, "AAA" );
    strcpy( Ranking[1].player_name, "BBB" );
    strcpy( Ranking[2].player_name, "CCC" );
when using sprintf you can simply use the %s pattern to copy a string if it's correctly NULL terminated (which should be the case here):

Code: Select all

        
        sprintf(ctemp2, "%s", ctemp);
But here you can directly store the result in your Ranking array (I fixed a typo, you were always storing in Ranking[0] instead of Ranking) :

Code: Select all

for(u8 i=0; i<NUM_PLAYERS_RANKING; i++)
    {
        Ranking[i].player_name[0] = SRAM_readByte(SRAMoffset++);
        Ranking[i].player_name[1] = SRAM_readByte(SRAMoffset++);
        Ranking[i].player_name[2] = SRAM_readByte(SRAMoffset++);
        Ranking[i].player_name[3] = SRAM_readByte(SRAMoffset++);
        Ranking[i].points = SRAM_readWord(SRAMoffset);
        // we read a word so offset need to be increased by 2 (offset = address)
        SRAMoffset += 2;
    }
The offset is just the address where you read/write the data in SRAM so when you read/write a word it's important to add 2 to the address/offset.
I called it offset because SRAM by itself has a starting address (which is handled by SGDK).

The SRAM file is then saved by the emulator inside it's save directory (depend how you configured the emulator). Usually the file is named as the rom file but with a .sav or .sram extension.
Thanks Stef. I just change my code and found sram file GensKmod is using.
Like to learn another lesson!

I read about sram even/odd use but never "saw". In this case, GensKmod, just using odds. Why this waste space?? Just emulator way of working?
In this example ranking is
name points
AAA 10001
BBB 9002
CCC 8003
Sin título.png
Sin título.png (9.7 KiB) Viewed 202 times
Anyway this is not SGDK directly related, maybe time to open in another post.

Chilly Willy
Very interested
Posts: 2880
Joined: Fri Aug 17, 2007 9:33 pm

Re: Sega Genesis Dev Kit (SGDK)

Post by Chilly Willy » Wed Jan 05, 2022 1:05 am

The MD uses a word bus, but save rams are only a byte wide. The "standard" is to put it on the odd byte lane, and then read/write every other byte to access the save ram. Some emulators toss the unused bytes, but others save the whole word, including the unused byte. So 32KB of save ram would be read/written at 0x200001 to 0x20FFFF at all the odd addresses.

Post Reply