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.

Beginners > For Fire Demo Need Help

#29517 - cba - Sun Nov 21, 2004 10:31 am

Hi,
I am a french's noob trying to make a simple fire demo. But after a lot of try, I don't find what I'am doing wrong in my code.

Could you help me ?

Thanks,
Cba




Code:
#include "gba.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define VCOUNT *(volatile u16*)0x4000006

//random max
#define RAND_MAX 32767
volatile s32 RAND_RandomData;

void SeedRandom(void);
void waitForVSync(void);
void flipBuffers(void);
void Create_Fire_Pal(void);

s32 RAND(s32 Value);
#define twopixel(a,b) ( (u16)( (a<<8) | b ) )
u16* videoBuffer   = (u16*) 0x6000000;


int main()
{
   int x,y;
   u16 tabcolor[31];
   u8 tabref[240][160];
    u16 avg;    //average color
    u8 color; //fire color   

   SetMode(MODE_4 | BG2_ENABLE);

   Create_Fire_Pal();
   
   flipBuffers();
   
   SeedRandom();         

   u8 white = 128;
   
   // Then loop
   while ( true )
   {
      // bottom row is withe
      for(x=0; x<240; x=x+2)
       {          
           tabref[x][159] = white;
           tabref[x+1][159] = white;
           videoBuffer[(159*120)+x/2] = twopixel(tabref[x][159],tabref[x+1][159]);
       }      
         
      for(y=157; y<160; y++)
        {
            for(x=0; x<240; x+=16)
            {
                color = (char)rand()%128;     // get a random color
               
                if(color>64) color = 128; // all or nothing;
                if(color<63) color = 0;   // white or black
               
                // this just makes fatter fire -- horizontal 8-pixel
                // wide seed colors. Try changing this to just 4-pixel
                // wide seeds and see what happens.
                for (int j=0;j<16;j++ )
                {
                   tabref[x+j][y]=color;
                }

                videoBuffer[(y*120)+x/2]   = twopixel(tabref[x][y],tabref[x+1][y]);
                videoBuffer[(y*120)+x/2+1] = twopixel(tabref[x+2][y],tabref[x+3][y]);
                videoBuffer[(y*120)+x/2+2] = twopixel(tabref[x+4][y],tabref[x+5][y]);
                videoBuffer[(y*120)+x/2+3] = twopixel(tabref[x+6][y],tabref[x+7][y]);
                videoBuffer[(y*120)+x/2+4] = twopixel(tabref[x+8][y],tabref[x+9][y]);
                videoBuffer[(y*120)+x/2+5] = twopixel(tabref[x+10][y],tabref[x+11][y]);
                videoBuffer[(y*120)+x/2+6] = twopixel(tabref[x+12][y],tabref[x+13][y]);
                videoBuffer[(y*120)+x/2+7] = twopixel(tabref[x+14][y],tabref[x+15][y]);
            }
        }   

      // then get the uppers val      
      for(y=159; y>0; y--)
        {
            avg = 0;
           
            for(x=0; x<240; x=x+2)
            {
               
               if ( x!=0 )
               {
                   avg  = tabref[x][y+1];
                   avg += tabref[x-1][y];
                   avg += tabref[x][y];
                   avg += tabref[x+1][y];                           
                   avg = avg/4;               
                   if(avg>1) avg -= 1;                   
                   if ( avg>128 ) avg=127;
                  tabref[x][y] = avg;        
               }
               else
               {
                  tabref[x][y]=0;
               }
               
                avg  = tabref[x+1][y+1];
                avg += tabref[x+1-1][y];
                avg += tabref[x+1][y];
                avg += tabref[x+1+1][y];                           
                avg = avg/4;               
                if(avg>1) avg -= 1; 
               
                if ( avg>128 ) avg=127; 
                                           
                  tabref[x+1][y] = avg;                 
               
                // move "blurred" pixel up by one line
                videoBuffer[(y*120)+x/2]   = twopixel(tabref[x][y],tabref[x+1][y]);                             
               
                //videoBuffer[(y*120)+x/2]   = twopixel(tabref[x][y],white);                                             
            }
        }      
      
      flipBuffers();      
   }

return 0;

}


void Create_Fire_Pal()
{
    u8 i = 0;
   
    for (i=0; i<32; i++)
    {
        BG_PaletteMem[i]     = RGB(i,0,0);     // black to max red
        BG_PaletteMem[i+32]  = RGB(31,i,0);    // max red to max yellow
        BG_PaletteMem[i+64]  = RGB(31,31,0);   // max yellow
        BG_PaletteMem[i+96 ] = RGB(31,31-i,0); // max yellow to red; we just do the opposite of the color eqn above     
    }
    BG_PaletteMem[ 128 ]=RGB(31,31,31);
}

void flipBuffers()
{
  if (REG_DISPCNT & backbuffer)
  {
    REG_DISPCNT &= ~backbuffer;
    videoBuffer = videoBackBuffer;
  } else {
    REG_DISPCNT |= backbuffer;
    videoBuffer = FrontBuffer;
  }

} // fin flipBuffers()

void waitForVSync()
{
  volatile u16* vreg = (volatile u16*) 0x04000004;
  while (  *vreg & (1 << 0));
  while (!(*vreg & (1 << 0)));

} // fin waitForVSync()

void SeedRandom(void)
{
RAND_RandomData = VCOUNT;
}

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

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



_________________
Cba

#29523 - Cearn - Sun Nov 21, 2004 1:32 pm

I was going to mention that it's usually a good idea to trace the bug in a small section of code before posting and give a description of what goes wrong, but seeing the code run I can completely understand why you didn't.
The main problem is the definition of tabref[240][160]. Local variables will always go into IWRAM, which is 32kB in size. tabref is 38kB, and therefore swamps your whole work RAM. After that, anything can happen.
A solution to this would be to make it a global variable and put it into EWRAM, your gba.h should have a IN_EWRAM definition, or something of the sort, then define tabref as
Code:

// global scope
u8 tabref[240][160] IN_EWRAM;

It won't solve all your problems, but at least it doesn't crash anymore.

One more thing. I'm sure someone will correct me for this if I'm wrong, but I thought that multidimensional arrays in C were row-based, so the last index would be for adjacent memory. tabref[240][160] would have 240 rows of 160 entries, not 160 rows of 240 entries, meaning you've effectively transposed the screen.

#29525 - cba - Sun Nov 21, 2004 2:16 pm

Thanks a lot I am going to try that
_________________
Cba

#29627 - cba - Mon Nov 22, 2004 9:20 pm

A very big thanks It is working :) Youpi
_________________
Cba