gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > creating a random map

#3707 - phr0zn - Wed Mar 05, 2003 7:37 pm

Hey everyone. I am working on a "random map" generator for my GBA project. I coded it so that I would create a double scripted map array called "map[30][20]". I then set the entire array to equal zero, then "randomly" place 1s around the map in an organized fashion to create rooms and paths. However, my problem is converting this to the gba.

What I want to do is create two background tiles, both 8x8 (hence getting a 240x160 pixel screen if there are 30x8 + 20x8 tiles). However, I cannot load them as sprites (this wouldn't make sense anyway for a background) because it would create more than the max 128 sprites at a time.

So I am wondering if it is possible to do it like this (please note im fairly new to programming for the game boy advance): by loading them into the videobuffer for each tile.

Code:

//the two tiles
#include "tile1.h"
#include "tile2.h"

u16 i,x,y;

for(x=0; x<20; x++)
      for(y=0; y<30; y++)
       {
            if(map[x][y] == 1)
            {
                  for(i = 0; i<256; i++)
                          theScreenPalette[i] = tile1Palette[i];
                   
                  u16* tempData = (u16*)tile1;
                  for(x=0; x<8; x++)
                     for(y=0; y<8; y++)
                         theVideoBuffer[y*8+8] = tempData[y*8+8];
           }
           else if(map[x][y] == 0)
           {
                  for(i = 0; i<256; i++)
                          theScreenPalette[i] = tile2Palette[i];
                   
                  u16* tempData = (u16*)tile2;
                  for(x=0; x<8; x++)
                     for(y=0; y<8; y++)
                         theVideoBuffer[y*8+8] = tempData[y*8+8];
            }
}



I really doubt this will work but my goal was to draw the tile for each time the tile is 1 or 0, to create a random background.

Any help and direction would be much appreciated. I can post more code if you need it.

Thanks a lot.
shad0an@hotmail.com

#3716 - Quirky - Thu Mar 06, 2003 8:34 am

Do you only have 2 tiles? Why not load the data for 2 tiles into vram first, then you only have to update the part of vram that contains the map. See www.thepernproject.com for how to do tiled backgrounds. This way, you only use up the VRAM for your 2 tiles (128 bytes or less depending on bits per pixel) and for the map (1024 bytes for a 32 by 32 8*8 tile map)

#3733 - phr0zn - Thu Mar 06, 2003 10:47 pm

herm. ive checked that out before. the problem is most of the tutorials deal with loading entire maps at once...or so thats what I have found. They use map editors and the such.

Ah...I have an idea now. I will just look at the source that the map editor outputs :-D thanks.

#3752 - peebrain - Fri Mar 07, 2003 6:01 pm

First problem I see is that you think that each tile can have it's own palette... There is no such thing as a "tile palette". All tiles use the same palette, the background palette. All sprite tiles use the same palette, the object palette.

~Sean
_________________
http://www.pbwhere.com

#3754 - Daikath - Fri Mar 07, 2003 6:13 pm

Sprites can use 1 256 colour pallette or 16 16 colour palette's.
_________________
?There are no stupid questions but there are a LOT of inquisitive idiots.?

#3757 - phr0zn - Fri Mar 07, 2003 10:21 pm

what if I kept the tiles in the same file, then used the entire file as a palette. then because I know that since the file would be 32x16 (two 16x16 tiles...i think this will be easier), I could say that the first tile ends at 16x...so

Code:


//the two tiles
#include "tiles.h"

u16 i,x,y;

for(i = 0; i<256; i++)
      theScreenPalette[i] = tilesPalette[i];
u16* tempData = (u16*)tiles;

for(x=0; x<20; x++)
      for(y=0; y<30; y++)
       {
            if(map[x][y] == 1)
            {       
                  for(x=0; x<16; x++)
                     for(y=0; y<16; y++)
                         theVideoBuffer[y*16+16] = tempData[y*16+16];
           }
           else if(map[x][y] == 0)
           {
                  for(x=16; x<32; x++)
                     for(y=0; y<16; y++)
                         theVideoBuffer[y*16+16] = tempData[y*16+16];
            }
}


is this how I should do it? I will test it out later (not on a comp that can compile now). thanks guys.

#3760 - phr0zn - Fri Mar 07, 2003 10:43 pm

here is my code as it is now if anyone cares.

Code:

// Typdefs
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;

typedef signed char s8;
typedef signed short s16;
typedef signed long s32;

// Defines
#define REG_DISPCNT      *(volatile u16*)0x4000000
#define REG_BG2CNT      *(volatile u16*)0x400000C
#define VCOUNT         *(volatile u16*)0x4000006
#define REG_BG2X      *(volatile u32*)0x4000028

//define the keys and macros
#define KEYSTART 8
#define KEYS (*(volatile u16*)0x4000130)
#define KEY_DOWN(k) (!((KEYS)&k))

//define our background
#define REG_BG2Y      *(volatile u32*)0x400002C

//define colour macro
#define COLOUR(r, g, b)   ((b << 10) | (g << 5) | r)

//video memory globals
u16* VRAM = (u16*)0x6000000;
u16* paletteMem = (u16*)0x5000000;

//our random maximum
#define RAND_MAX 4

//our directions
#define LEFT 0
#define RIGHT 1
#define UP 2
#define DOWN 3

//this is so it works with my MBV2 cable so I can test it on the Hardware
#define MULTIBOOT volatile const u8 __gba_multiboot;   
MULTIBOOT

//random data global
volatile s32 RAND_RandomData;

void PlotPixel(int x, int y, u16 c);
void ClearScreen(void);
void SeedRandom(void);
s32 RAND(s32 Value);

//our includes
#include "char.h"
#include "messages.h"
#include "tiles.h" //our tiles file

int main(void)
{
   REG_DISPCNT = 0x1403;
   REG_BG2CNT = 0x0000;


   u16 map[15][10]; //a 15x10 16x16 tile map
   u16 dir; //our current direction
   u16 xpos; //our x position
   u16 ypos; //our Y position
   u16 i; //a counter

   u16 x, y, j;  //for the palettes, etc.

   //set up the screenpalette and the temporary data for "tiles"
   for(i = 0; i<256; i++)
      paletteMem[i] = tilesPalette[i];
    u16* tempData = (u16*)tiles;


   for(xpos=0; xpos < 10; xpos++)  //make every single int in map[15][10] = 0
    {
       for(ypos = 0; ypos < 15; ypos++)
       {
              map[ypos][xpos] = 0;
       }
    }
   
    map[7][5] = 1;  //set absolute middle to equal 1.
   
    xpos = 7;  //set the X and Y starting position...at (15,10)
    ypos = 5;

   i=1; //reset i to 1
      
   DisplayText(helpstring, 20, 0, 145);  //our initial screen text

   if(KEY_DOWN(KEYSTART))  //if the key 'start' is down
   {
         ClearScreen();  //clear the screen

    while(1) //the game has begun
   {

      SeedRandom();

      while(i<75)
      {
         dir = RAND(4); //get a random number between 0 and 3
       
         if(dir == LEFT)     
         {
            if(xpos>0)
            {
               xpos--;
               if(map[xpos][ypos] == 0)
               {
                  map[xpos][ypos] = 1;
                  i++;
               }
            }
         }
         else if(dir == RIGHT) //ibit
         {
            if(xpos<29)
            {
               xpos++;
               if(map[xpos][ypos] == 0)
               {
                  map[xpos][ypos] = 1;
                  i++;
               }
            }   //make it equal one 
         }
         else if(dir == UP)  //ibit
         {
            if(ypos<19)
            {
               ypos++;
               if(map[xpos][ypos] == 0)
               {
                   map[xpos][ypos] = 1;
                  i++;
               }
            }
         }
         else if(dir == DOWN)  //ibit
         {
            if(ypos>0)
            {
               ypos--;
               if(map[xpos][ypos] == 0)
               {
                  map[xpos][ypos] = 1;
                  i++;
               }
            }
         }
      }


for(xpos=0; xpos < 10; xpos++)
   {
       for(ypos = 0; ypos < 15; ypos++)
      {
          if(map[xpos][ypos] == 1)
            {     //draw the first half the the image
                  for(x=0; x<16; x++)
                     for(y=0; y<16; y++)
                         VRAM[y*16+x] = tempData[y*16+x];
           }
           else if(map[xpos][ypos] == 0)
           {      //draw the second half
                  for(x=16; x<32; x++)
                     for(y=0; y<16; y++)
                         VRAM[y*32+x] = tempData[y*32+x];
            }

      }
   }

   #ifndef DDEBUG
      DisplayNumber(i, 235, 150);
   #endif

   } //end while

} //end if

   return 0;
}

void PlotPixel(int x, int y, u16 c)
{
   VRAM[x + (y * 240)] = c;
}

void ClearScreen(void)
{
   REG_BG2X = 0;
   REG_BG2Y = 0;
   u16 x,y;
   for(y = 0; y <160; y++)
      for(x = 0; x < 240; x++)
         PlotPixel(x,y,0x0000);
}


void SeedRandom(void)
{
   RAND_RandomData = VCOUNT;
}


s32 RAND(s32 Value)
{
   RAND_RandomData *= 20077;
   RAND_RandomData += 12345;

   return ((((RAND_RandomData >> 16) & RAND_MAX) * Value) >> 15);
}