The small-questions-not-worth-dedicated-topics topic

SGDK only sub forum

Moderator: Stef

Post Reply
diegzumillo
Interested
Posts: 15
Joined: Sun Sep 08, 2019 6:35 pm

The small-questions-not-worth-dedicated-topics topic

Post by diegzumillo » Thu Mar 12, 2020 3:31 pm

Hi
I am trying to learn how to use SGDK while also learning how to work with plain C. So everything is a struggle. I don't want to clog the forum nor hijack the discord channel too much so I decided to make a topic to dump all my questions, anyone interested in asking their questions here is also welcome!

Here is my first one. I understand we use const to save data to the rom. But if I need to have a writable version of it in runtime, is there a proper way of doing things or do I just create a new variable and copy the values from a to b?

On the same topic. I am trying to code the basic structure of a level loader. SGDK already has some useful tools, like the map stuff, but that's only the visual part. My idea is to define the level as a struct, with all the info needed in it, including arrays of game-related structs like "platform", "block", "enemy x". Now, for sake of simplicity I would do the visual part like this as well; define the tiles in it. BUT I'm afraid whatever I come up with won't make efficient use of memory. I assume sgdk's map function does have some kind of compression system. How are you guys doing this? something like what I'm describing?

Grind
Very interested
Posts: 69
Joined: Fri Jun 13, 2014 1:26 pm
Location: US
Contact:

Re: The small-questions-not-worth-dedicated-topics topic

Post by Grind » Fri Mar 13, 2020 6:39 pm

You said "platforms" so I'm going to assume you are making a platformer :P
It doesn't matter too much how you organize it, and most stuff can just stay in ROM without consuming any memory. Games like this (well, even top down RPGs too) organize maps like:

Tile set - The list of available tile graphics to draw, could be straight up 8x8 VDP tiles or "meta-tiles" that are 16x16 or 32x32 for example
Tile attributes - For each of those tiles in the tile set, some flags/values that represent how they are interacted with
(This is separate from the TILE_ATTR stuff in SGDK, which is just telling the VDP how to draw tiles)

Map meta data - width and height of your level, the name that gets displayed, which tile set to load, music that plays, etc
Map tiles - A list of indexes in a tile set drawn in order (left to right then up to down usually)
Map object list - List of enemies, items, etc. Stuff that can't be implemented as a simple map tile and needs to be a full blown game object

If you can help it, it's better for the level tile maps to stay in ROM, but some games make modifications to the map itself at runtime. In that case you could do something like this. Be careful with that though you only have 64k RAM.

Code: Select all

// Allocate memory for mappings
u16 *myMap = MEM_alloc(<number of array elements> * sizeof(u16));
// Copy map data to RAM
memcpy(myMap, theConstMap, <number of array elements> * sizeof(u16));
// Change stuff
myMap[i] = something;

// ... play the level ...

// Done with the mapping, delete it
MEM_free(myMap);
For metadata I've used a sort of "struct database". There are probably better ways, it's just a matter of taste.

Code: Select all

// Typedef in header
#define STAGE_COUNT 95
typedef struct {
	const uint8_t *PXM; // PXM is the layout, each byte is an index of the current tileset
	const uint8_t *PXE; // PXE is the entity list
	const uint8_t *TSC; // TSC is the script
	const uint8_t *JTSC; // Japanese version of the Stage TSC
	// Which palette to load for PAL3. Most use PAL_Regu but some differ
	const Palette *npcPalette;
	uint8_t tileset; // Which tileset in tileset_info to use
	uint8_t background; // Which background in background_info to use
	char name[24]; // The name of the map, as displayed to the player
} stage_info_def;
extern const stage_info_def stage_info[STAGE_COUNT];
// Implementation in source file
const stage_info_def stage_info[STAGE_COUNT] = {
	{ NULL,		NULL,		NULL,		NULL,		&PAL_Regu,	0,	0,	"" },
	{ PXM_Pens1,	PXE_Pens1,	TSC_Pens1,	JTSC_Pens1,	&PAL_LabB,	16,	14,	"Arthur's House" },
	{ PXM_Eggs,	PXE_Eggs,	TSC_Eggs,	JTSC_Eggs,	&PAL_Regu,	6,	13,	"Egg Corridor" },
};
All the ways the player interacts with the level can be defined in tile attributes with different values. So 1 could mean completely solid, 2 could be a one way platform, 3 a ladder, 4 a spike that hurts you. So whenever you are implementing your collision it can be done very efficiently without needing to do any loops to search through tiles:

