PDA

Voir la version complète : [GBA][Aide] Mode 3 et Sprites


DJP
26/01/2006, 22h18
Voila, je suis n'arrive pas a integrer des sprites dans le mode 3, voici le code que j'utilise actuellement (et qui ne fonctionne donc pas) :


#include <gba_console.h>
#include <gba_video.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <gba_sprites.h>
#include <stdio.h>

#define OAMMem ((u32*)0x7000000)
#define VideoBuffer ((u16*)0x6000000)
#define FrontBuffer ((u16*)0x6000000)
#define BackBuffer ((u16*)0x600A000)
#define OBJ_GFXMem ((u16*)0x6010000)
#define BGPaletteMem ((u16*)0x5000000)
#define OBJPaletteMem ((u16*)0x5000200)
#define EWRAM_8 ((u16*)0x2000000)

#define RGB16(r,g,b) ((r)|((g)<<5)|((b)<<10))
#define RGB(r,g,b) ((((b)>>3)<<10)+(((g)>>3)<<5)+((r)>>3))

#define PI 3.14159
#define RADIAN(n) (((float)n)/(float)180*PI)

#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 160

#include "../data/bg1.b16.c"
#include "../data/blocs.b16.c"
#include "../data/graphs.c"
#include "../data/Image.pal.c"
#include "../data/Image.til.c"

#define IRIS_IN_EWRAM __attribute__ ((section(".ewram")))
#define IRIS_DATA_IN_IWRAM __attribute__ ((section(".iwram")))
#define IRIS_IN_IWRAM __attribute__ ((section(".iwram"),long_call))
#define IRIS_IN_ROM __attribute__ ((section (".rodata")))

#define IRIS_ROTATION_FLAG 0x100
#define IRIS_TAILLE_NORMAL 0
#define IRIS_TAILLE_DOUBLE 0x200
#define IRIS_MODE_NORMAL 0x0
#define IRIS_MODE_ALPHABLEND 0x400
#define IRIS_MODE_WINDOWED 0x800
#define IRIS_MOSAIC 0x1000
#define IRIS_COLOR_16 0x0000
#define IRIS_COLOR_256 0x2000
#define IRIS_SQUARE 0x0
#define IRIS_WIDE 0x4000
#define IRIS_TALL 0x8000
// Attribut 1
#define IRIS_ROTDATA(n) (n << 9)
#define IRIS_HORIZONTAL_FLIP 0x1000
#define IRIS_VERTICAL_FLIP 0x2000
#define IRIS_SIZE_8 0x0
#define IRIS_SIZE_16 0x4000
#define IRIS_SIZE_32 0x8000
#define IRIS_SIZE_64 0xC000
// Attribut 2
#define IRIS_PRIORITY_0 0
#define IRIS_PRIORITY_1 1
#define IRIS_PRIORITY_2 2
#define IRIS_PRIORITY_3 3
#define IRIS_PRIORITY(n) ((n) << 10)
#define IRIS_PALETTE(n) ((n) << 12)

#define IRIS_OBJ_ENABLED 0x1000
#define IRIS_OBJ_1D 0x40
#define IRIS_OBJ_2D 0x00

//Arguments pour les tailles. Il y en a deux, un pour la forme (0=carré, 1=aplati, 2=vertical)
#define IRIS_TAILLE_8x8 0,0
#define IRIS_TAILLE_16x16 0,1
#define IRIS_TAILLE_32x32 0,2
#define IRIS_TAILLE_64x64 0,3
#define IRIS_TAILLE_16x8 1,0
#define IRIS_TAILLE_32x8 1,1
#define IRIS_TAILLE_32x16 1,2
#define IRIS_TAILLE_64x32 1,3
#define IRIS_TAILLE_8x16 2,0
#define IRIS_TAILLE_8x32 2,1
#define IRIS_TAILLE_16x32 2,2
#define IRIS_TAILLE_32x64 2,3


// la palette du sprite
unsigned short *IRIS_SpritesPalette = (unsigned short int *) 0x5000200 ;

// Emplacement des sprites dans le registre
unsigned short *IRIS_OAM = (unsigned short*)0x7000000 ;
unsigned short *IRIS_OAMData = (unsigned short*)0x6010000 ;

// Structure pour les attributs des sprites gba
typedef struct S_Attributs
{
unsigned short Attribut0 ;
unsigned short Attribut1 ;
unsigned short Attribut2 ;
unsigned short Attribut3 ;
} T_Attributs, *P_Attributs ;

// Tableau des 4 attributs des sprites à copier dans l'OAM
// je les mets volontairement en ewram
T_Attributs IRIS_IN_EWRAM IRIS_OAMBuffer[128] ;

// Structure tres simpliste d'un sprite
typedef struct S_Sprite
{
unsigned char Num ; // numero utilisé par le sprite
unsigned short *Nom ; // nom du tableau de tiles
unsigned int CoorX ; // coordonnés X du sprite a l'ecran
unsigned int CoorY ; // coordonnés Y du sprite a l'ecran
T_Attributs Attributs ; // les attributs hard du sprite
} T_Sprite , *P_Sprite ;

// Creation de 128 sprites avec la structure ci-dessus
T_Sprite IRIS_IN_EWRAM IRIS_Sprites[128] ;



