C implementation of Assembler code
I'm trying to rewrite this asm code in C, but my asm knowledge very bad.
struct
{
union
{
struct{
WORD ShiftZ0;
WORD ShiftZ1;
WORD ShiftZ2;
WORD ShiftZ3; };
struct{
DWORD ShiftZ01;
DWORD ShiftZ23; };
};
short ShiftZ0Align;
short ShiftZ1Align;
short ShiftZ2Align;
short ShiftZ3Align;
int deltaZ0ToNextLine;
int deltaZ1ToNextLine;
void *Palette;
} AsmDrawData;
inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void video,int no_dot) {
__asm
{
cm开发者_运维技巧p no_dot,0
je end
mov esi,zdata
mov edi,video
mov ebx,zbuffer
mov ecx,AsmDrawData.Palette
lp:
mov eax,AsmDrawData.ShiftZ01
add ax,[esi]
cmp ax,[ebx]
jle end_out_byte
mov [ebx],ax
mov edx,data
movzx edx,byte ptr [edx]
mov DX_REG,[ecx+edx(COLOR_DEPTH/8)]
mov [edi],DX_REG
end_out_byte:
add edi,(COLOR_DEPTH/8)
add ebx,2
add esi,2
inc data
dec no_dot
jg lp
end:
}
}
This is what I write, but this wrong:
inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void *video,int no_dot) {
for( int i = 0; i < no_dot; i++ ) {
if( ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0 >= ((WORD*)zbuffer)[i] )
{
((WORD*)zbuffer)[i] = ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0;
((WORD*)video)[i] = ((WORD*)AsmDrawData.Palette)[((BYTE*)data)[i]];
}
}
}
Where I could be wrong? (sorry for my very very bad english)
This is not a real answer. It's just some ideas and a rewriting of the function as I understand it in hopefully a more clear form.
I highly suspect that your problem was with the line:
if( ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0 >= ((WORD*)zbuffer)[i] )
In this code you cast the zdata
pointer from a byte to a word pointer. That seems odd to me. The assembly does appear to have done the same thing, though. Since you probably know more about how the zdata field gets populated you can probably make a better determination about it.
This zbuffer algorithm appears to be fairly standard, so even without trying to reverse engineer this assembly you should be able to re-implement it in C fairly easily.
I rewrote this, . I like to keep this localized, so I just declare local pointers at the top that have the correct types (and also use the C99 stdint names because they are more portable than WORD).
#include <stdint.h>
inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void *video,int no_dot) {
uint8_t * zd = zdata; // Should this be 8 or 16 bit
uint8_t * dat = data;
uint16_t * zb = zbuffer;
uint16_t shz = AsmDrawData.ShiftZ0;
uint16_t * vid = (uint16_t *)video;
for( int i = 0; i < no_dot; i++ ) {
uint16_t X = shz + zd[i];
if( X >= zb[i] ) // Is this the correct direction of the compare
{
zb[i] = zdata[i] + X; // update the depth
vid[i] = AsmDrawData.Palette[ dat[i] ]; // update the color
}
}
}
精彩评论