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.

DS development > Sound problems after some minutes of play...

#168689 - HarryPitfall - Fri May 15, 2009 6:05 pm

Hello people, I'm getting a really strange behavior with my 'prototype' game...
After 3 or 4 minutes of play, the game just stop to play sounds, mmEffectEx just do nothing. I'm using a music also while the game is running (the music is fine, but the effect stops to play).
I test on 2 emulators, and they have the bug, I didn't test on a real hardware...
There is something wrong with the code itself that i don't see?

Code:

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

#include "soundbank.h"
#include "soundbank_bin.h"

// Console Helper Functions

void clearScreen() {
   iprintf("\x1b[2J");
}

void printAt(int line, int column, int color, const char* str) {
   iprintf("\x1b[%d;%dH\x1b[%dm%s", line, column, color, str);
}

const char* strEnemy[4] = {">o<", "@", "$", "#"};

typedef struct {
   int active;
   int x, y;
   int type;
   int hp;
   int size;   
   int color;
} enemyData;


int main() {
   // Randomize
   srand(time(NULL));
   // Load Sound/Music
   mmInitDefaultMem((mm_addr)soundbank_bin);
   mmLoadEffect(SFX_BOOM);
   mmLoadEffect(SFX_SHOT);
   mmLoadEffect(SFX_GETHIT);
   mmLoadEffect(SFX_GETSCORE);
   mmLoadEffect(SFX_GETSHIELD);
   // Effect
   mm_sound_effect boom = {
      { SFX_BOOM } ,         // id
      (int)(1.0f * (1<<10)),   // rate
      0,      // handle
      255,   // volume
      127,   // panning
   };
   mm_sound_effect shot = {
      { SFX_SHOT } ,         // id
      (int)(1.0f * (1<<10)),   // rate
      0,      // handle
      255,   // volume
      127,   // panning
   };
   mm_sound_effect gethit = {
      { SFX_GETHIT } ,         // id
      (int)(1.0f * (1<<10)),   // rate
      0,      // handle
      255,   // volume
      127,   // panning
   };
   mm_sound_effect getscore = {
      { SFX_GETSCORE } ,         // id
      (int)(1.0f * (1<<10)),   // rate
      0,      // handle
      255,   // volume
      127,   // panning
   };
   mm_sound_effect getshield = {
      { SFX_GETSHIELD } ,         // id
      (int)(1.0f * (1<<10)),   // rate
      0,      // handle
      255,   // volume
      127,   // panning
   };
   mmLoad(MOD_BGMUSIC);
   mmSetModuleVolume(512); // Half Volume...
   // SubScreen = Console (32 columns, 24 rows)
   consoleDemoInit();
   //  Video Mode...
   videoSetMode(MODE_FB0);
   vramSetBankA(VRAM_A_LCD);
   // Raw Draw (Upper Screen)
   for(int row = 0; row < 192; row++)
      for(int col = 0; col < 256; col++) {
         int offset = (row * 256) + col;
         VRAM_A[offset] = RGB15(row % 32, col % 32, (offset>>1) % 32);
      }
   //
   while (1) {
      clearScreen();
      int flag1 = 0;
      while (flag1 == 0) {
         printAt(11,  9, 39, "+------------+");
         printAt(12,  9, 39, "|            |");
         printAt(13,  9, 39, "+------------+");
         printAt(12, 11, 45, "SPACE RAID");
         scanKeys();
         if (keysDown() & KEY_A) flag1 = 1;
         swiWaitForVBlank();
      }
      //
      mmStart(MOD_BGMUSIC, MM_PLAY_LOOP);      
      //      
      int nextobj = 0;   
      enemyData objs[10];
      for(int i = 0; i < 10; i++) {
         objs[i].active = 0;
         objs[i].x = 0;
         objs[i].y = 0;
         objs[i].type = 0;
         objs[i].hp = 0;
         objs[i].size = 0;
         objs[i].color = 0;
      }
      //
      int navex = 15;
      int score = 0;
      int shield = 5;
      int framejump = 0;
      int framecount = 0;
      int takedown = 0;
      int combo = 0;      
      int iscomboenabled = 0;
      while (shield > 0) {   
         framejump = (framejump+1) % 3;
         if (framejump == 0) {
            framecount = (framecount+1) % 360; // 360 is a good number (div 2, 3, 5, 6, 10)
            int isShot = 0;
            // Input
            scanKeys();
            /* Handle left and right parts of D-Pad. */
            if (keysHeld() & KEY_LEFT) {
               if (navex > 2) navex--;
            } else if (keysHeld() & KEY_RIGHT) {
               if (navex < 29) navex++;
            }
            /* Fire? */
            if (keysDown() & KEY_A) {
               isShot = 1;            
            }
            // Logic
            if (((rand() % 5) == 0) && (objs[nextobj].active == 0)) {
               objs[nextobj].active = 1;
               objs[nextobj].type = rand() % 2;
               objs[nextobj].x = 2 + (rand() % 28);
               objs[nextobj].y = -1;
               objs[nextobj].hp = 0; // Unused for now...
               // Change Type If...
               if (takedown > 5) {
                  takedown = 0;
                  objs[nextobj].type = 2;
               }
               if (iscomboenabled == 1) {
                  iscomboenabled = 0;
                  objs[nextobj].type = 3;
               }
               
               if (objs[nextobj].type == 0)
                  objs[nextobj].size = 1;
               else
                  objs[nextobj].size = 0;
               if (objs[nextobj].type < 2)   
                  objs[nextobj].color = 44;
               else
                  objs[nextobj].color = 43;
               // So, can change into bonus if...
               nextobj = (nextobj + 1) % 10;
            }
            for(int i = 0; i < 10; i++) {
               if (objs[i].active == 1) {
                  objs[i].y++;
                  if (objs[i].y == 21) {
                     // Colision Check, Shields and Game Over...
                     int distance = navex - objs[i].x;
                     int hitfactor = 2 + objs[i].size;
                     if ((distance < hitfactor) && (distance > -hitfactor)) {
                        if (objs[i].type == 2) {
                           score+=50;         
                           getscore.handle = mmEffectEx(&getscore);
                        } else if (objs[i].type == 3) {
                           shield++;
                           getshield.handle = mmEffectEx(&getshield);
                        } else {                     
                           objs[i].active = 0;
                           shield--;
                           gethit.handle = mmEffectEx(&gethit);
                        }
                     }
                  } else if (objs[i].y > 21) {
                     objs[i].active = 0;
                  }
               }
            }
            // Output
            clearScreen();
            printAt(21, navex - 1, 43, "<^>");
            if (isShot) {
               mmEffectEx(&shot);
               int j = 0;
               combo = 0;
               for(int i = 20; i > 0; i--) {
                  printAt(i, navex, 41, "|");
                  // Check colision, if did it, stop the phaser here... add points and disable enemy, also, draw the hit (amazing)                  
                  for(int k = 0; k < 10; k++) {
                     if ((objs[k].active == 1) && (objs[k].type < 2)) {
                        if (
                           (objs[k].x == navex) ||
                           ((objs[k].x-objs[k].size) == navex) ||
                           ((objs[k].x+objs[k].size) == navex)
                        ) {
                           j = 1; // Something Get's Hit!
                           objs[k].active = 0;
                           score += ((objs[k].type + 1) * 5);
                           printAt(objs[k].y - 1, objs[k].x - 1, 41, "\\|/");
                           printAt(objs[k].y,     objs[k].x - 1, 41, "- -");
                           printAt(objs[k].y + 1, objs[k].x - 1, 41, "/|\\");                           
                           takedown++;
                           combo++;
                        }               
                     }
                  }
               }   
               if (combo > 2)
                  iscomboenabled = 1;
               if (j == 0)
                  score--; // Missing shots costs 1 score...
               else
                  boom.handle = mmEffectEx(&boom); // Hit Sound!
            }      
            for(int i = 0; i < 10; i++) {
               if (objs[i].active == 1) {
                  printAt(objs[i].y, objs[i].x - objs[i].size, objs[i].color, strEnemy[objs[i].type]);
               }   
            }
            printAt(22, 0,         42, "================================");
            printAt(23, 1,         46, "Score: "); iprintf("%d", score);
            printAt(23, 20,        46, "Shield: "); iprintf("%d", shield);
            // Wait
         }
         swiWaitForVBlank();
      }   
      //
      mmStop();
      //
      int flag2 = 0;
      while (flag2 == 0) {
         printAt(11, 10, 39, "+-----------+");
         printAt(12, 10, 39, "|           |");
         printAt(13, 10, 39, "+-----------+");
         printAt(12, 12, 39 + (rand() % 8), "GAME OVER");
         scanKeys();
         if (keysDown() & KEY_A) flag2 = 1;
         swiWaitForVBlank();
      }
   }
   // Halt      
   return 0;
}