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 > Yay! Translucent plasma.

#173589 - relminator - Sun Apr 18, 2010 9:17 am

It's in Framebuffer mode. Anyway i could combine this with standard mode 5 screens?

Source + executable:
http://www.file-pasta.com/file/0/plasma.zip


Code:

/*
NDS Translucent Plasma
Relminator

http://rel.betterwebber.com

*/

#include <nds.h>
#include <stdio.h>
#include <math.h>


// some sine LUTs
u8 lsin1[2048];
u8 lsin2[2048];
u8 lsin3[2048];

// RGB palette
u16 pal[256];   

int main(void)
{
   
   // constant sine divisor
   const u8 K1 = 32;
    const u8 K2 = 12;
    const u8 K3 = 28;
   
   // maximum values our dynamic plasmas can move
   u16 KSIN1 = u8(K1 *(360/57.3f));
    u16 KSIN2 = u8(K2 *(360/57.3f));
    u16 KSIN3 = u8(K3 *(360/57.3f));
   
   
          
   // precalculate our luts
   for (int i = 0; i< ((2048) - 1); i++)
   {
        lsin1[i] = sin(i/(float)K1) * 32+32;
        lsin2[i] = sin(i/(float)K2) * 16+16;
        lsin3[i] = sin(i/(float)K3) * 20+20;
    }   

   // generate our 256 color palette
   for (int i=0; i<256; i++)
   {
       u8 r = (u8)(abs(int(16 - 15 * sin(i * M_PI / 16.0f))));
      u8 g = (u8)(abs(int(16 - 15 * sin(i * M_PI / 12.0f))));
      u8 b = (u8)(abs(int(16 - 15 * sin(i * M_PI / 18.0f))));
      pal[i] = RGB15(r,g,b);
   }

   irqInit();
   irqEnable(IRQ_VBLANK);
   
   
   //initialize the DS Dos-like functionality
   consoleDemoInit();
   
   iprintf("\x1b[1;1HTranslucent Plasma!");
   iprintf("\x1b[2;1HFramebuffer madness!");
   iprintf("\x1b[3;1HRelsoft");
   iprintf("\x1b[4;1Hhttp://rel.betterwebber.com");
   iprintf("\x1b[6;1HAnya Therese B. Lope");
 
   //set frame buffer mode 0
   videoSetMode(MODE_FB0);
 
   //enable VRAM A for writting by the cpu and use
   //as a framebuffer by video hardware
   vramSetBankA(VRAM_A_LCD);
 
   u8 rot;                  // translucent factor
   u16 counter =0;            // frame counter
   u16 a = 0, b = 0, ct = 0;   // movement deltas
   u16 c;                  // palette color index
   
   while(1)
   {

      // dynamically move our plasmas
      a= (a + 1) % (KSIN1 + 1);
      b = (b + 1) % (KSIN2 + 1);
      ct = (ct + 1) % (KSIN3 + 1);
      
      // offset 2nd plasma by a factor of 64 * 2 or (-64 to 64)
      rot = 64 * (((counter & 1) == 1) | 1);
      
      // inc frame
      counter++;
      
      //write to vram directly
      short unsigned int *vram_offset = VRAM_A;
      
      for (int ya = 0; ya<SCREEN_HEIGHT; ya++)
      {
         for (int xa = 0; xa <SCREEN_WIDTH-1; xa++)
         {
            rot = -rot;      // draw plasmas every other pixel
            // calculate colors
            c = (lsin1[xa + a + rot] + lsin2[ya + b + rot] +lsin3[1024+xa + ya - ct]);
            c = (lsin1[xa + a + rot+c] + lsin2[ya + b + rot+c] +lsin3[1024+xa + ya - ct+c]);
            // write to vram
            *vram_offset++ = pal[c];
         }
         vram_offset++;      // magic
      }      
      swiWaitForVBlank();
   }
 
   return 0;
}
 

_________________
http://rel.betterwebber.com

#173590 - Ruben - Sun Apr 18, 2010 10:38 am

Nice effect. A few recommendations:

-Upsize u8/u16 to u32 unless you absolutely need them to be that type; this will speed things up a bit.
-How about mode 0 tile-blitting? You could pack two pixels at once
-Wait for VBlank *before* drawing; tiny but yeah
-I'm not 100% sure, but libnds may have hardware division/modulo routines
-Pre-calculate LUT data