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;
    }
}