PDA

Voir la version complète : [NDS][Aide] ndslib et sprite


JieF
16/09/2007, 11h43
Bonjour, premier post donc de l'indulgence s'il vous plait :)

Voilà, je commence tout juste en dev NDS, d'ailleurs j'ai même pas de NDS, bref. Gêné par les problèmes de fragmentation de mémoires pour les sprites avec la palib, je me suis dis que je pourrai regarder du coté de la ndslib.
J'ai donc créé une fonction createsprite à l'instar de la palib en pensant ecraser la même zone mémoire à chaque fois. Si SPRITE_GFX_SUB pointe en mémoire et que j'incrémente pour y copier mes données alors c'est toujours la même zone que j'utilise non ? mais apparemment c'est pas aussi simple.
Donc cette fonction je l'utilise dans une démo de bourrin qui recrée une trentaine de sprites à chaque touch du stylet dans un zone de l'écran.

Résultat : No$gba plante au bout d'une grosse cinquantaine de clicks mais me dit dans utility-->errors -->

Errors per second -- 0
Total Errors -- 0
Low Power Mode -- Okay
Multiboot Support -- Unsupported (bad entrypoint)
Quality Rating -- Good (better than most GBA games)

et quant à DeSmuME : il fait tourner mon test sans planter du tout.

Dans la pratique, après avoir refilé le .nds à un pote qui a tout ce qu'il faut, il y a des p'tits bugs d'affichages sur les sprites et ça plante au bout de 2 ou 3 clicks. Le binaire se trouve ici : http://asso-claj.ovh.org/Sprite.nds et la source ici : http://asso-claj.ovh.org/Sprite.cpp.
vu la taille de la source, je la recopie ici :

#include <stdlib.h>
#include <nds.h>
#include <stdio.h>
#include <nds/arm9/image.h>

//include our ball pcx file (auto generated)
#include "ball_pcx.h"
#include "ball_old_pcx.h"
#include "f1_pcx.h"
#include "f2_pcx.h"

#define NUM_SPRITES 128
const u8 *tab_file[] = {ball_pcx,ball_old_pcx,f1_pcx,f2_pcx,};

SpriteEntry OAMCopySub[128];

touchPosition Stylus;

// Function: Detect button
int stylusInBox(int x,int y,int w,int h){
if(keysHeld() && KEY_TOUCH && Stylus.px>=x && Stylus.py>=y && Stylus.px<=(x+w) && Stylus.py<=(y+h)){
return 1;
}else{
return 0;
}
}

//simple sprite struct
typedef struct {
int x,y; //location
int dx, dy; //speed
SpriteEntry* oam;
int gfxID; //graphics location
int ID; //graphics ID
}Sprite;

//init sprites
Sprite sprites[NUM_SPRITES];
//---------------------------------------------------------------------------------
void initOAM(void) {
//---------------------------------------------------------------------------------
int i;

for(i = 0; i < 128; i++) {
OAMCopySub[i].attribute[0] = ATTR0_DISABLED;
}
}
//---------------------------------------------------------------------------------
void updateOAM(void) {
//---------------------------------------------------------------------------------
unsigned int i;

for(i = 0; i < 128 * sizeof(SpriteEntry) / 4 ; i++)
{
((uint32*)OAM_SUB)[i] = ((uint32*)OAMCopySub)[i];
}
}

//---------------------------------------------------------------------------------
void CreateSprite(u8 *file_pcx,int i,int x,int y){
//---------------------------------------------------------------------------------
sImage file;
//load our ball pcx file into an image
loadPCX((u8*)file_pcx, &file);
//tile it so it is usefull as sprite data
imageTileData(&file);

// Palette initialisation
for(int i = 0; i < 256; i++){
SPRITE_PALETTE_SUB[i*256] = file.palette[i];
}

// Sprite initialisation
for(int j = 0; j< 32*16; j++){
SPRITE_GFX_SUB[j+(i*1024)] = file.image.data16[j];
}

sprites[i].gfxID = i*64;
sprites[i].oam = &OAMCopySub[i];
sprites[i].ID = i;


//set up our sprites OAM entry attributes
sprites[i].oam->attribute[0] = ATTR0_COLOR_256 | ATTR0_SQUARE;
sprites[i].oam->attribute[1] = ATTR1_SIZE_32;
sprites[i].oam->attribute[2] = sprites[i].gfxID;
sprites[i].oam->attribute[1] |= (x & 0x01FF);
sprites[i].oam->attribute[0] |= (y & 0x00FF);

}

//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------

//turn on the power to the system
powerON(POWER_ALL);
//One palette for_all
paletteForAll((u8*)tab_file[0]);

//initOAM();
//set main display to render directly from the frame buffer
videoSetMode(0);

//set up the sub display
videoSetModeSub(MODE_0_2D |
DISPLAY_SPR_1D_LAYOUT |
DISPLAY_SPR_ACTIVE |
DISPLAY_BG0_ACTIVE |
DISPLAY_BG1_ACTIVE );

//vram banks are somewhat complex
vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_SUB_BG, VRAM_D_SUB_SPRITE);

// a vblank interrupt is needed to use swiWaitForVBlank()
// since the dispatcher handles the flags no handler is required
irqInit();
irqSet(IRQ_VBLANK, 0);


