STRUCTURE DE JEU 2D

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 5 janv. 2008 à 02:21
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 5 janv. 2008 à 02:31
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/45306-structure-de-jeu-2d

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
5 janv. 2008 à 02:31
GetDC() doit se libérer par ReleaseDC().
Gdi() retourne ce qui sort de CreateCompatibleDC(), l'appelant doit appeler DeleteDC().

__fastcall int setpix(int x,int y,color c) {
UINT add;
if(x<0 || y<0 || x>=X || y>=Y) return 0;
add = 3 *((Y - y - 1) * X + x);
_asm {
mov edi,VIDEO
add edi,add
mov ax,word ptr c
mov [edi],ax
mov al,c.r
mov [edi+2],al
}
return 1;
}

Typique ce qu'il ne faut jamais faire, une fonction se fait full asm ou C mais jamais un peu d'asm au milieu. Rien de tel pour empêcher toute optimisation du compilo.
'return xx' met une valeur dans EAX, vu que tu retournes 0 ou !=0, ce que tu as mis dans EDI allait dans EAX et le retour était deja prêt. Utiliser EDI n'est pas gratuit, le compilo mettra du PUSH et POP pour le restaurer, certain que c'était nécessaire ? (je t'assure que non).

avec
#define X 800
#define Y 600

Une struct se passant par adresse, on dira que color est un simple DWORD (ce qu'il faudrait mettre en union dans la struct color) vu que tu ne fais que le lire.
typedef struct _color {
union _clr {
struct {
BYTE b;
BYTE g;
BYTE r;
BYTE a;
};
DWORD value;
} clr;
} color, *LPcolor;

color c;
v = bnSetpix(x, y, c.clr.value);
Ainsi la fonction n'a pas à déréférencer l'adresse pour accéder à la valeur.
On va se dispenser des tests < 0, suffit de regarder x et y en DWORDs.
__declspec(naked) int __fastcall bnSetpix(int x, int y, DWORD c)
{
__asm {
xor eax, eax
cmp ecx, X
jae short setpixEXIT ;// x >= X
cmp edx, Y
jae short setpixEXIT ;// y >= Y
mov eax, edx
neg eax
add eax, (Y - 1)
imul eax, X
add eax, ecx
mov dx, word ptr[esp+4]
lea eax, [eax+eax*2]
add eax, VIDEO
mov cl, byte ptr[esp+6]
mov word ptr[eax], dx
mov byte ptr[eax+2], cl
setpixEXIT:
ret 4
}
}

Voici ce qu'il convenait d'écrire, tu constateras qu'il n'y a pas de PUSH ni de POP, les 3 registres généraux suffisaient amplement.
Pour conclure: Si l'ASM reste la voie de l'optimisation maximale, sa mise en oeuvre nécessite de nombreuses heures de pratique. Je t'encourage bien entendu à persévérer mais retiens bien que ce doit être FULL ASM ou FULL C, jamais de mix. C'est à force d'exercices qu'on prend la tournure d'esprit ASM mais il convient de ne pas en insérer dans ses codes tant qu'on n'en a pas une habitude bien rodée, exercices d'abord, en prod ensuite.

Bonne continuation.
Rejoignez-nous