#153232 - TheMagnitude - Wed Mar 26, 2008 8:18 pm
This is part of a tutorial on patater, but i changed the function initsprites() to my own function to initialize a single sprite, to save me copying and pasting lots of code when i progress with more sprites.
It works fine on DeSmuMe, the orange shuttle moves horizontally across the screen and the moon moves vertically.
But when i pop it onto my real ds the sprites turn out black, but still transparrent, and they move, except the moon sprite appears to have an posX of 0, when i set it to 150.
Its the addObject() function that seems to be the problem, since that is the only thing I have changed from the original source in the tutorial.
Last edited by TheMagnitude on Thu Mar 27, 2008 8:46 pm; edited 1 time in total
It works fine on DeSmuMe, the orange shuttle moves horizontally across the screen and the moon moves vertically.
But when i pop it onto my real ds the sprites turn out black, but still transparrent, and they move, except the moon sprite appears to have an posX of 0, when i set it to 150.
Its the addObject() function that seems to be the problem, since that is the only thing I have changed from the original source in the tutorial.
Code: |
/*
* main.cpp * * Created by Jaeden Amero on 11/12/07. * Copyright 2007. All rights reserved. * */ #include <nds.h> #include <assert.h> #include "sprites.h" /* Backgrounds */ #include "starField.h" #include "planet.h" #include "splash.h" /* Sprites */ #include "orangeShuttle.h" #include "moon.h" // SPRITE GLOBALS SpriteInfo spriteInfo[SPRITE_COUNT]; tOAM *oam; static const int BYTES_PER_16_COLOR_TILE = 32; static const int COLORS_PER_PALETTE = 16; static const int BOUNDARY_VALUE = 32; static const int OFFSET_MULTIPLIER = BOUNDARY_VALUE / sizeof(SPRITE_GFX[0]); int nextAvailableTileIdx = 0; static int oamIdIterator = 0; /* Select a low priority DMA channel to perform our background copying. */ static const int DMA_CHANNEL = 3; void initVideo() { /* * Map VRAM to display a background on the main and sub screens. * * The vramSetMainBanks function takes four arguments, one for each of the * major VRAM banks. We can use it as shorthand for assigning values to * each of the VRAM bank's control registers. * * We map banks A and B to main screen background memory. This gives us * 256KB, which is a healthy amount for 16-bit graphics. * * We map bank C to sub screen background memory. * * We map bank D to LCD. This setting is generally used for when we aren't * using a particular bank. * * We map bank E to main screen sprite memory (aka object memory). */ vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_MAIN_BG_0x06020000, VRAM_C_SUB_BG_0x06200000, VRAM_D_LCD); vramSetBankE(VRAM_E_MAIN_SPRITE); /* Set the video mode on the main screen. */ videoSetMode(MODE_5_2D | // Set the graphics mode to Mode 5 DISPLAY_BG2_ACTIVE | // Enable BG2 for display DISPLAY_BG3_ACTIVE | // Enable BG3 for display DISPLAY_SPR_ACTIVE | // Enable sprites for display DISPLAY_SPR_1D // Enable 1D tiled sprites ); /* Set the video mode on the sub screen. */ videoSetModeSub(MODE_5_2D | // Set the graphics mode to Mode 5 DISPLAY_BG3_ACTIVE); // Enable BG3 for display } void initBackgrounds() { /* Set up affine background 3 on main as a 16-bit color background */ BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(0) | // The starting place in memory BG_PRIORITY(3); // A low priority /* Set the affine transformation matrix for the main screen background 3 * to be the identity matrix. */ BG3_XDX = 1 << 8; BG3_XDY = 0; BG3_YDX = 0; BG3_YDY = 1 << 8; /* Place main screen background 3 at the origin (upper left of the screen) */ BG3_CX = 0; BG3_CY = 0; /* Set up affine background 2 on main as a 16-bit color background */ BG2_CR = BG_BMP16_128x128 | BG_BMP_BASE(8) | // The starting place in memory BG_PRIORITY(2); // A higher priority /* Set the affine transformation matrix for the main screen background 3 * to be the identity matrix. */ BG2_XDX = 1 << 8; BG2_XDY = 0; BG2_YDX = 0; BG2_YDY = 1 << 8; /* Place main screen background 2 an interesting place. */ BG2_CX = -(SCREEN_WIDTH / 2 - 32) << 8; BG2_CY = -32 << 8; /* Set up affine background 3 on the sub screen as a 16-bit color * background */ SUB_BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(0) | // The starting place in memory BG_PRIORITY(3); // A low priority /* Set the affine transformation matrix for the sub screen background 3 * to be the identity matrix. */ SUB_BG3_XDX = 1 << 8; SUB_BG3_XDY = 0; SUB_BG3_YDX = 0; SUB_BG3_YDY = 1 << 8; /* * Place main screen background 3 at the origin (upper left of the screen) */ SUB_BG3_CX = 0; SUB_BG3_CY = 0; } SpriteEntry * addObject( const unsigned short pal[], const unsigned int tiles[], uint32 palLen, uint32 tilesLen, u16 xpos, u16 ypos, int width, int height, int angle, bool affine, tObjColMode colmode, tObjMode objmode = OBJMODE_NORMAL, tObjPriority objpriority = OBJPRIORITY_0, bool hflip = false, bool vflip = false) { assert(oamIdIterator < SPRITE_COUNT); SpriteInfo * info = &spriteInfo[oamIdIterator]; SpriteEntry * obj = &oam->spriteBuffer[oamIdIterator]; assert((height==64 || height==32 || height==16 || height==8) && (width==64 || width==32 || width==16 || width==8)); // INFO info->oamId = oamIdIterator; info->width = width; info->height = height; info->angle = angle; info->entry = obj; // ATTRIBUTE 0 obj->posY = ypos; obj->isHidden = false; obj->isRotoscale = affine; assert(!obj->isRotoscale || (info->oamId < MATRIX_COUNT)); obj->rsDouble = false; obj->objMode = objmode; obj->isMosaic = false; obj->colMode = colmode; if (height == width) obj->objShape = OBJSHAPE_SQUARE; else if (height>width) obj->objShape = OBJSHAPE_TALL; else if (height<width) obj->objShape = OBJSHAPE_WIDE; else obj->objShape = OBJSHAPE_FORBIDDEN; // ATTRIBUTE 1 obj->posX = xpos; if (affine == true) obj->rsMatrixIdx = info->oamId; else { obj->hFlip = hflip; obj->vFlip = vflip; } switch (height >= width ? height : width) { case 8: obj->objSize = OBJSIZE_8; break; case 16: obj->objSize = OBJSIZE_16; break; case 32: obj->objSize = OBJSIZE_32; break; case 64: obj->objSize = OBJSIZE_64; break; } // ATTRIBUTE 2 obj->tileIdx = nextAvailableTileIdx; nextAvailableTileIdx += tilesLen / BYTES_PER_16_COLOR_TILE; obj->objPriority = objpriority; obj->objPal = info->oamId; // ROTATE if (affine==true) rotateSprite(&oam->matrixBuffer[info->oamId],info->angle); // COPY SPRITE PALLETTES dmaCopyHalfWords(SPRITE_DMA_CHANNEL, pal, &SPRITE_PALETTE[info->oamId * COLORS_PER_PALETTE], palLen); // COPY SPRITE GRAPHICS dmaCopyHalfWords(SPRITE_DMA_CHANNEL, tiles, &SPRITE_GFX[obj->tileIdx * OFFSET_MULTIPLIER], tilesLen); ++oamIdIterator; return obj; } void displayStarField() { dmaCopyHalfWords(DMA_CHANNEL, starFieldBitmap, /* This variable is generated for us by * grit. */ (uint16 *)BG_BMP_RAM(0), /* Our address for main * background 3 */ starFieldBitmapLen); } void displayPlanet() { dmaCopyHalfWords(DMA_CHANNEL, planetBitmap, /* This variable is generated for us by * grit. */ (uint16 *)BG_BMP_RAM(8), /* Our address for main * background 2 */ planetBitmapLen); } void displaySplash() { dmaCopyHalfWords(DMA_CHANNEL, splashBitmap, /* This variable is generated for us by * grit. */ (uint16 *)BG_BMP_RAM_SUB(0), /* Our address for sub background 3 */ splashBitmapLen); } int main() { /* Turn on the 2D graphics core. */ powerON(POWER_ALL_2D); /* * Set up interrupts. * * We don't really get into what these do exactly at this point in the * manual, but we still need to do them for now. */ irqInit(); irqSet(IRQ_VBLANK, 0); /* * Configure the VRAM and background control registers. * * Place the main screen on the bottom physical screen. Then arrange the * VRAM banks. Next, confiure the background control registers. */ lcdMainOnBottom(); initVideo(); initBackgrounds(); /* Set up a few sprites. */ oam = new tOAM(); initOAM(oam); //initSprites(oam,spriteInfo); addObject( orangeShuttlePal, orangeShuttleTiles, (uint32)orangeShuttlePalLen, (uint32)orangeShuttleTilesLen, (u16)100, (u16)100, 64, 64, 462, true, OBJCOLOR_16, OBJMODE_NORMAL, OBJPRIORITY_0, false, false); addObject( moonPal, moonTiles, (uint32)moonPalLen, (uint32)moonTilesLen, (u16)150, (u16)50, 32, 32, 0, false, OBJCOLOR_16, OBJMODE_NORMAL, OBJPRIORITY_2, false, false); /* Display the backgrounds. */ displayStarField(); displayPlanet(); displaySplash(); /* * Update the OAM. * * We have to copy our copy of OAM data into the actual * OAM during VBlank (writes to it are locked during * other times). */ swiWaitForVBlank(); updateOAM(oam); return 0; } |
Last edited by TheMagnitude on Thu Mar 27, 2008 8:46 pm; edited 1 time in total