Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rgbgfx + c tools #168

Closed
yenatch opened this issue Nov 24, 2017 · 6 comments
Closed

rgbgfx + c tools #168

yenatch opened this issue Nov 24, 2017 · 6 comments

Comments

@yenatch
Copy link
Contributor

yenatch commented Nov 24, 2017

need to unearth pkmncompress.c and use the other pokecrystal c tools instead of the submodule

@dannye
Copy link
Member

dannye commented Nov 24, 2017

If by "unearth" you mean "find a copy of", I have it.
http://www.mediafire.com/file/zw9m4tob1lty6c2/pkmncompress.rar

This has been in my MediaFire since April 2014.
I'm not sure if there's a newer version.

@yenatch
Copy link
Contributor Author

yenatch commented Nov 24, 2017

there is

i think

@dannye
Copy link
Member

dannye commented Nov 24, 2017

I found a version on my computer from January 2015.
http://www.mediafire.com/file/z379bl3h8esvbih/pkmncompress.c

@dannye
Copy link
Member

dannye commented Nov 24, 2017

Here's August 2015. Might be the same as the previous:
pret/pokemon-reverse-engineering-tools@8b51c47

@yenatch
Copy link
Contributor Author

yenatch commented Nov 24, 2017

i found my personal copy from dec 2014. it's diverged some. i'll try to consolidate the changes.

