:: PlayerAdvance.org ::  

Précédent   :: PlayerAdvance.org :: > :: Développement Amateur :: > Nintendo DS > Divers

Divers Tout ce qui ne correspond pas aux autres sous-forums mais qui concerne le développement amateur sur Nintendo DS

Publicité

Réponse
 
Outils de la discussion Modes d'affichage
Vieux 05/08/2013, 16h47   #1
Tannis Dragon
Membre
 
Date d'inscription: 04/07/2006
Messages: 25
Par défaut Afficher un Sprite avec Libnds

Bonjour,

Je vais déjà répondre sur une interrogation possible dont vous pourriez me faire part

Pourquoi ne pas utiliser PA_LIB ?
En effet mon sprite s'affiche nickel et facilement avec cette librairie.
Mais... oui car il y a un "mais", elle me bloque sur mon affichage d'image à l'écran :
Sur la BG3 du sub et main ,ma Map est un fond blanc constitué d'image de 14/14 tiles que je dispose suivant certaine condition (appuie bouton). Sur Pa_Lib je n'arrive pas a reproduire ce que je fais sur la libnds.

Petit détail sur mon application :
J'utilise BG3 pour mes images sur fond blanc, BG1 pour un fond avec une image 256x256 réservé au menu (que j'éteindrais ensuite pour laisser BG3 visible). BG0 pour le texte. Actuellement c'est opérationnelle sauf quelques trucs bizarres que je n'arrive pas à expliquer (mais c'est hors sujet ici)
Pour information voici les VRam que j'utilise dans mon programme d'origine :
Code:
	// Bank A (128 Ko) pour Map et Tiles, Bank E (64 Ko) pour Sprite => Ecran Main (bas)
	vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
	vramSetBankE(VRAM_E_MAIN_SPRITE);
	// Bank C (128 Ko) pour Map et Tiles, Bank I (16 Ko) pour Sprite => Ecran Sub (haut)
	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
	vramSetBankI(VRAM_I_SUB_SPRITE);
Dans le répertoire source j'ai le All_Gfx.h, mon sprite et sa palette et le main.c. (si je met le all_Gfx.C je n'arrive plus à compiler du à des doublons et autres)

Pour revenir à mon sprite, sur mon jeux je devrais en afficher au maximum 10 sur l'écran Main et 1 sur l'écran sub.

Donc ne soyez pas surpris pour les bank I et E comme emplacement mémoire pour les Tiles car j'ai peu de tiles à y mettre.

Dans le code ci dessous je cherche à afficher 1 seul sprite de 32x32 qui serait déjà bien

Code:
// Includes
#include <PA9.h>       // Include for PA_Lib
#include <nds.h>
#include "All_gfx.h"

typedef struct {
   u16 atr0, atr1, atr2, atr3;
}Atr_Sprite;

Atr_Sprite Oam[2][128];