void WaitVBlank(void)
{
while (*(volatile unsigned short*)0x4000006<160) {};
}

void CopieDo16(short *src,short *dst,unsigned short taille){
do { *(dst++) = *(src++) ;} while (--taille) ;}
void CopieDo32(int *src,int *dst,unsigned int taille){
do { *(dst++) = *(src++) ;} while (--taille) ;}

/*!################################################ #################################################
\fn : InsertSpriteTiles256
\brief : copie un certain nombre de tile dans l'emplacement reserve aux sprites.
################################################## ################################################*/
void InsertSpriteTiles256(void *Tiles, unsigned short NbTiles, unsigned short Offset)
{
CopieDo16((void*)Tiles, IRIS_OAMData + (Offset<<4), NbTiles<<5) ;
}

void CreeSprite(unsigned char num,unsigned short *nom, unsigned int forme, unsigned int taille,
unsigned int x, unsigned int y)
{

// on met a jour la structure
IRIS_Sprites[num].Num = num ;
IRIS_Sprites[num].Nom = nom ;
IRIS_Sprites[num].CoorX = x ;
IRIS_Sprites[num].CoorY = y ;

IRIS_Sprites[num].Attributs.Attribut0 = (forme <<14) | IRIS_COLOR_256 | y ;
IRIS_Sprites[num].Attributs.Attribut1 = (taille<<14) | x ;
IRIS_Sprites[num].Attributs.Attribut2 = 0 ;
IRIS_Sprites[num].Attributs.Attribut3 = 0 ;

}

int frame = 0;

void Vblank() {

frame++;
}

int sudoku[9][9]={
{8,1,0,0,0,0,7,0,3},
{0,0,0,6,0,7,0,0,8},
{9,0,2,3,1,0,6,0,0},
{0,4,0,0,7,0,5,6,0},
{0,0,7,9,0,1,2,0,0},
{0,6,3,0,4,0,0,9,0},
{0,0,4,0,9,2,1,0,6},
{6,0,0,5,0,4,0,0,0},
{7,0,8,0,0,0,0,5,9}
};
//---------------------------------------------------------------------------------
// Program entry point
//---------------------------------------------------------------------------------

int main(){

unsigned char x,y;
int i;
unsigned short loop ;

//on active que les sprites et on gere leur tiles en mode 1D (comme les tiles des bg quoi)
SetMode (MODE_3 | BG2_ENABLE | IRIS_OBJ_ENABLED | IRIS_OBJ_1D) ;
CreeSprite(0,(void*)Image_tiles,IRIS_TAILLE_64x64, 10, 10);

// copie de la palette du sprite
CopieDo16((void*)Image_palette, IRIS_SpritesPalette, 256) ;

for(i = 0; i < 38400; i++) VideoBuffer[i] = bg1_bitmap16[i];

/*
for(x = 80; x < 97; x++){
for(y = 1; y < 18; y++){
VideoBuffer[((y<<8)-(y<<4))+x] = bg1_bitmap16[((y<<8)-(y<<4))+x];
}
}
*/

clavier();

while(1){
InsertSpriteTiles256(IRIS_Sprites[0].Nom, 8*8, 0) ;

// copiage des 4 attibuts des 128 sprites (en 32 bit donc seulement 256 donnés au lieu de 512)
for (loop=0 ; loop< 128 ; loop++) IRIS_OAMBuffer[loop] = IRIS_Sprites[loop].Attributs ;
CopieDo32((void*)IRIS_OAMBuffer,(void*)IRIS_OAM,25 6) ;
}
}



Please, Help

Brunni
26/01/2006, 22h27
J'ai pas passé à fond ton code mais il semble que tu crées les sprites à partir de la tile 0 ("CharBaseBlock(4)"), or en mode 3 ça ne marche qu'à partir de la tile 512 ("CharBaseBlock(5)") parce que les réserves mémoire sont différentes:
Mode 0-2:
BGs: 64 ko (CBB 0-3)
Sprites: 32 ko (CBB 4-5)
Mode 3-5:
Bitmaps: 80 ko
Sprites: 16 ko (CBB 5)

Nesgba
26/01/2006, 22h57
oui en mode 3-4 ca debute a 512 donc tu initialise ton sprite au tile 512 et tu copie ses tiles a partir du 512.
je t'ai fillé une fonction de creation de sprite vide tu devrai la completer un peu sinon tu irra pas loin :(

dans la fonction de creation de sprite met (tu peut le passer en argument avec ta fonction de creation aussi):
IRIS_Sprites[num].Attributs.Attribut2 = 512 ;

ensuite pour copier tes tiles:
InsertSpriteTiles256(IRIS_Sprites[0].Nom, 8*8, 512) ;

ps: ca fait vraiment plaisir que tu mette au hard !! :)
n'hesite pas a poser toutes les question que tu veut ^^

DJP
26/01/2006, 23h09
ouai là j'ai fait du gros copier coller pour avoir un truc qui marche "normalement" mais j'ai déjà des fonctions un peu plus clean (pour ce que j'en fait) et des fonctions de déplacement par exemple...

En tout cas merci, j'avai pensé a essayer de le mettre en 512, mais j'avais oublié l'attribut2 :D