Dark Bit Factory & Gravity
PROGRAMMING => C / C++ /C# => Topic started by: relsoft on April 29, 2010
-
Hey guys, I've been coding on C/C++ again after 5 years (LOL).
Anyways, how does one use NDEBUG and assert() aminly in multi module programs?
Do I have to define NDEBUG to each and every modules header that uses assert() to disable assertion? Or just doing it the way I do now would work (defining it before including the headers whose modules uses assert())?
Aso NDEBUG is NO DEBUG right?
I don't know if this is the correct way.
main:
#define NDEBUG
#include <nds.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include "cearn_atan.h"
#include "Cspline.h"
#include "Csprite.h"
#include "Cobject.h"
#include "Cbullet.h"
#include "Cenemy.h"
#include "Cshot.h"
#include "Coption.h"
#include "Cviper.h"
#include "nds_ship.h"
#include "nds_shot.h"
#include "nds_opt.h"
#include "nds_blt_.h"
#include "nds_en16_.h"
#include "nds_en_64x32_.h"
#define MAX_SPRITES 128
#define MAX_POINTS 8
#define MAX_ENEMIES 7
#define FP_PI 16384
/******************************************************************************
*******************************************************************************
MAIN entry point
*******************************************************************************
******************************************************************************/
u16 Csprite::num_sprites = 0;
Cenemy enemies[MAX_ENEMIES];
Cviper viper;
int main(void)
{
videoSetMode(MODE_5_2D);
videoSetModeSub(MODE_5_2D);
vramSetBankA(VRAM_A_MAIN_SPRITE);
vramSetBankB(VRAM_B_MAIN_SPRITE);
vramSetBankD(VRAM_D_SUB_SPRITE);
consoleDemoInit();
iprintf("\x1b[1;1HSpace Impakto DS");
iprintf("\x1b[2;1HRelminator");
iprintf("\x1b[4;1HEnemy uses Fixed point");
iprintf("\x1b[5;1Hcatmull-Rom spline");
iprintf("\x1b[6;1Hhttp://rel.betterwebber.com");
iprintf("\x1b[9;1HControls:");
iprintf("\x1b[10;1HArrows->move");
iprintf("\x1b[11;1HKey A->Fire weapons");
//api: initialize OAM to 1D mapping with XX byte offsets and no external palette
oamInit(&oamMain, SpriteMapping_1D_128, false);
//
viper.initialize( (u8*)nds_shipTiles, (u8*)nds_shotTiles, (u8*)nds_optTiles, (u8*)nds_blt_Tiles );
//Cobject::init(OamState *_oam,u8 *_gfx, u32 _width, u32 _height, SpriteSize _size, u32 _numframes)
int width = 16;
int height = 16;
SpriteSize size = SpriteSize_16x16;
enemies[0].init(&oamMain, (u8*)nds_en16_Tiles, width, height, size, 6, E_GFX_VRAM);
// second sprite test
enemies[1].init(&oamMain, (u8*)nds_en16_Tiles+(16*16*6), width, height, size, 4, E_GFX_VRAM);
for (int i=0; i<enemies[1].num_frames; i++)
{
enemies[1].sprites[i].x = 100;
enemies[1].sprites[i].y = 100;
}
// test for single frame sprite
enemies[2].init(&oamMain, (u8*)nds_en16_Tiles+(16*16*10), width, height, size, 1, E_GFX_VRAM);
enemies[2].sprites[0].x = 10;
enemies[2].sprites[0].y = 100;
// see if oam get inremented after single frame sprite
enemies[3].init(&oamMain, (u8*)nds_en16_Tiles+(16*16*16), width, height, size, 2, E_GFX_VRAM);
for (int i=0; i< enemies[3].num_frames; i++)
{
enemies[3].sprites[i].x = 100;
enemies[3].sprites[i].y = 10;
}
// see if RAM based enemy would work
enemies[4].init(&oamMain, (u8*)nds_en16_Tiles+(16*16*10), width, height, size, 6, E_GFX_RAM);
// safe reference
enemies[4].sprites->x = 200;
enemies[4].sprites->y = 10;
// see if non-animated RAM based enemy would work
enemies[5].init(&oamMain, (u8*)nds_en16_Tiles+(16*16*0), width, height, size, 1, E_GFX_RAM);
// alternative but not safe reference just to test
enemies[5].sprites[0].x = 200;
enemies[5].sprites[0].y = 100;
// use a different tilset (64x32)
width = 64;
height = 32;
size = SpriteSize_64x32;
enemies[6].init(&oamMain, (u8*)nds_en_64x32_Tiles+(64*32*4), width, height, size, 3, E_GFX_VRAM);
enemies[6].anim_delay = 7;
for (int i=0; i < enemies[6].num_frames; i++)
{
enemies[6].sprites[i].x = 50;
enemies[6].sprites[i].y = 50;
}
// palette
dmaCopy(nds_shipPal, SPRITE_PALETTE, 512);
for (int i=0; i<MAX_ENEMIES; i++)
{
enemies[i].init_spline(MAX_POINTS);
}
//enemies[0].init_spline(MAX_POINTS);
u16 total_frame = 0;
while(1)
{
total_frame++;
for (int i=0; i<MAX_ENEMIES; i++)
{
enemies[i].update();
enemies[i].update_oam();
}
viper.control(enemies[6]);
viper.update();
// wait retrace
swiWaitForVBlank();
//api: updates real oam memory
oamUpdate(&oamMain);
/*
*
* consoleClear();
* printf("direction= %i \n", Gdir);
* printf("direction_counter= %i \n", Gdir_c);
* printf("frame offset= %i \n", G_frame);
*
*/
}
return 0;
}
sub module:
/******************************************************************************
*******************************************************************************
Space Impakto DS
relminator
http://rel.betterwebber.com
Cobject class
*******************************************************************************
******************************************************************************/
#include <nds.h>
#include <assert.h>
#include "Csprite.h"
#include "Cobject.h"
/******************************************************************************
******************************************************************************/
Cobject::Cobject()
{
frame =0;
num_frames = 1;
}
/******************************************************************************
******************************************************************************/
Cobject::Cobject(OamState *_oam,u8 *_gfx, u32 _width, u32 _height, SpriteSize _size, u32 _numframes, E_gfx_location _gfx_location)
{
oam = _oam;
anim_counter = 0;
anim_delay = 3;
frame = 0;
num_frames = _numframes;
if (num_frames <= 0) num_frames = 1;
gfx_location = _gfx_location;
tile_offset = _width * _height;
if (gfx_location == E_GFX_VRAM)
{
sprites = new Csprite[num_frames];
assert(sprites);
for (int i = 0; i < num_frames; i++)
{
// if not last frame do not increment oam_id
// else increment so that we change objects automatically
if (i < (num_frames-1))
sprites[i].create (oam,_width, _height, _size, SpriteColorFormat_256Color,false);
else
sprites[i].create (oam,_width, _height, _size, SpriteColorFormat_256Color,true);
dmaCopy(_gfx, sprites[i].gfx, tile_offset);
_gfx += tile_offset;
}
}
else // ram
{
// only allocate 1 instance since we are going to
// dma copy every frame
sprites = new Csprite[1];
assert(sprites);
sprites[0].create (oam,_width, _height, _size, SpriteColorFormat_256Color,true);
dmaCopy(_gfx, sprites[0].gfx, tile_offset);
gfx_start_offset = _gfx;
}
}
/******************************************************************************
******************************************************************************/
Cobject::~Cobject()
{
if (sprites)
{
delete[] sprites;
}
}
/******************************************************************************
******************************************************************************/
void Cobject::init(OamState *_oam,u8 *_gfx, u32 _width, u32 _height, SpriteSize _size, u32 _numframes, E_gfx_location _gfx_location)
{
oam = _oam;
anim_counter = 0;
anim_delay = 3;
frame = 0;
num_frames = _numframes;
if (num_frames <= 0) num_frames = 1;
gfx_location = _gfx_location;
tile_offset = _width * _height;
if (gfx_location == E_GFX_VRAM)
{
sprites = new Csprite[num_frames];
assert(sprites);
for (int i = 0; i < num_frames; i++)
{
// if not last frame do not increment oam_id
// else increment so that we change objects automatically
if (i < (num_frames-1))
sprites[i].create (oam,_width, _height, _size, SpriteColorFormat_256Color,false);
else
sprites[i].create (oam,_width, _height, _size, SpriteColorFormat_256Color,true);
dmaCopy(_gfx, sprites[i].gfx, tile_offset);
_gfx += tile_offset;
}
}
else // ram
{
// only allocate 1 instance since we are going to
// dma copy every frame
sprites = new Csprite[1];
assert(sprites);
sprites[0].create (oam,_width, _height, _size, SpriteColorFormat_256Color,true);
dmaCopy(_gfx, sprites[0].gfx, tile_offset);
gfx_start_offset = _gfx;
}
}
/******************************************************************************
******************************************************************************/
void Cobject::update_oam()
{
// if vram type directly animate
if (gfx_location==E_GFX_VRAM)
{
sprites[frame].update_oam();
}
else // dma copy every fram for ram type
{
u8 *offset = gfx_start_offset + (tile_offset* frame);
dmaCopy(offset, sprites[0].gfx, tile_offset);
sprites[0].update_oam();
}
}
Thanks!!!
-
Failing asserts are usually programming errors.
Why do you want to enable/disable those on a per-module basis?
I usually specify "NDEBUG" globally for the release build.
If the macro NDEBUG was defined at the moment <assert.h> was last
included, the macro assert() generates no code, and hence does
nothing at all. Otherwise, the macro assert() prints an error
message to standard output and terminates the program by calling
abort() if expression is false (i.e., compares equal to zero).
-
Often your compiler will decide if NDEBUG is defined if you've told it to build in debug mode.
Jim
-
Thanks for the tips guys.
Actually, I wanted to make NDEBUG global so that everymodule would turnoff/on assertion whenever I want.
BTW, how do you tell the compiler to build in debug mode? I'm using an NDS port of GCC and Notepad++ to code. I compile via make.
-
With gcc debug build is usually controlled with -g option, but I think gcc won't do anything with NDEBUG automatically, you have to specify -DNDEBUG manually.
Jim
-
Thanks!!!!
But would doing this:
#define NDEBUG
// includes here....
On my main module would essentially turnoff debugging right?
-
You can't just define NDEBUG in one module and expect all other modules to see it.
You really want to be doing -DNEBUG in the compiler options to ensure all c/cpp files have the same defines.
Jim
-
Thanks dude!!!