Import .ACT palette colors

edited April 2014 in How To...

I've read this article from 2006 about how to import color palettes, and I've tried to use it, however it's giving me wrong colors. It seems to be working fine in greyscale.

image alt text

This is my .act file: https://dl.dropboxusercontent.com/u/30076751/nes.act , and this is my code,

Palette palette;

void setup() {
  size(640, 640);
  palette = new Palette("nes.act",64);
  background(0);

  for(int i=0; i<palette.size(); i++){
    noStroke();
    fill(palette.colors[i]);
    rect(i*width/palette.size(), 0, width/palette.size(), height);
  }
}

class Palette {
  color[] colors;

  Palette(String file){
    byte[] b=loadBytes(file);
    if(file.endsWith(".cs")){
      createPalette(b,8,26,b[2]&0xff);
    }
    else if (file.endsWith(".act")){
      createPalette(b,0,3,255);
    }
  }

  Palette(String file, int length){
    byte[] b=loadBytes(file);
    if(file.endsWith(".cs")){
      createPalette(b,8,26,length);
    }
    else if (file.endsWith(".act")){
      createPalette(b,0,3,length);
    }
  }

  void createPalette(byte[] b, int start, int steps, int length){
    colors=new color[length];
    int cnt=0;
    for(int i=0 ;i<length;i++){
      colors[i]=0xff<<24|b[start+i*steps]<<16|b[start+i*steps+1]<<8|b[start+i*steps+2]; 
    }
  }

  int size(){
    return colors.length;
  }
}

I've also tried by looking at the nes.act file and guessing how bytes were decoded but I can't get it :/ It looks like this,

0000 00ff ffff b641 44f8 a4c0 e400 58e9
347a f858 9894 0084 d801 ccf8 78f8 f8d8
f8e8 b8f8 9878 f868 44fc 4428 bc6d 5dcf
0000 fc00 00bc b8b8 f868 88fc 0068 f8d7
e7f6 6ccb fd3c bdfc 0040 5838 6a7d 0088
8827 9a9a 38a2 a200 f1e8 aeee ea01 a844
59f8 9892 ae9b 00b0 0000 6800 b7f7 b8d5
ddd5 58d7 54b8 f818 e8e8 78f8 b800 fac7
36ac 7c00 be96 3d50 3000 f6d8 ac61 5645
fca0 44f5 e7db e45c 10f3 9d7b f838 00f8
7858 9d0c 0bfa fafa bcbc bc7a 7a7a 3c3c
3c29 2929 1414 1406 0606 0202 02ff ffff

I found this too, from Adobe. It says,

There is no version number written in the file. The file is exactly 76 long, and contains 256 RGB colors: The first color in the table is index zero. There are three bytes per color in the order Red, Green, Blue.

Tagged:

Answers

  • edited April 2014

    Ok, I've solved it. However I don't know why the above code didn't work as expected. It is certainly some bitwise thing I don't understand.

    Notice that start = 0 for .act files because there isn't any header.

    I've changed it to a simpler approach, however it isn't as consice as the another one,

      void createPalette(byte[] b, int start, int steps, int length){
        colors=new color[length];
        int cnt=0;
        for(int i=0 ;i<length;i++){
          //colors[i] = 0xff<<24 | b[start+i*steps]<<16 | b[start+i*steps+1]<<8 | b[start+i*steps+2];
          int red = b[start+i*steps] & 0xFF;
          int green = b[start+i*steps+1] & 0xFF;
          int blue = b[start+i*steps+2] & 0xFF;
          colors[i] = color(red, green, blue);
        }
      }
    
  • edited April 2014

    Finally, I found that the current byte should be converted to int before applying bitwise operations, so the original one would work.

    void createPalette(byte[] b, int start, int steps, int length){
      colors=new color[length];
      int cnt=0;
      for(int i=0 ;i<length;i++){
        //corrected
        colors[i] = 0xff<<24 | (b[start+i*steps] & 0xFF)<<16 | (b[start+i*steps+1] & 0xFF)<<8 | (b[start+i*steps+2] & 0xFF);
      }
    }
    

    The byte type in Java is a signed byte (-127 to 128), and bitwise operations require an integer (32-bit) value.

    If we simply use a byte, for example, 0xFE, it would be taken as 0xFFFFFFFE, which is -2. So, we must be sure we have the unsigned value: 0x000000FE (254 in decimal) by using int() function, or applying a mask to it: 0xFE & 0xFF.

Sign In or Register to comment.