Code: Select all

// Attributes
const u8 attributes[4] = { TA_NONE, TA_SOLID, TA_LADDER, TA_PLATFORM };
// Tile map
const u8 level[16] = {
    0, 0, 0, 0,
    0, 3, 3, 2,
    0, 0, 0, 2,
    1, 1, 1, 1,
};
// Check what kind of tile the player is touching
u8 tile_index = level[player_x + level_width * player_y];
u8 tile_attribute = attributes[tile_index];

diegzumillo
Interested
Posts: 15
Joined: Sun Sep 08, 2019 6:35 pm

Re: The small-questions-not-worth-dedicated-topics topic

Post by diegzumillo » Tue Mar 24, 2020 10:40 pm

Oh shoot! I didn't get a notification and just assumed no one replied. Thank you for taking the time to explain these things to me. I'm happy to say I have learned quite a bit since I made that original post!

I do have more questions though :D Although it's not "too small to have a dedicated post" I'll put it here anyway.

I am currently trying to setup a way to have background elements to be on front of the player. Ideally, I would have stuff on planA, stuff on planB, sprite, then some of that stuff from planB would be set to have priority flag on, in order to be in front of the player. But I can't for the life of me figure out how to do this. I don't want to use the drawImage functions because the maps are quite large, so I need VDP_setMapEx to define which portions of the map I want to draw. OK, so now I use that function to draw background on planB, good, then I call it again to draw stuff on planA, good, then I call it again to draw some foreground elements on planA with priority flag on, but since these are all drawing over the whole screen it overwrites what I put before.

Is there a way to use VDP_setMapEx with different priority flags depending on the tile? Or is there already a more established way of doing what I want that I'm unaware of? I considered using sprites but that's risky, I don't know how many sprites that will take.

edit: found the option to turn email notifications on and it was on already. Then I found the notification in my spam folder :x

Miquel
Very interested
Posts: 514
Joined: Sat Jul 30, 2016 12:33 am

Re: The small-questions-not-worth-dedicated-topics topic

Post by Miquel » Tue Mar 24, 2020 11:53 pm

diegzumillo wrote:
Thu Mar 12, 2020 3:31 pm
Here is my first one. I understand we use const to save data to the rom. But if I need to have a writable version of it in runtime, is there a proper way of doing things or do I just create a new variable and copy the values from a to b?
Don't do that, you're making it worst. Use "const" for data that never changes.
The exception is compressed data.
HELP. Spanish TVs are brain washing people to be hostile to me.

diegzumillo
Interested
Posts: 15
Joined: Sun Sep 08, 2019 6:35 pm

Re: The small-questions-not-worth-dedicated-topics topic

Post by diegzumillo » Wed Mar 25, 2020 12:01 am

Miquel wrote:
Tue Mar 24, 2020 11:53 pm
diegzumillo wrote:
Thu Mar 12, 2020 3:31 pm
Here is my first one. I understand we use const to save data to the rom. But if I need to have a writable version of it in runtime, is there a proper way of doing things or do I just create a new variable and copy the values from a to b?
Don't do that, you're making it worst. Use "const" for data that never changes.
The exception is compressed data.
I know, that's what I meant. Stuff on ROM cannot be changed, it's read only, it's the stuff on the cart, so we use const. BUT if we want a version of it that changes (say, the level has a door that can be opened or closed) then you need to copy the current level from the rom to a non const version in the RAM.

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

Re: The small-questions-not-worth-dedicated-topics topic

Post by Chilly Willy » Wed Mar 25, 2020 8:56 pm

It's better to just have the level setup code copy the rom level data to ram in a case like that. If the level data needs to stay between levels for some reason, you're in big trouble as the MD has very little ram. In a case like THAT, I'd say require save ram and store a compressed delta of the level data from rom and the level data as it is in ram to the save ram.

Post Reply