// Function: main()
int main(int argc, char ** argv)
{
    // pointeur 8bit
    u8* Memory_8b;

    // Variable de Boucle
    int i,j;

    // Valide les interruptions
	irqInit();
	// Rafraichissement de l ecran
	irqEnable(IRQ_VBLANK);

	// Inverse l'ecran haut et bas cela les places de la bonne facon
	REG_POWERCNT= 0x1;

	// Allumage des 2 ecrans
	powerON(POWER_ALL_2D); //	powerON(POWER_ALL);

    // Activation des sprites Mode 0 pour les deux ecrans
    videoSetMode(  MODE_0_2D |              // Mode 0 mosaique
                   DISPLAY_SPR_ACTIVE |     // Active les sprites
                   DISPLAY_SPR_1D |         // Mode Tiles
				   DISPLAY_SPR_1D_SIZE_128
                    );

	videoSetModeSub(  MODE_0_2D |            // Mode 0 mosaique
                   DISPLAY_SPR_ACTIVE |     // Active les sprites
                   DISPLAY_SPR_1D |         // Mode Tiles
				   DISPLAY_SPR_1D_SIZE_128
                    );
    // Allocation de la RAM ecran du Bas
    vramSetBankE(VRAM_E_MAIN_SPRITE);

    // Allocation de la RAM ecran du Haut
    vramSetBankI(VRAM_I_SUB_SPRITE);

    // Couleur blanche sur les palettes ecrans (donne fond blanc sur tout les ecrans)
    PALETTE[0] = 65535;
    PALETTE_SUB[0] = 65535;

    // Mise a zero des attribut des sprites
	for (i=0; i<2 ; i++)
	{
		for (j=0; j<128 ; j++)
		{
			Oam[i][j].atr0 = 255;
			Oam[i][j].atr1 = 511;
		}
	}

	// chargement palette du sprite
    dmaCopy(Pointeur_Pal, SPRITE_PALETTE, 136);
    dmaCopy(Pointeur_Pal, SPRITE_PALETTE_SUB, 136);

    // Copie des Tiles en memoire
    Memory_8b = (u8*)SPRITE_GFX;
    dmaCopy(Pointeur_Sprite, Memory_8b, 32*32);

    Memory_8b = (u8*)SPRITE_GFX_SUB;
    dmaCopy(Pointeur_Sprite, Memory_8b, 32*32);


    // Configuration OAM (Main)
	Oam[0][0].atr0 = (100&255) + (OBJCOLOR_256 << 13) + (OBJSHAPE_SQUARE << 14);

	Oam[0][0].atr1 = (100&511) + (OBJSIZE_32 << 14);

	Oam[0][0].atr2 = (OBJPRIORITY_0 << 10) + (0 & 1023);// 0 position du premier tiles

	// Configuration OAM (Sub)

	Oam[1][0].atr0 = (100&255) + (OBJCOLOR_256 << 13) + (OBJSHAPE_SQUARE << 14);

	Oam[1][0].atr1 = (100&511) + (OBJSIZE_32 << 14);

	Oam[1][0].atr2 = (OBJPRIORITY_0 << 10) + (0 & 1023);// 0 position du premier tiles

	// Copie des attributs dans la memoire
	DMA_Copy((void*)Oam, (void*)OAM0, 256, DMA_32NOW);


	// Infinite loop to keep the program running
	while (1)
	{
		swiWaitForVBlank();
	}

	return 0;
} // End of main()
J'ai simplement :
initialiser en mode 0 et sprite
initialiser la VRAM
charger la palette
charger les tiles
initialiser l'oam
charger l'oam

