Jump to content
IGNORED

polyon sprite


yami

Recommended Posts

Polygons can have up to 15 vertices.

 

See our description at www.arsantica-online.com in the stccc section.

 

Oh, it is plain 2D. ;-)

 

Here a bin2asm converter for the scene file, for those interested.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int pos;
uint8_t getByte(FILE *in)
{
  int inbyte0;

  inbyte0 = fgetc(in);
  ++pos;
  if ( inbyte0 < 0 ){
    printf("Error\n");
    exit(1);
  }
  return (uint8_t)inbyte0;
}
uint16_t getWord(FILE *in)
{
  return (uint16_t)((getByte(in)<<|getByte(in));
}

int main(void)
{
  FILE *in;
  int inbyte;
  uint8_t fb;
  uint16_t word;
  uint16_t color;
  int frame;
  int idx;
  in = fopen("scene1.bin","r");

  frame = 0;
  pos = 0;
  while( !feof(in) ){
    fb = getByte(in);
    printf("frame%03d:\n",frame);
    printf(" dc.b $%02x\n",fb);
    if ( fb & 1 ){
      printf("; /* clear screen */\n");
    }
    if ( fb & 2 ){
      printf("palette%03d:\n",frame);
      word = getWord(in);
      printf(" dc.w $%04x\n",word);
      for(idx = 0; word ; word <<= 1, idx += 1){
        if ( word & 0x8000 ){
          color = getWord(in);
          printf(" dc.w $%04x ; %d\n",color,idx);
        }
      }
    }
    if ( fb & 4 ){
      uint8_t cntVert;
      printf("; /* frame indexes */\n"
             "frameIdx%03d:\n", frame);
      cntVert = getByte(in);
      printf(" dc.b %d  ; number of vertices\n", cntVert);
      for( ; cntVert > 0; --cntVert){
        uint8_t x,y;
        x = getByte(in);
        y = getByte(in);
        printf( " dc.b %3d,%3d\n",x,y);
      }
      int vert = 0;
      while( 1 ){
        fb = getByte(in);
        printf("desc%03d_%03d:\n"
               " dc.b $%02x\n",frame, vert,fb);

        if ( fb == 0xfd ){
          printf(" .end\n");
          exit(0);
        }
        if ( fb == 0xff ){
          break;

        }
        if ( fb == 0xfe ){
          while( (pos & 0xffff) ){
            (void)getByte(in);
          }
          break;
        }

        printf(" dc.b ");
        for ( fb &= 0xf; fb; --fb){
          printf("%d",getByte(in));
          if ( fb != 1 ){
            printf(",");
          } else {
            printf("\n");
          }
        }
        ++vert;
      }
    } else {
      printf("; /* non-indexed */\n");
      int vert = 0;
      while( 1 ){
        fb = getByte(in);
        printf("desc%03d_%03d:\n"
               " dc.b $%02x\n",frame, vert,fb);

        if ( fb == 0xfd ){
          printf(" .end\n");
          exit(0);
        }
        if ( fb == 0xff ){
          break;

        }
        if ( fb == 0xfe ){
          while( (pos & 0xffff) ){
            (void)getByte(in);
          }
          break;
        }

        printf(" dc.b ");
        for ( fb &= 0xf; fb; --fb){
          printf("%d,%d",getByte(in),getByte(in));
          if ( fb != 1 ){
            printf(",");
          } else {
            printf("\n");
          }
        }
        ++vert;
      }
    }

    ++frame;
  }

  return 0;
}

The output seems to be correct.

Edited by 42bs
  • Like 1
Link to comment
Share on other sites

Btw we find out that fc28-fc2b (hoff and voff) can effect kind of subpix adjustment.

 

The Epyx manual describe those as magic numbers.

 

Are those kind of init value for Suzy like the init value in the Amiga Blitter when applying bresenham line?

 

And can those be used to minimize the edge jitter?

Edited by Heaven/TQA
Link to comment
Share on other sites

Btw we find out that fc28-fc2b (hoff and voff) can effect kind of subpix adjustment.

 

The Epyx manual describe those as magic numbers.

 

Are those kind of init value for Suzy like the init value in the Amiga Blitter when applying bresenham line?

 

And can those be used to minimize the edge jitter?

 

From the manual:

 

 

Horizontal and Vertical Size Offset

In order to balance the visual 'bump' that occurs at the reference point of a multi- quadrant sized sprite, we implemented a 'cheat' value of initial offset for both horizontal and vertical size. They are programmed independently at the time of sprite engine initialization. For horizontal, the left direction offset is forced to zero, and the right direction offset is programmed to 007F. For vertical, the up direction offset is forced to zero, and the down direction offset is programmed to 007F.

 

So these offsets are not related to the "jitter" on the edges. These are simply due to rounding errors when summing up.

A triangle is simply a one pixel sprite which is stretched in Y an X direction and tilted.

Link to comment
Share on other sites

Yes, the real thing is slower than the emulator. In my version the OXYGENE zoom takes 7 VBL (60Hz) per frame but handybug only 5 or 6.

But it shows clearly that the triangle routine needs a lot of optimization to detect single pixel triangles or ones with no tilt.

 

But actually, I take it as competition against myself ;-) It is funny how many bugs one can place in a few hundred lines of code :(

  • Like 1
Link to comment
Share on other sites

Some findings:

 

- the data file is (at least with lzma or lz4) not compressible.

- pre-processing saves a few cycles, but that's against the rule ;-)

- I thought the calculation of the tilt is the biggest problem. Three divides, each 174+n cycles.

So I made a 1/y table and used multiplication (only 54 cycles).

Guess what? No change. The first frame takes 7 VBLs(60Hz) to render. With or without divide.

So I really think, optimizing has to check for all those single pixel triangles.

- With Processing I could show that the n-poly to triangle can be rather simple: Keeping x0,y0 and draw a triangle to the next two points. Then go to the next and so on. X0,Y0 is always kept.

while ( true ) {
  marker = getByte();
  if ( marker == 0xff || marker == 0xfe || marker == 0xfd ) {
    return marker;
  }
  col = (marker >> 4);
  fill(r[col], g[col], b[col]);
  stroke(r[col], g[col], b[col]);

  nvertices = marker & 0xf;
  v0 = getByte();
  v1 = getByte();
  {
    for ( nvertices-=2; nvertices > 0; --nvertices) { 
      v2 = getByte();
      mytriangle(x[v0], y[v0], x[v1], y[v1], x[v2], y[v2]);
      v1 = v2;
    }
  }
}

Too bad, in my Lynx code is still a bug, sometime the screen is corrupted. But the Processing version looks correct.

 

Regarding BLL: If you define "DEBUG" then the loader is active and you reload directly without entering BLL.

This way, you can store the scene file on the flash card just download the demo via ComLynx.

  • Like 1
Link to comment
Share on other sites

hm the data file is already 640kb. And I have the very bad feeling that it will get slower if you have to unpack it in addtion to playing the video.

Anyway, the latest emulator core can handle 2MB ROMs ;-)

 

Too bad I have to stick with version 0.95. Anything else does not run on my PC. Something M$ broke in one of the updates over the last year :(

Link to comment
Share on other sites

Btw Bastian, preprocessing is allowed. Otherwise no C64 version possible ;).

 

I did not went yet to test lz4 but thought it might help in packed streaming depacking.

 

Ah, ok, then at least the "lsr" for the vertices can be off-loaded.

Link to comment
Share on other sites

Bastian,

 

what do you mean with filler bytes? as Leonard filled up to 64k boundary with "filler bytes". but that's not like you can save 400k ;)

 

Ok, yes, now seeing the pure numbers I might have a big-bug in my converter ... back to start, no $4000 ... ;-)

Link to comment
Share on other sites

Managed to get packing working. But it is too slow. But fits in 500k.

 

For some reason the colors are not 100% right. Close, but not completely correct.

 

attachicon.gifpacked.zip

    if ( fb & 2 ){
      if ( !out ){
        printf("palette%04d:\n",frame);
        printf(" dc.b ");
      }
      for(cnt = 0, idx = 0; word ; word <<= 1, ++idx){
        if ( word & 0x8000 ){
          //00000RRR0GGG0BBB => 0G BR
          int r = (getByte(in) & 0x7)<<1;
          int g = getByte(in);
          int b = (g & 0x7)<<1;
          g = (g >> 4) & 0xe;

          if ( out ){
            fputc(idx,out);
            fputc(g,out);
            fputc((b<<4)|r,out);
          } else {
            printf("%d,", idx);
            printf("$%02x,", g);
            if ( word & 0x7fff ){
              printf("$%02x,",(b<<4)|r);
            } else {
              printf("$%02x\n",(b<<4)|r);
            }
          }
          cnt += 2;
        }
      }
    }

&7 is the trick, shift for brightness

post-3110-0-98368700-1543920481.jpg

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...