while (1){
scanKeys();
Stylus=touchReadXY();

if(stylusInBox(0,0,255/2,190)){

CreateSprite((u8*)tab_file[0],0,0,0);
CreateSprite((u8*)tab_file[1],1,32,0);
CreateSprite((u8*)tab_file[2],2,64,0);
CreateSprite((u8*)tab_file[3],3,96,0);
CreateSprite((u8*)tab_file[0],4,128,0);
CreateSprite((u8*)tab_file[1],5,160,0);
CreateSprite((u8*)tab_file[2],6,192,0);
CreateSprite((u8*)tab_file[3],7,224,0);
CreateSprite((u8*)tab_file[0],8,0,32);
CreateSprite((u8*)tab_file[1],9,32,32);
CreateSprite((u8*)tab_file[2],10,64,32);
CreateSprite((u8*)tab_file[3],11,96,32);
CreateSprite((u8*)tab_file[0],12,128,32);
CreateSprite((u8*)tab_file[1],13,160,32);
CreateSprite((u8*)tab_file[2],14,192,32);
CreateSprite((u8*)tab_file[3],15,224,32);
CreateSprite((u8*)tab_file[0],16,0,64);
CreateSprite((u8*)tab_file[1],17,32,64);
CreateSprite((u8*)tab_file[2],18,64,64);
CreateSprite((u8*)tab_file[3],19,96,64);
CreateSprite((u8*)tab_file[0],20,128,64);
CreateSprite((u8*)tab_file[1],21,160,64);
CreateSprite((u8*)tab_file[2],22,192,64);
CreateSprite((u8*)tab_file[3],23,224,64);
CreateSprite((u8*)tab_file[0],24,0,96);
CreateSprite((u8*)tab_file[1],25,32,96);
CreateSprite((u8*)tab_file[2],26,64,96);
CreateSprite((u8*)tab_file[3],27,96,96);
CreateSprite((u8*)tab_file[0],28,128,96);
CreateSprite((u8*)tab_file[1],29,160,96);
CreateSprite((u8*)tab_file[2],30,192,96);
CreateSprite((u8*)tab_file[3],31,224,96);
}
if(stylusInBox(255/2,0,255/2,190)){

CreateSprite((u8*)tab_file[1],0,0,0);
CreateSprite((u8*)tab_file[2],1,32,0);
CreateSprite((u8*)tab_file[3],2,64,0);
CreateSprite((u8*)tab_file[0],3,96,0);
CreateSprite((u8*)tab_file[1],4,128,0);
CreateSprite((u8*)tab_file[2],5,160,0);
CreateSprite((u8*)tab_file[3],6,192,0);
CreateSprite((u8*)tab_file[0],7,224,0);
CreateSprite((u8*)tab_file[1],8,0,32);
CreateSprite((u8*)tab_file[2],9,32,32);
CreateSprite((u8*)tab_file[3],10,64,32);
CreateSprite((u8*)tab_file[0],11,96,32);
CreateSprite((u8*)tab_file[1],12,128,32);
CreateSprite((u8*)tab_file[2],13,160,32);
CreateSprite((u8*)tab_file[3],14,192,32);
CreateSprite((u8*)tab_file[0],15,224,32);
CreateSprite((u8*)tab_file[1],16,0,64);
CreateSprite((u8*)tab_file[2],17,32,64);
CreateSprite((u8*)tab_file[3],18,64,64);
CreateSprite((u8*)tab_file[0],19,96,64);
CreateSprite((u8*)tab_file[1],20,128,64);
CreateSprite((u8*)tab_file[2],21,160,64);
CreateSprite((u8*)tab_file[3],22,192,64);
CreateSprite((u8*)tab_file[0],23,224,64);
CreateSprite((u8*)tab_file[1],24,0,96);
CreateSprite((u8*)tab_file[2],25,32,96);
CreateSprite((u8*)tab_file[3],26,64,96);
CreateSprite((u8*)tab_file[0],27,96,96);
CreateSprite((u8*)tab_file[1],28,128,96);
CreateSprite((u8*)tab_file[2],29,160,96);
CreateSprite((u8*)tab_file[3],30,192,96);
CreateSprite((u8*)tab_file[0],31,224,96);

}
swiWaitForVBlank();
updateOAM();
}
}
Quelqu'un qui s'y connait pourrait-il m'apporter de l'aide, me filer une piste ???
- J'ai tenté de charger la palette à part pour tous les sprites genre dans une fonction palette4all(), mais ça ne marche pas (un léger mieux peut-être, mais c une seule palette*NUM_SPRITES pour tous les sprites)
- j'ai essayé d'utiliser un autre registre que SUB mais ça ne m'affiche plus les sprites.

JieF
18/09/2007, 21h35
Please help me :cry: :snif2:

Arialia
18/09/2007, 23h36
Vraiment désolée de ne pas t'avoir aidé avant mais franchement je pensais que des codeurs plus balèzes que moi auraient pu t'aider .....:whst:

c'est pas la grande forme ce soir mais je vais essayer ....

alors déjà l'avantage des sprites c'est qu'ils peuvent bouger .... donc pour moi tu devrais faire deux fonctions :
- une qui crée le sprite : ça presque ok
- la deuxième qui déplace ton sprite
- sinon il est possible d'utiliser le même graphique pour plusieurs sprites ... cela éviterai le chargement de fichiers à chaque clic ...


bon sinon pour les attributs OAM je suis plus très sure j'avoue avoir aussi galéré
faudrait que je revoie mes codes pour pouvoir t'aider ....

JieF
19/09/2007, 15h47
Merci pour ta réponse,
Ce que j'ai supprimé sur la source mais qu'on peut voir en la téléchargeant c'est la fonction MoveSprite donc qui existe bien dans la source d'origine.
Là mon but était d'en foutre dans la tronche un max pour voir s'il supportait, mais apparemment non,
Je vais jeter un oeil du côté de la µlib pour voir