En mémoire avec desmume_Win32 ma palette est bien en place avec les bonnes couleurs, les tiles sont chargés ou il faut en mémoire.
Les écrans sont blanc pour les 4 BG du haut et du bas (conforme a ce que j'attendais).

Mais voilà ... Mon sprite n'apparait pas en haut, ni en bas (en priorité 0 pourtant).

J'ai exploré google ainsi que les tutos et autre pour voir si un forum montrerait comment afficher un sprite en libnds, mais aucun n'a pu m'aider (sa reviens toujours sur la Pa_Lib).
J'expose ici mon problème après 1 semaine de recherche et de manip pour me dépatouiller.

Si quelqu'un peut me dire d’où vient mon erreur dans mon code. Je vous remercie d'avance.

PS : sur mon programme d'origine il me met une tache uniformément bizarre sur l'écran du bas et rien sur celui du haut. Avec le même code, ci dessus il ne me met rien du tout...
Tannis Dragon est déconnecté   Réponse avec citation

Publicité

Vieux 10/08/2013, 10h53   #2
Tannis Dragon
Membre
 
Date d'inscription: 04/07/2006
Messages: 25
Par défaut

Bonjour,

Bien j'ai résolu mon problème.

En regardant dans la mémoire à l'adresse de l'OAM, j'ai constaté que tout étaient à 0.
Conclusion il ne me copie pas avec la DMA mes attributs OAM.

j'ai donc remplacé la structure actuelle par un simple tableau de uint16 avec un pointeur :
Code:
    // pointeur 16bit
    uint16* Memory_16b;

    uint16 OAM_B[128][4];
    uint16 OAM_H[128][4];
Puis j'ai fait une boucle pour mettre directement en mémoire :
Code:
    // Configuration OAM (sub)
	OAM_H[0][0] = (100&255) + (OBJCOLOR_256 << 13) + (OBJSHAPE_SQUARE << 14);

	OAM_H[0][1] = (100&511) + (OBJSIZE_32 << 14);

	OAM_H[0][2] = (OBJPRIORITY_0 << 10) + (0 & 1023);// 0 position du premier tiles

	// Copie des attributs dans la memoire
	Memory_16b = OAM_SUB;

	for(i=0;i<128;i++)
	{
	    for(j=0;j<4;j++)
            Memory_16b[i*4+j] = OAM_H[i][j];
	}
Ce n'est surement pas très "PRO", mais je suis qu'un simple amateur en programmation C/C++

Suite à cela j'ai remarqué aussi que certaine couleurs manquaient sur mon sprite : certain pixels étaient en noir.
Là encore la DMA était en cause (j'ai l'impression de ne pas maitriser du tout les copies DMA )

j'ai donc modifié de la sorte la partie chargement de couleur :
Code:
	// chargement palette du sprite
	Memory_16b = SPRITE_PALETTE;

    for(j=0;j<136;j++)
        Memory_16b[j] = Pointeur_Pal[j];

	Memory_16b = SPRITE_PALETTE_SUB;

    for(j=0;j<136;j++)
        Memory_16b[j] = Pointeur_Pal[j];
Bien entendu l'étape suivante pour ma part fût dans mettre un deuxième

J'ai réussie plus facilement mais avec une interrogation que je pose ici car cela fait un peu parti du même sujet :

j'ai 2 sprites de 32x32 que je copie en mémoire :
Code:
    // Copie des Tiles en memoire
    dmaCopy(Pointeur_Sprite, (void*)(SPRITE_GFX1 + (0x200000 *  0)), 32*32);
    dmaCopy(Pointeur_Sprite, (void*)(SPRITE_GFX1 + (0x200000 *  0)+0x400), 32*32);
Je sais, je sais j'utilise la DMA ici, c'est le seul qui marche

je décale naturellement de 0x400 dans la mémoire, ce qui représente 1024 pixels (32x32 pixels) je suis en 256 couleurs (1 octet).
Cela marche bien.

Mais pour donner le premier Tiles sur l'OAM du sprite2 j'ai été surpris.

Pour moi le premier Tiles du sprite2 est à 16 :
32x32 pixels du sprite1 me donne 4x4 Tiles en mémoire donc 16 Tiles (de 0 à 15).
Mes attributs devraient être comme ci dessous :
Code:
    // Configuration OAM (Main)
	OAM_B[0][0] = (100&255) + (OBJCOLOR_256 << 13) + (OBJSHAPE_SQUARE << 14); // pos Y

	OAM_B[0][1] = (100&511) + (OBJSIZE_32 << 14); // pos X

	OAM_B[0][2] = (OBJPRIORITY_0 << 10) + (0 & 1023);// 0 position du premier tiles

	// deuxieme
	OAM_B[1][0] = (100&255) + (OBJCOLOR_256 << 13) + (OBJSHAPE_SQUARE << 14);

	OAM_B[1][1] = (132&511) + (OBJSIZE_32 << 14);

	OAM_B[1][2] = (OBJPRIORITY_0 << 10) + (16 & 1023);// 16 position du premier tiles
le sprite2 n'apparait pas...
En essayant quelques combinaisons binaire (2,4,8...) en position j'ai finalement retrouvé mon sprite2 à la position 8

Mon code devient alors celui ci :
Code:
    // Configuration OAM (Main)
	OAM_B[0][0] = (100&255) + (OBJCOLOR_256 << 13) + (OBJSHAPE_SQUARE << 14); // pos Y

	OAM_B[0][1] = (100&511) + (OBJSIZE_32 << 14); // pos X

	OAM_B[0][2] = (OBJPRIORITY_0 << 10) + (0 & 1023);// 0 position du premier tiles

	// deuxieme
	OAM_B[1][0] = (100&255) + (OBJCOLOR_256 << 13) + (OBJSHAPE_SQUARE << 14);

	OAM_B[1][1] = (132&511) + (OBJSIZE_32 << 14);

	OAM_B[1][2] = (OBJPRIORITY_0 << 10) + (8 & 1023);// 8 position du premier tiles
Quelqu'un peut me donner une explication (méthode de calcul) sur ce décalage que je qualifie d'anormal ?

Merci.
Tannis Dragon est déconnecté   Réponse avec citation
Vieux 17/08/2013, 23h04   #3
Tiwaz
Newser
 
Date d'inscription: 18/03/2007
Localisation: Un coin trop froid...
Messages: 739
Par défaut

Rhaa, je l'ai pas vu tout de suite:

DISPLAY_SPR_1D_SIZE_128 : tes tiles sont donc indexés tous les 128b, or, un tile fait 64... Donc, c'est bien la moitié... Tu répares ça (et reviens à (16 & 1023) ) en utilisant DISPLAY_SPR_1D_SIZE_64

Bonne soirée

P.S. Tu es fan du DMA, donc un petit lien : http://drunkencoders.com/files/2013/...al-answer.html
__________________
Un langage de programmation est censé être une façon conventionnelle de donner des ordres à un ordinateur. Il n'est pas censé être obscur, bizarre et plein de pièges subtils, ça ce sont les attributs de la magie.

Dernière modification par Tiwaz ; 17/08/2013 à 23h39.
Tiwaz est déconnecté   Réponse avec citation
Vieux 20/08/2013, 21h59   #4
Tannis Dragon
Membre
 
Date d'inscription: 04/07/2006
Messages: 25
Par défaut

Bonsoir Tiwaz,

Merci pour ton aide !!

Je n'ai pas encore testé (vue l'heure tardif et que demain je boss ), mais au vue de ton explication sa me semble logique.
Je ne connaissais pas la signification du 128 sur le DISPLAY_SPR_1D_SIZE_128.

