News:

11 March 2016 - Forum Rules

Main Menu

C++ RLE Compression/DeCompression routine

Started by Pikachumanson, November 26, 2012, 06:22:46 PM

Previous topic - Next topic

Pikachumanson

I originally was going to ask this question on nesdev but I didn't know the answer to their registration question. What the hell is the name of the NES DANCE PAD? :o

Anyway I was studying up on RLE and I wrote a program in C++ to compress and decompress rle strings in file. Note, my experience in programming comes from making games on the PC and college work. I am not sure how to implement this on a NES rom. Are there any improvement or things you would do to implement this in a NES rom?

I wanted to write the C++ routine first and mess around with the asm later. Write now I'm just interested in seeing the title screen graphics of the game I am working on.


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

int rle_comp( FILE *src, FILE *dest )     //Compression routine
{
int prev = 0;
int cur = 0;
int run = 1;
unsigned char count;

for ( count = 0; run; ++count )
{
if ( ( cur = getc( src ) ) == EOF )
run = 0;
if ( ( ( cur != prev || !run ) && count )
|| ( count == UCHAR_MAX ) )
{
if ( fwrite( &count, sizeof count, 1, dest ) != 1
|| putc( prev, dest ) == EOF )
run = 0;
count = 0;
}
prev = cur;
}
return ferror( src ) || ferror( dest );
}

int rle_decomp( FILE *src, FILE *dest )     //decompression routine
{
int cur = 0;
unsigned char count = 0;

while( fread( &count, sizeof count, 1, src ) == 1
&& ( cur = getc( src ) ) != EOF )
while( count-- != 0 )
putc( cur, dest );

return ferror( src ) || ferror( dest );
}

int main( int argc, char *argv[] )
{
FILE *src, *dest;   //file data

if( argc == 4 )
{
src = fopen( argv[2], "rb" );    //if error print message
if( src == NULL )
{
fprintf(stderr, "error: %s can't be opened\n", argv[2]);
exit(EXIT_FAILURE);
}

dest = fopen( argv[3], "wb" );
if( dest == NULL )
{
fclose( src );
fprintf(stderr, "error: %s can't be opened\n", argv[3]);
exit(EXIT_FAILURE);
}

if( strcmp( argv[1], "--comp") == 0 )
{
if ( rle_comp( src, dest ) != 0 )
fprintf( stderr,
"error: I/O failure during compression\n" );
}
else if ( strcmp( argv[1], "--decomp" ) == 0 )
{
if ( rle_decomp( src, dest ) != 0 )
fprintf( stderr,
"error: I/O failure during decompression\n" );
}
else
fprintf(stderr, "error: unknown option %s\n", argv[1]);  //if you type something other than comp or decomp

fclose( src );      //close files
fclose( dest );
}
else
printf( "usage: hexdump OPTION <src-file> <dest-file>\n"  //What we see in the output screen
"\nwhere OPTION is mandatory:\n"
" --comp perform rle compression on src-file\n"
" --decomp decompress src-file into dest-file\n");

return 0;
}

LostTemplar

You should probably put that in code tags (with proper indentation), it's very hard to read. Or use something like Pastebin for syntax highlighting.

Other than that, you have to seek to the position in the NES ROM from which you want to start decompressing. Also, you have to figure out what kind of RLE your game is using. It might not always be count, value, count, value, ..., but there might be a special byte code marking RLE encoded data. Last but not least, you have to know when to stop decompressing. For compression, it's the same, just the other way around (though you usually know the length of your data by looking at the input file's size).

Pikachumanson

Sorry about that. I modified my first post. Sigh... It seems I have my work cut out for me then. Thanks for your answer LostTemplar. Luckily I know where the data I want is located but I have no idea about the so called "special byte". Oh well, back to the drawing board. I am going to solve this problem eventually.

snarfblam

Quote from: Pikachumanson on November 26, 2012, 06:22:46 PMWhat the hell is the name of the NES DANCE PAD? :o

Come on, now. Didn't you have a Power Pad as a kid? I had one. I think I used it exactly once.

Pikachumanson

I put that and it wouldn't go through. I'll try again later. I'm really diggin' that site.

KingMike

Or Family Trainer or Family Fun Fitness, depending on your region.
"My watch says 30 chickens" Google, 2018