1

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 { cmp 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)

3
  • It would help us to help you if you would also paste some sample data to see precisely how it is wrong. The asm code has an if inside the loop which isn't present in your code. Commented Aug 30, 2010 at 12:45
  • Hmm. It's very strange that IF statement doesn't exist in my question — in code of my question it is. I add IF, now there are all my function. Commented Aug 30, 2010 at 12:58
  • And I'm sorry, but I can't show some sample data — this code for software rendering. It's very easy to see on screen that something wrong, but what exactly — hard. I think that something wrong with Z compare, but I can't understand what exactly. Commented Aug 30, 2010 at 13:02

1 Answer 1

2

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
     }
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

It seems to be correct. I change zd type to uint16_t (because zdata actually 16 bit Z buffer) and almost of rendering good. There is another error with it, but I think that I can fix it. But maybe I can't :)
I understand what wrong. There are sign/unsigned confusion with some operations. This is correct:
int16_t * zd = (int16_t *)zdata; uint8_t * dat = data; int16_t * zb = (int16_t *)zbuffer; uint16_t shz = AsmDrawData.ShiftZ0; uint16_t * vid = (uint16_t *)video; [...] int16_t X = shz + zd[i]; [...] zb[i] = X; // update the depth

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.