IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Problème avec la traduction d'un code ASM vers C++


Sujet :

Langage C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Problème avec la traduction d'un code ASM vers C++
    Bonjour,
    Je fais une traduction d'un code que j'ai depuis pas mal d'années en asm x86 qui génère un effet de vague d'eau sur une bitmap, dans l'idée d'en apprendre quelque chose je cherche à convertir ce code en c++, je pense avoir traduit environ 90% correctement mais les 10% restant me donne du fil à retordre, je n'ai pas d'erreur de compilation, les deux seuls warnings ne concerne pas directement cette partie du code mais des API Win 32, c'est une fois executer que au lieu d'avoir des belles vagues j'ai un genre de tas de pixels qui bougent pendant à peine une seconde puis le programme plante.

    c'est qui me préocupe c'est principalement deux fonctions dont je pense qu'il y a une subitilité que je n'arrive pas à reproduire correctement en C++:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    _WaveGetPixel:
    		movzx	eax,byte ptr [esi] ; esi = Src
    		shl	eax,2
    		movzx	edx,byte ptr [esi+3]
    		lea	edx,[edx+2*edx]
    		add	eax,edx
    		movzx	edx,byte ptr [esi-3]
    		lea	edx,[edx+2*edx]
    		add	eax,edx
    		movzx	edx,byte ptr [esi+ecx] ; ecx = dwDIByteWidth
    		lea	edx,[edx+2*edx]
    		add	eax,edx
    		mov	edx,esi
    		sub	edx,ecx
    		movzx	edx,byte ptr [edx]
    		lea	edx,[edx+2*edx]
    		add	eax,edx
    		shr	eax,4
    		mov	[edi],al ; edi = Rdr
    		inc	esi
    		inc	edi
    		ret
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; Rendering subroutine, renders the new frame data into lpDIBitsRender
    ; Algorithm:
    ; posx = Wave1(x-1, y) - Wave1(x+1, y) + x
    ; posy = Wave1(x, y-1) - Wave1(x, y+1) + y
    ; SourceBmp(x, y) = DestBmp(posx, posy)
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    _WaveRender	proc	_lpWaveObject
    		local	@dwPosX,@dwPosY,@dwPtrSource,@dwFlag
     
    		pushad
    		xor	eax,eax
    		mov	@dwFlag,eax
    		mov	ebx,_lpWaveObject
    		assume	ebx:ptr WAVE_OBJECT
     
    		test	[ebx].dwFlag,F_WO_ACTIVE
    		jz	_Ret
     
    		or	[ebx].dwFlag,F_WO_NEED_UPDATE
    		mov	esi,[ebx].lpWave1           ; esi = 00756F98
    		mov	edi,[ebx].dwWaveByteWidth	; edi = pixel pointer
     
    		xor	ecx,ecx
    		inc	ecx		; ecx=i  --  i=1; i<height; i++
    _Loop1:
    		xor	edx,edx		; edx=j  --  j=0; j<width; j++
    _Loop2:
    		push	edx
    ;********************************************************************
    ; PosY = i + energy above pixel - energy below pixel
    ; PosX = j + energy left of pixel - energy right of pixel
    ;********************************************************************
    		mov	eax,edi
    		sub	eax,[ebx].dwWaveByteWidth
    		mov	eax,[esi+eax]
    		mov	@dwPosY,eax
     
    		mov	eax,[ebx].dwWaveByteWidth
    		lea	eax,[edi+eax]
    		mov	eax,[esi+eax]
    		sub	@dwPosY,eax
    		add	@dwPosY,ecx
     
    		mov	eax,[esi+edi-4];;;;;
    		sub	eax,[esi+edi+4]
    		add	eax,edx			;@dwPosX = eax
    		mov	@dwPosX,eax
     
    		cmp	eax,0
    		jl	_Continue
    		cmp	eax,[ebx].dwBmpWidth ; = 395
    		jge	_Continue
    		mov	eax,@dwPosY
    		cmp	eax,0
    		jl	_Continue
    		cmp	eax,[ebx].dwBmpHeight ; = 123
    		jge	_Continue
    ;********************************************************************
    ; ptrSource = dwPosY * dwDIByteWidth + dwPosX * 3
    ; ptrDest = i * dwDIByteWidth + j * 3
    ;********************************************************************
    		mov	eax,@dwPosX
    		lea	eax,[eax+eax*2]
    		mov	@dwPosX,eax
    		push	edx
    		mov	eax,@dwPosY
    		mul	[ebx].dwDIByteWidth ; = 1188
    		add	eax,@dwPosX
    		mov	@dwPtrSource,eax
     
    		mov	eax,ecx
    		mul	[ebx].dwDIByteWidth
    		pop	edx
    		lea	edx,[edx+edx*2]
    		add	eax,edx			;@dwPtrDest = eax
    ;********************************************************************
    ; Render pixel [ptrDest] = Original pixel [ptrSource]
    ;********************************************************************
    		pushad
    		mov	ecx,@dwPtrSource
    		mov	esi,[ebx].lpDIBitsSource
    		mov	edi,[ebx].lpDIBitsRender
    		lea	esi,[esi+ecx]
    		lea	edi,[edi+eax]
    		.if	ecx !=	eax
    			or	@dwFlag,1	; If the source pixel and destination pixel are different, it indicates that the activity is still ongoing
    			mov	ecx,[ebx].dwDIByteWidth
    			call	_WaveGetPixel
    			call	_WaveGetPixel
    			call	_WaveGetPixel
    		.else
    			cld
    			movsw ; ESI + 3
    			movsb ; EDI + 3
    		.endif
    		popad
    ;********************************************************************
    ; Continue looping
    ;********************************************************************
    _Continue:
    		pop	edx
    		inc	edx
    		add	edi,4		; Increment pixel
    		cmp	edx,[ebx].dwBmpWidth
    		jb	_Loop2
     
    		inc	ecx
    		mov	eax,[ebx].dwBmpHeight
    		dec	eax
    		cmp	ecx,eax
    		jb	_Loop1
    ;********************************************************************
    ; Copy the rendered pixel data to hDc (Device Context)
    ;********************************************************************
    		invoke	SetDIBits,[ebx].hDcRender,[ebx].hBmpRender,0,[ebx].dwBmpHeight,\
    			[ebx].lpDIBitsRender,addr [ebx].stBmpInfo,DIB_RGB_COLORS
    		.if	! @dwFlag
    			and	[ebx].dwFlag,not F_WO_ACTIVE
    		.endif
    _Ret:
    ;********************************************************************
    		assume	ebx:nothing
    		popad
    		ret
     
    _WaveRender	endp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    void WaveGetPixel(unsigned char* dst, const unsigned char* src, int stride) {
        unsigned int sum = 0;
        unsigned int pix;
     
        // (4 * Pxl(x,y) +
        //  3 * Pxl(x-1,y) +
        //  3 * Pxl(x+1,y) +
        //  3 * Pxl(x,y+1) +
        //  3 * Pxl(x,y-1)) / 16
        //
        // convolution kernel:
        //
        // +----+----+----+
        // |    | 3A |    |
        // +----+----+----+
        // | 3L | 4C | 3R |
        // +----+----+----+
        // |    | 3B |    |
        // +----+----+----+
     
        // 4 * Pxl(x,y)
        // current pixel (4C)
        pix = src[0];
        pix <<= 2;
        sum += pix;
     
        // 3 * Pxl(x-1,y)
        // pixel to the left (3L)
        pix = src[-3];
        pix *= 3;
        sum += pix;
     
        // 3 * Pxl(x+1,y)
        // pixel to the right (3R)
        pix = src[3];
        pix *= 3;
        sum += pix;
     
        // 3 * Pxl(x,y+1)
        // pixel below (3B)
        pix = src[stride];
        pix *= 3;
        sum += pix;
     
        // 3 * Pxl(x,y-1)
        // pixel above (3A)
        pix = src[-stride];
        pix *= 3;
        sum += pix;
     
        // / 16
        sum >>= 4;
     
        dst[0] = sum;
    }
     
    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    // Rendering subroutine, renders the new frame data into lpDIBitsRender
    // Algorithm:
    // posx = Wave1(x-1, y) - Wave1(x+1, y) + x
    // posy = Wave1(x, y-1) - Wave1(x, y+1) + y
    // SourceBmp(x, y) = DestBmp(posx, posy)
    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     
    void WaveRender(WAVE_OBJECT* lpWaveObject) { // Translation OK
        int dwPosX, dwPosY, dwFlag = 0;
        int dwPtrSource;
        int dwPtrDest;
     
        if (!(lpWaveObject->dwFlag & F_WO_ACTIVE))
            return;
     
        lpWaveObject->dwFlag |= F_WO_NEED_UPDATE;
        int *esi = lpWaveObject->lpWave1;
        int edi = lpWaveObject->dwWaveByteWidth;
        //int edi = (lpWaveObject->dwWaveByteWidth / sizeof(*esi));
     
        //unsigned char *Src = lpWaveObject->lpDIBitsSource;
        //unsigned char *Rdr = lpWaveObject->lpDIBitsRender;
     
        unsigned char* Src;
        unsigned char* Rdr;
     
        int i = 1;
        do {
            int j = 0;
            do {
     
                // Calculate PosY = i + energy above pixel - energy below pixel
                dwPosY = esi[(edi - lpWaveObject->dwWaveByteWidth) / sizeof(*esi)];
                dwPosY = dwPosY - esi[(lpWaveObject->dwWaveByteWidth + edi) / sizeof(*esi)] + i;
     
                // Calculate PosX = j + energy left of pixel - energy right of pixel
                dwPosX = esi[(edi - 4) / sizeof(*esi)] - esi[(edi + 4) / sizeof(*esi)] + j;
     
                if (dwPosX >= 0 && dwPosX < lpWaveObject->dwBmpWidth && dwPosY >= 0 && dwPosY < lpWaveObject->dwBmpHeight) {
                    // Calculate ptrSource = dwPosY * dwDIByteWidth + dwPosX * 3
                    dwPtrSource = (dwPosY * lpWaveObject->dwDIByteWidth + dwPosX * 3);
     
                    // Calculate ptrDest = i * dwDIByteWidth + j * 3
                    dwPtrDest = (i * lpWaveObject->dwDIByteWidth + j * 3);
     
                    // Render pixel [ptrDest] = Original pixel [ptrSource]
                    //Src += dwPtrSource; //lea	esi,[esi+ecx]
                    //Rdr += dwPtrDest;   //lea	edi,[edi+eax]  
                    Src = &lpWaveObject->lpDIBitsSource[dwPtrSource];
                    Rdr = &lpWaveObject->lpDIBitsRender[dwPtrDest];
     
                    if (dwPtrSource != dwPtrDest) {
                        dwFlag |= 1;  // Set flag to indicate that the state is still active
                        WaveGetPixel(Rdr, Src, lpWaveObject->dwDIByteWidth);
                        Rdr += 1;
                        Src += 1;
                        WaveGetPixel(Rdr, Src, lpWaveObject->dwDIByteWidth);
                        Rdr += 1;
                        Src += 1;
                        WaveGetPixel(Rdr, Src, lpWaveObject->dwDIByteWidth);
                        Rdr += 1;
                        Src += 1;
                    }
                    else {
                        Src = Src + 3;
                        Rdr = Rdr + 3;
                    }
                }
                edi += 4;
                j += 1;
            } while (j < lpWaveObject->dwBmpWidth);
             i += 1;
        } while (i < lpWaveObject->dwBmpHeight - 1);
     
        // Copy rendered pixel data to hDc
        SetDIBits(lpWaveObject->hDcRender, lpWaveObject->hBmpRender, 0, lpWaveObject->dwBmpHeight, (const int*)lpWaveObject->lpDIBitsRender, &lpWaveObject->stBmpInfo, DIB_RGB_COLORS);
     
        if (!dwFlag) {
            lpWaveObject->dwFlag &= ~F_WO_ACTIVE;
        }
    }

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Si j'ai bien compris ce code, ça utilise une texture (dans lpWave1) pour faire un genre de bump-mapping sur le bitmap à traiter?
    Peut-on voir cette texture, ses dimensions, son échelle de valeurs?
    Ça pourrait valoir le coup d'encapsuler un peu plus (quitte à décapsuler plus tard pour du code performance-critical)

    PS: Je suppose que tu as déjà vérifié que tes bitmaps ont les bonnes dimensions et le bon format (on dirait qu'il faut spécifiquement des bitmaps 24 bits ici -- le code de floutage traite individuellement chaque canal)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Si c'est du traitement d'image, autant passer directement aux Shaders, non ?

Discussions similaires

  1. Réponses: 6
    Dernier message: 30/07/2012, 21h53
  2. Comment gérer les WideString avec du code ASM ?
    Par Zepeq dans le forum Langage
    Réponses: 2
    Dernier message: 06/04/2008, 11h57
  3. [JavaComm]Pb avec l'execution d'un code natif sous linux
    Par seb31 dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 02/06/2004, 14h25
  4. Code asm à lier à un programme C
    Par Condor7 dans le forum x86 16-bits
    Réponses: 3
    Dernier message: 26/05/2004, 17h52
  5. [TP]code asm dans une procedure
    Par M.Dlb dans le forum Turbo Pascal
    Réponses: 3
    Dernier message: 17/08/2002, 20h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo