Jump to content
IGNORED

sprpck updated


42bs

Recommended Posts

Just now, karri said:

yep. I am getting a bit interested in doing a brute force packer as no logic seems to work. Why, oh why are we so stupid?

I think your(?) approach with looking only at a small window might be a way.
Having a sliding window of 32 pixels.

 

  • Like 1
Link to comment
Share on other sites

Thanks for the quick look at this, @42bs! 1166 is pretty close to 1151 and much improved from my first try. I did not realize the -e option could be used to define the "edge" color, which in this case was index 0 defined to be black. There was already a background sprite clearing the screen to black, so the bootscreen sprite did not need to set every pixel in the rectangle; just the non-black ones.

Link to comment
Share on other sites

I am just running SuperSqueek with the brute force algo. Simple lines have just around 80000 variations that I need to evaluate. But the complex lines take ages... The worst line is 5^15 variations. Just generating the test vectors takes minutes...

I really have to cut down the problem with some kind of logic.

  • Sad 1
Link to comment
Share on other sites

Also made a small tool which dumps a sprite to compare sprpck vs. Amiga packer. Here some interesting finding:

 

L<n>(color(s)) or P<n>(color)

(Where n = count-1).

 

Amiga:

18:L5(011100) PF(0) P2(1)

sprpck:

19:L3(0111) PF(0) P1(0) P2(1)

 

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


unsigned char curByte;
unsigned int bitcount;

int readBits(FILE *in, int bits, int *len)
{
  int ret;

  if ( bitcount == 0 ){
    if ( feof(in) != 0 ){
      return -1;
    }
    fread(&curByte, 1, 1, in);
//->    printf("[%02x]",curByte);
    --(*len);
    bitcount = 8;
  }
  ret = 0;
  if ( bits > bitcount ){
    ret = curByte >> (8-bitcount);
    ret <<= bits-bitcount;
    if ( feof(in) != 0 ){
      return -1;
    }
    bits-= bitcount;
    fread(&curByte, 1, 1, in);
//->    printf("{%02x}",curByte);
    bitcount = 8;
    --(*len);
  }
  ret |= curByte >> (8-bits);
  curByte <<= bits;
  bitcount -= bits;
//->  if ( bitcount == 0 ) printf("+");

  return ret;
}

int main(int argc, char **argv)
{
  FILE *in;
  char inb;
  int bps;

  int nxt;
  int p;
  int cnt;
  int col;

  if ( (in = fopen(argv[1],"rb")) == NULL )
  {
    printf("Couldn't open %s !\n",argv[1]);
    return -1;
  }
  if ( argc == 3 ){
    bps = *argv[2]-'0';
    if ( bps < 1 || bps > 4 ){
      printf("BPS must be 1,2,3 or 4\n");
      return -1;
    }
    printf("BPS: %d\n",bps);
  } else {
    bps = 4;
  }
  curByte = 0;
  int dummy;
  while( 1 ){
    bitcount = 0;
    nxt = readBits(in,8,&dummy);
    if ( nxt < 0 ) break;
    printf("%2X:",nxt);
    for( --nxt; nxt > 0; ){
      p = readBits(in, 1, &nxt);
      if ( p < 0 ) break;
      if ( p == 0 ) {
        printf("P");
        cnt = readBits(in, 4, &nxt);
        if ( cnt < 0 ) break;
        printf("%X", cnt);
        col = readBits(in, bps, &nxt);
        if ( col < 0 ) break;
        printf("(%X) ", col);
      } else {
        printf("L");
        cnt = readBits(in, 4, &nxt);
        if ( cnt < 0 ) break;
        printf("%X(",cnt);
        for( col = 1; cnt >= 0 && col >= 0; --cnt){
          col = readBits(in, bps, &nxt);
          if ( col >= 0 ) {
            printf("%X",col);
          }
        }
        printf(") ");
        if ( col < 0 ) goto leave;
      }
    }
    printf("\n");
  }
leave:
  fclose(in);

  printf("\n");
  return 0;
}

 

Edited by 42bs
Link to comment
Share on other sites

Thanks.

 

I realized that the amount of data you need to analyse is on both sides of a literal packet. If either side has a runlength packet you need to analyse up to a certain number of bits that you should turn to literals.

 

The number depends on the bpp like:

 

    def better_as_literal(self):
        self.longest = 0
        for i in range(1, 16):
            if i * self.bpp < 1 + 4 + self.bpp:
                self.longest = i
 

So for 1 bpp you may need to check for +- 5 pixels while for 4 bpp it is enough with +- 2 pixels.

 

Here is the first line of SuperSqueek. Zero means runlen while one is literal

[[0, 16], [0, 16], [0, 16], [0, 16], [0, 16], [0, 7], [0, 3], [0, 7], [0, 2], [1, 1], [0, 4], [0, 16], [0, 16], [0, 6], [0, 2], [0, 7], [0, 2], [0, 7]]

 

With a little logic the only place where variation makes sense is in the middle. Here I vary the spot from -2..2.

Here is the interesting part from -2, -1, 0, 1, 2
(0, 7), (0, 0), (1, 3), (0, 4), (0, 16),
(0, 7), (0, 1), (1, 2), (0, 4), (0, 16),
(0, 7), (0, 2), (1, 1), (0, 4), (0, 16),

(0, 7), (0, 2), (1, 2), (0, 3), (0, 16),
(0, 7), (0, 2), (1, 3), (0, 2), (0, 16),
 

Of course I also need to clean up the vector

Link to comment
Share on other sites

9 minutes ago, karri said:

So for 1 bpp you may need to check for +- 5 pixels while for 4 bpp it is enough with +- 2 pixels.

In sprpck I do this, but only to the right.

I have this "int plimit[4] = { 6,5,4,3 };", means a packed chunk of this number of elements is not worth to further investigate.

 

But sprpck cannot "see" beyond a full packet. Maybe I should "split" up into 16 pixel chunks as last step.... (this is so mind-bogling, writing a 249byte rotozoomer is a piece of cake compared to this). :(


 

Link to comment
Share on other sites

53 minutes ago, 42bs said:

In sprpck I do this, but only to the right.

I have this "int plimit[4] = { 6,5,4,3 };", means a packed chunk of this number of elements is not worth to further investigate.

 

But sprpck cannot "see" beyond a full packet. Maybe I should "split" up into 16 pixel chunks as last step.... (this is so mind-bogling, writing a 249byte rotozoomer is a piece of cake compared to this). :(


 

I was planning to do it the other way. Start with up to 512 pixel chunks and process only the pixels outside "chunk % 16" both to right and left. My latest version is pretty fast already. But it is still just an algorithm study.

Link to comment
Share on other sites

New update pushed. Now Carl's picture compresses down to 1156 (5 bytes left from Amiga tools).

Fixed the bug found in the "Astroid Chasers" credit screen.

Removed "logic" compression. Now it only uses a sliding window of 32 pixels to find the best compression.

 

Still it packs differently in most parts then the Amiga tool.
 

  • Thanks 1
Link to comment
Share on other sites

  • 3 months later...

What is the story on the 64bit support? I have been building a toolchain in Docker images, so it becomes very easy to run a dev environment from Visual Studio Code. The Docker image uses a 64-bit version of alpine.

To build the image, it gets all the latest sources of CC65 and sprpck and builds it using make.

  • First issue is the sizes in the header definition for 64-bit.
    #define WORD unsigned short
    #define DWORD unsigned long
    #define LONG long
  • There seem to be some glitches in the generation of the .spr files

$(SPRPCK) -t6 -p2 -r001005 -S021007 -a000000 panels.bmp

 

With an older version of sprpck (Windows 1.98) the errors do not occur.

 

Any takers?

 

If anyone is interested in this new dev environment, please let me know and I can follow up

 

CircuitDudeBad.png

CircuitDudeGood.png

panels.bmp

Link to comment
Share on other sites

19 minutes ago, LX.NET said:

First issue is the sizes in the header definition for 64-bit.
#define WORD unsigned short
#define DWORD unsigned long
#define LONG long

What is the problem with this? AFAIK even for x64 VS uses "long" == 32bit.
But I agree, it would be better to use stdint.h definitions instead.

 

Thanks for the BMP, I'll have a look (but it is different from what you show in the post).

Edited by 42bs
Link to comment
Share on other sites

54 minutes ago, 42bs said:

What is the problem with this? AFAIK even for x64 VS uses "long" == 32bit.
But I agree, it would be better to use stdint.h definitions instead.

 

Thanks for the BMP, I'll have a look (but it is different from what you show in the post).

It would be great if we have source code that would compile cleanly on 32-bit and 64-bit. In Visual Studio Code (not Visual Studio 2017 or 2019) the Dev Container runs a Linux distro of your choosing. Most likely 64-bit from here on in. 

Link to comment
Share on other sites

34 minutes ago, Cyprian said:

 

I'm interested. Thanks

Me too. The idea of using Visual Studio Code is pretty clever as if runs on Linux as well.

 

Perhaps we could have  an integrated emulator and symbolic debugger as well.

 

The cc65 does already have high level C-symbols included in the assembly source. So it should be doable.

Link to comment
Share on other sites

On 1/5/2021 at 11:32 AM, karri said:

Me too. The idea of using Visual Studio Code is pretty clever as if runs on Linux as well.

 

Perhaps we could have  an integrated emulator and symbolic debugger as well.

 

The cc65 does already have high level C-symbols included in the assembly source. So it should be doable.

If you have a machine that can run Docker containers, the development experience becomes even better. I will try to post about this some time next week. 

Link to comment
Share on other sites

On 1/6/2021 at 4:38 PM, LX.NET said:

If you have a machine that can run Docker containers, the development experience becomes even better. I will try to post about this some time next week. 

I just decided to take a leap and give Windows a chance by ordering a modern laptop. Any hints in how to run things in Docker containers is highly appreciated. I hope to avoid dual boots.

Link to comment
Share on other sites

1 hour ago, karri said:

I just decided to take a leap and give Windows a chance by ordering a modern laptop. Any hints in how to run things in Docker containers is highly appreciated. I hope to avoid dual boots.

I am not using Docker, but for a long time I use VirtualBox VMs with (in my case) Xubuntu for various things where I need Linux. It even works nicely with USB, so I can run JTAG debuggers withing the VMs.

Nice thing: I have a VM per customer.

But I suggest to spend an extra penny for sufficient RAM (I have 32GB).

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...