Author Topic: How to store level data??  (Read 2821 times)

0 Members and 1 Guest are viewing this topic.

Offline spinal

  • Coder of DSision
  • Neo MOD
  • Hero Member
  • *
  • Posts: 796
    • spinalcode
How to store level data??
« on: June 28, 2010, 03:11:49 AM »
OK, currently I am storing my test levels in an array like so...

Code: [Select]
unsigned char LevelMaps[16*14 * 2] = {
1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,

1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,1,0,1,0,1,1,1,1,1,1,
1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,
1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,
1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,
1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,
6,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};

However, this is way less than ideal. My game is [hopefully] going to be a room based game, rather than scrolling, so I will require a method of storing these rooms and loading them back. Now, if I were using a modern machine, I would simply create a binary file for each room and name it depending on its location, e.g. room_x_y.bin and then load it when the character wanted to enter that room. I assume that is out of the question on the snes.
Can any suggest a method for storing my rooms?

Offline ChillyWilly

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1751
  • Just a coding machine.
Re: How to store level data??
« Reply #1 on: June 28, 2010, 03:26:42 AM »
The most common method for roms is to just keep binary files (compressed or uncompressed) and then incbin them into the game at the proper place. You can also use a rom filesystem like romfs to read the files from rom into ram, pretending the rom is a drive.

Offline spinal

  • Coder of DSision
  • Neo MOD
  • Hero Member
  • *
  • Posts: 796
    • spinalcode
Re: How to store level data??
« Reply #2 on: June 28, 2010, 03:34:56 AM »
Are you saying I can load the room data from separate files?

Offline mic_

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 632
Re: How to store level data??
« Reply #3 on: June 28, 2010, 04:00:52 AM »
If that's how you want to organize them.
Just incbin every level and memcpy the current level to another array. If the player can't alter the level (e.g. by blowing up a wall) you don't even need to do a memcpy, you can just point to the original data.
The other part is to write the correct nametable data to VRAM based on the currently loaded level, but that should just be a simple loop.

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: How to store level data??
« Reply #4 on: June 28, 2010, 11:37:29 AM »
The easiest way is to use a rom filsystem like ChillyWilly suggested.  :D
(Actually i've been working on such a rom filesystem that makes things much easier but still haven't found the time to finish it.)  ::sm-03::  O0O

The next thing you can do(for the tilemaps only) is to create a binary file with all tilemaps , then ""bin2c" it" , include it as
a constant array(make sure to use mic_'s constify tool because the snesc compiler doesn't like too much consts and can put
some of them into ram section) , then , lets say you have 32tilemap layers ( (width * height) * layers):

Code: [Select]
const unsigned char map[] = //actual "file" size is (width * height)*layers
{

};

const int mapSize = ..
const int maxTilesPerLayer = (width*height)
const int maxLayers =

Then you can make a simple function to load the map:
Code: [Select]

int loadRoom(int roomIndex,.. ? )
{
if( roomIndex >= maxLayers) //or roomIndex * maxTilesPerLayer >= mapSize
return out of bounds

copyToVram((map + (roomIndex * maxTilesPerLayer)),maxTilesPerLayer)
return all ok!
}



And if you wish to define which "exit-type tile" opens which room , you can just add a few extra info on top of each map:

Code: [Select]
1Byte - number of "links"
0...links
{
           1Byte - associated_tile_x
           1Byte - associated_tile_y
           1Byte - associated_tile_which_room_index_loads
           1Byte - for padding
}

Then with a few changes , we have :
Code: [Select]
const unsigned char map[] =
{

};

const int mapSize = ..
const int maxTilesPerLayer = (width*height)
const int maxLayers =

Then you can make a simple function to load the map:
Code: [Select]

int loadRoom(int roomIndex,.. ? )
{
volatile const unsigned char* p;
short links;
short index;

if( roomIndex >= maxLayers)
return out of bounds

links = (short)*(map + (roomIndex * maxTilesPerLayer);

if(!links)
copyToVram((map + (roomIndex * maxTilesPerLayer)+1),maxTilesPerLayer)
else
{
p = (map + (roomIndex * maxTilesPerLayer)+1);

for(index = 0; index < links; index++,p += 4)
{
tileX = *(p + index);
tileY = *(p + (index+1));
roomToLoad = *(p + (index+2));

Configure here your list with those special tiles so that when player is standing on tileY,tileX will be moved to "roomToLoad"
}

copyToVram(p,maxTilesPerLayer)
}

return all ok!
}


I hope it helped you somehow  :D  :D
« Last Edit: June 28, 2010, 11:48:59 AM by Conle »

Offline mic_

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 632
Re: How to store level data??
« Reply #5 on: June 28, 2010, 01:05:19 PM »
Quote
The next thing you can do(for the tilemaps only) is to create a binary file with all tilemaps , then ""bin2c" it" , include it as
a constant array(make sure to use mic_'s constify tool because the snesc compiler doesn't like too much consts and can put
some of them into ram section) , then , lets say you have 32tilemap layers ( (width * height) * layers)

No need for that  ;D
If he already has the maps as a set of binary files then he can just do this in an assembly file:

Code: [Select]
.include "hdr.asm"

.section ".rodata_levels" superfree

level1_data:
.incbin "level1.bin"

level2_data:
.incbin "level2.bin"

; and so on..

.ends

And then in the C code:

Code: [Select]
extern char level1_data[];  // or whatever type you want it to be
extern char level2_data[];
// ...

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: How to store level data??
« Reply #6 on: June 28, 2010, 01:22:43 PM »
No need for that  ;D
If he already has the maps as a set of binary files then he can just do this in an assembly file:

Code: [Select]
.include "hdr.asm"

.section ".rodata_levels" superfree

level1_data:
.incbin "level1.bin"

level2_data:
.incbin "level2.bin"

; and so on..

.ends

And then in the C code:

Code: [Select]
extern char level1_data[];  // or whatever type you want it to be
extern char level2_data[];
// ...

Yep , that's the same thing  :D .... unless he's making pc support tools to design his maps , then it would me much easier to compile all his maps into a single object :D