Sinon le faite que pour un 32x32 => 8 block et un 16x16 => 2 block, j'ai pu déterminer l'équation d'une droite qui me déterminait le coefficient multiplicatif a utiliser => 1/128.

Merci pour ton site, je l'ai survolé, apparemment c'est un test entre différente méthode de chargement en mémoire. Il est intéressant.

Je repasserais sur le site pour informer de mon résultat et je fermerais le sujet
Tannis Dragon est déconnecté   Réponse avec citation
Vieux 21/08/2013, 20h46   #5
Tannis Dragon
Membre
 
Date d'inscription: 04/07/2006
Messages: 25
Par défaut

Bonsoir,

Tiwaz a en effet raison, j'ai modifié mon VideoSetmode.
Avant :
Code:
    // Activation des sprites Mode 0 pour les deux ecrans
    videoSetMode(  MODE_0_2D |              // Mode 0 mosaique
                   DISPLAY_SPR_ACTIVE |     // Active les sprites
                   DISPLAY_SPR_1D |         // Mode Tiles
		   DISPLAY_SPR_1D_SIZE_128
                    );

	videoSetModeSub(  MODE_0_2D |            // Mode 0 mosaique
                   DISPLAY_SPR_ACTIVE |     // Active les sprites
                   DISPLAY_SPR_1D |         // Mode Tiles
		   DISPLAY_SPR_1D_SIZE_128
                    );
Apres :
Code:
    // Activation des sprites Mode 0 pour les deux ecrans
    videoSetMode(  MODE_0_2D |              // Mode 0 mosaique
                   DISPLAY_SPR_ACTIVE |     // Active les sprites
                   DISPLAY_SPR_1D |         // Mode Tiles
                   DISPLAY_SPR_1D_SIZE_64
                    );

	videoSetModeSub(  MODE_0_2D |            // Mode 0 mosaique
                   DISPLAY_SPR_ACTIVE |     // Active les sprites
                   DISPLAY_SPR_1D |         // Mode Tiles
                   DISPLAY_SPR_1D_SIZE_64
                    );
Je n'avais aucun doute sur cette solution.
Merci Tiwaz encore une fois.

@+
Tannis Dragon est déconnecté   Réponse avec citation
Vieux 21/08/2013, 21h57   #6
Tiwaz
Newser
 
Date d'inscription: 18/03/2007
Localisation: Un coin trop froid...
Messages: 739
Par défaut

De rien, tout le plaisir est pour moi... Désolé de ne pas être plus souvent présent et de répondre avec un peu de retard.

Bref, bonne continuation. Ca fait plaisir de voir que certains continue le developpement DS, alors que tout le monde se tourne vers les mobiles.
__________________
Un langage de programmation est censé être une façon conventionnelle de donner des ordres à un ordinateur. Il n'est pas censé être obscur, bizarre et plein de pièges subtils, ça ce sont les attributs de la magie.
Tiwaz est déconnecté   Réponse avec citation
Réponse

Liens sociaux

Tags
libnds, sprite

Publicité



Utilisateurs regardant la discussion actuelle : 1 (0 membre(s) et 1 invité(s))
 
Outils de la discussion
Modes d'affichage

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Navigation rapide

Discussions similaires
Discussion Auteur Forum Réponses Dernier message
NDS pb avec soundPlaySample Hazel d'ark Aide au développement 0 22/02/2010 12h49
NDS libnds : plusieurs sprites differents sur le meme ecran Christuff Aide au développement 3 01/02/2010 06h48
NDS Programmer sur DS avec la libnds Pitt Tutoriels 84 17/11/2009 18h12
Programmer sur DS avec la libnds Arcadia Les News 0 11/03/2007 21h42
Wi-Fi avec Freebox HD impossible ? ShiRo [NDS] Divers 5 20/02/2007 15h33


Fuseau horaire GMT +2. Il est actuellement 20h27.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Tous droits réservés.
Version française #16 par l'association vBulletin francophone
Design par Ass-Itch, DJP et Dr.Vince