/*
 * Copyright © 2013 stag019 <stag019@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

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

uint8_t *compressed;
int xrows;
int xwidth;
int curbit;
int curbyte;

void writebit(int bit)
{
	if(++curbit == 8)
	{
		curbyte++;
		curbit = 0;
	}
	compressed[curbyte] |= bit << (7 - curbit);
}

void method_1(uint8_t *RAM)
{
	int i;
	int j;
	int nibble_1;
	int nibble_2;
	int code_1;
	int code_2;
	int table;
	static int method_1[2][0x10] = {{0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4, 0xC, 0xD, 0xF, 0xE, 0xA, 0xB, 0x9, 0x8}, {0x8, 0x9, 0xB, 0xA, 0xE, 0xF, 0xD, 0xC, 0x4, 0x5, 0x7, 0x6, 0x2, 0x3, 0x1, 0x0}};

	for(i = 0; i < xrows * xwidth * 8; i++)
	{
		j = i / xrows;
		j += i % xrows * xwidth * 8;
		if(!(i % xrows))
		{
			nibble_2 = 0;
		}
		nibble_1 = (RAM[j] >> 4) & 0x0F;
		table = 0;
		if(nibble_2 & 1)
		{
			table = 1;
		}
		code_1 = method_1[table][nibble_1];
		nibble_2 = RAM[j] & 0x0F;
		table = 0;
		if(nibble_1 & 1)
		{
			table = 1;
		}
		code_2 = method_1[table][nibble_2];
		RAM[j] = (code_1 << 4) | code_2;
	}
}

void RLE(int nums)
{
	int search;
	int i;
	int j;
	int bitcount;
	int number;
	static unsigned int RLE[0x10] = {0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};

	bitcount = -1;
	search = ++nums;
	while(search > 0)
	{
		for(i = 0; i < 0xF; i++)
		{
			if(RLE[i] == search)
			{
				bitcount = i;
				break;
			}
		}
		if(bitcount != -1)
		{
			break;
		}
		search--;
	}
	number = nums - RLE[bitcount];
	for(j = 0; j < bitcount; j++)
	{
		writebit(1);
	}
	writebit(0);
	for(j = bitcount; j >= 0; j--)
	{
		writebit((number >> j) & 1);
	}
}

void data_packet(uint8_t *bitgroups, int bgi)
{
	int i;
	for(i = 0; i < bgi; i++)
	{
		writebit((bitgroups[i] >> 1) & 1);
		writebit(bitgroups[i] & 1);
	}
}

int interpret_compress(uint8_t *RAM_1, uint8_t *RAM_2, int interpretation, int switchram)
{
	uint8_t *_1_RAM;
	uint8_t *_2_RAM;
	int i;
	int ram;
	int type;
	int nums;
	uint8_t *bitgroups;
	int x;
	int y;
	int byte;
	int bit;
	int bitgroup;
	int bgi = 0;

	_1_RAM = (uint8_t*) calloc(0x188, 1);
	_2_RAM = (uint8_t*) calloc(0x188, 1);
	if(switchram)
	{
		memcpy(_1_RAM, RAM_2, 0x188);
		memcpy(_2_RAM, RAM_1, 0x188);
	}
	else
	{
		memcpy(_1_RAM, RAM_1, 0x188);
		memcpy(_2_RAM, RAM_2, 0x188);
	}

	switch(interpretation)
	{
		case 1:
			method_1(_1_RAM);
			method_1(_2_RAM);
		break;
		case 2:
		case 3:
			for(i = 0; i < xrows * xwidth * 8; i++)
			{
				_2_RAM[i] ^= _1_RAM[i];
			}
			method_1(_1_RAM);
		break;
	}
	if(interpretation == 3)
	{
		method_1(_2_RAM);
	}

	curbit = 7;
	curbyte = 0;
	compressed = (uint8_t*) calloc(0x310, 1);
	compressed[0] = (xrows << 4) | xwidth;
	writebit(switchram);

	for(ram = 0; ram < 2; ram++)
	{
		type = 0;
		nums = 0;
		bitgroups = (uint8_t*) calloc(0x1000, 1);

		for(x = 0; x < xwidth; x++)
		{
			for(bit = 0; bit < 8; bit += 2)
			{
				byte = x * xrows * 8;
				for(y=0; y < xrows * 8; y++)
				{
					if(ram)
					{
						bitgroup = (_2_RAM[byte] >> (6 - bit)) & 3;
					}
					else
					{
						bitgroup = (_1_RAM[byte] >> (6 - bit)) & 3;
					}
					if(!bitgroup)
					{
						if(!type)
						{
							writebit(0);
						}
						else if(type == 1)
						{
							nums++;
						}
						else
						{
							data_packet(bitgroups, bgi);
							writebit(0);
							writebit(0);
						}
						type = 1;
						free(bitgroups);
						bitgroups = (uint8_t*) calloc(0x1000, 1);
						bgi = 0;
					}
					else
					{
						if(!type)
						{
							writebit(1);
						}
						else if(type == 1)
						{
							RLE(nums);
						}
						type = -1;
						bitgroups[bgi++] = bitgroup;
						nums = 0;
					}
					byte++;
				}
			}
		}
		if(type == 1)
		{
			RLE(nums);
		}
		else
		{
			data_packet(bitgroups, bgi);
		}
		if(!ram)
		{
			if(interpretation < 2)
			{
				writebit(0);
			}
			else
			{
				writebit(1);
				writebit(interpretation - 2);
			}
		}
	}
	free(bitgroups);
	free(_1_RAM);
	free(_2_RAM);
	return (curbyte + 1) * 8 + curbit;
}

int compress(uint8_t *data, int width, int height)
{
	uint8_t *RAM_1;
	uint8_t *RAM_2;
	int i;
	int mode;
	int order;
	int newsize;
	int compressedsize;
	int size = -1;
	uint8_t *current = NULL;

	xrows = height;
	xwidth = width;

	RAM_1 = (uint8_t*) calloc(0x188, 1);
	RAM_2 = (uint8_t*) calloc(0x188, 1);

	for(i = 0; i < xrows * xwidth * 8; i++)
	{
		RAM_1[i] = data[(i << 1)];
		RAM_2[i] = data[(i << 1) | 1];
	}

	for(mode = 1; mode < 4; mode++)
	{
		for(order = 0; order < 2; order++)
		{
			if(!(mode == 1 && order == 0))
			{
				newsize = interpret_compress(RAM_1, RAM_2, mode, order);
				if(size == -1 || newsize < size)
				{
					if(current != NULL)
					{
						free(current);
					}
					current = (uint8_t*) calloc(0x310, 1);
					memcpy(current, compressed, newsize / 8);
					free(compressed);
					size = newsize;
				}
			}
		}
	}
	compressed = (uint8_t*) calloc(0x310, 1);
	compressedsize = size / 8;
	memcpy(compressed, current, compressedsize);
	free(current);

	free(RAM_1);
	free(RAM_2);

	return compressedsize;
}

int main(int argc, char *argv[])
{
	int i;
	FILE *f;
	int fz;
	int size;
	uint8_t *contents;
	int tiles;
	int *chloc;
	char outfile[256];

	if(argc < 2)
	{
		fputs("Usage: pkmncompress infile.2bpp [infile.2bpp ...]\n", stderr);
		return EXIT_FAILURE;
	}

	for(i = 1; i < argc; i++)
	{
		strcpy(outfile, argv[i]);
		if((chloc = (int *) strrchr(outfile, '.')) != NULL)
		{
			strcpy((char *) chloc, ".pic");
		}
		else
		{
			strcat(outfile, ".pic");
		}

		f = fopen(argv[i], "rb");

		if(!f)
		{
			perror("Opening file failed");
			return EXIT_FAILURE;
		}

		fseek(f, 0, SEEK_END);
		fz = ftell(f);
		if(fz == 0x310)
		{
			tiles = 7;
		}
		else if(fz == 0x240)
		{
			tiles = 6;
		}
		else if(fz == 0x190)
		{
			tiles = 5;
		}
		else if(fz == 0x100)
		{
			tiles = 4;
		}
		else
		{
			fputs("Error: wrong file size.\n", stderr);
			return EXIT_FAILURE;
		}

		contents = (uint8_t*) calloc(0x310, 1);
		fseek(f, 0, SEEK_SET);
		fread(contents, 1, fz, f);
		fclose(f);

		size = compress(contents, tiles, tiles);

		free(contents);

		f = fopen(outfile, "wb");
		fwrite(compressed, 1, size, f);

		free(compressed);

		//printf("Success! File size: %i bytes\n", size);
	}

	return EXIT_SUCCESS;
}

@yenatch
Copy link
Contributor Author

yenatch commented Mar 11, 2018

fixed by #177

@yenatch yenatch closed this as completed Mar 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants