Skip to content

Instantly share code, notes, and snippets.

@AfBu

AfBu/pico8png.cs Secret

Created September 12, 2015 22:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AfBu/dc9ddca6a885d95cdb64 to your computer and use it in GitHub Desktop.
Save AfBu/dc9ddca6a885d95cdb64 to your computer and use it in GitHub Desktop.
PICO-8 PNG CARTRIDGE LOADING ROUTINE
// emulator variables
byte[] cart = new byte[32769];
byte[] ram = new byte[32768];
public string LoadCart(string fn)
{
string code = "";
// load raw data from png
Bitmap bmp = new Bitmap(fn);
int x, y;
for (y = 0; y < bmp.Height; y++)
{
for (x = 0; x < bmp.Width; x++)
{
int pos = x + y * bmp.Width;
// if we reached limit we are not doing anything
if (pos > 32768) continue;
Color c = bmp.GetPixel(x, y);
byte a = (byte)(c.A & 0x03);
byte r = (byte)(c.R & 0x03);
byte g = (byte)(c.G & 0x03);
byte b = (byte)(c.B & 0x03);
byte z = (byte)((a << 6) + (r << 4) + (g << 2) + b);
cart[pos] = z;
}
}
// copy cart to ram
Buffer.BlockCopy(cart, 0, ram, 0, 0x4300);
// decode source
bool compressed = (cart[0x8000] == 1);
int size = (cart[0x4304] << 8) + cart[0x4305];
if (compressed)
{
int i = 0;
string chars = " 0123456789abcdefghijklmnopqrstuvwxyz!#%(){}[]<>+=/*:;.,~_";
while (i < size && 0x4308 + i < 0x8000)
{
byte b = cart[0x4308 + i];
if (b == 0x00) // extended
{
code += (char)cart[0x4308 + i + 1];
i += 2;
}
else if (b == 0x01) // new line
{
code += "\n";
i++;
}
else if (b >= 0x02 && b <= 0x3B) // characters
{
code += chars[b - 2];
i++;
}
else // copy block
{
byte b2 = cart[0x4308 + i + 1];
int offset = (b - 0x3C) * 16 + (b2 & 0xF);
int length = (b2 >> 4) + 2;
string part = "";
for (int c = 0; c < length; c++)
{
part += code[code.Length - offset + c];
}
code += part;
i += 2;
}
}
}
else // uncompressed
{
for (int i = 0; i < size; i++)
{
code += (char)cart[0x4308 + i];
}
}
return code;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment