Initial commit
This commit is contained in:
commit
1d7a13e2c5
72 changed files with 21402 additions and 0 deletions
8
Makefile
Normal file
8
Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
include config.mak
|
||||
|
||||
OUTPUT = $(PROG)
|
||||
CC = g++
|
||||
LD = $(CC)
|
||||
AR = ar
|
||||
|
||||
include build.mak
|
8
Makefile.mingw
Normal file
8
Makefile.mingw
Normal file
|
@ -0,0 +1,8 @@
|
|||
include config.mak
|
||||
|
||||
OUTPUT = $(PROG).exe
|
||||
CC = /opt/cross/bin/i386-mingw32msvc-g++
|
||||
LD = $(CC)
|
||||
AR = /opt/cross/bin/i386-mingw32msvc-ar
|
||||
|
||||
include build.mak
|
33
blocks.cpp
Normal file
33
blocks.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "blocks.h"
|
||||
#include <string.h>
|
||||
|
||||
Frame* Block::getFrame( int index ) { return index >= 0 && index < 64 ? &frames[index] : 0; }
|
||||
|
||||
IdentificationFrame* DirectoryBlock::IDFrame() { return (IdentificationFrame*)&frames[0]; }
|
||||
DirectoryFrame* DirectoryBlock::Directory( int index ) { return index < 15 && index >= 0 ? (DirectoryFrame*)&frames[index + 1] : 0; }
|
||||
void DirectoryBlock::Directory( int index, DirectoryFrame *frame ) { memcpy( &frames[index], frame, sizeof( DirectoryFrame ) ); }
|
||||
Frame* DirectoryBlock::Reserved( int index ) { return index < 20 && index >= 0 ? &frames[index + 16] : 0; }
|
||||
Frame* DirectoryBlock::Unused( int index ) { return index < 27 && index >= 0 ? &frames[index + 36] : 0; }
|
||||
Frame* DirectoryBlock::WriteTest() { return &frames[63]; }
|
||||
int DirectoryBlock::nextOpenBlock() {
|
||||
for( int i = 0; i < 15; i++ ) {
|
||||
int type = Directory( i )->blockType();
|
||||
if( type >= 160 && type <= 163 ) { return i + 1; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
SaveHeaderFrame* InitialBlock::Header() { return (SaveHeaderFrame*)&frames[0]; }
|
||||
Icon* InitialBlock::getIcon( int index ) {
|
||||
//return index < 3 && index >= 0 ? &frames[index + 1] : 0;
|
||||
SaveHeaderFrame *header = Header();
|
||||
IconFrame *frame = (IconFrame*)&frames[index + 1];
|
||||
Icon *icon = new Icon();
|
||||
for( int y = 0; y < 16; y++ ) {
|
||||
icon->paletteColor( y, header->paletteColor( y ) );
|
||||
for( int x = 0; x < 16; x++ ) {
|
||||
icon->pixel( x, y, frame->colorAt( x, y ) );
|
||||
}
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
40
blocks.h
Normal file
40
blocks.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef BLOCKS_H
|
||||
#define BLOCKS_H
|
||||
|
||||
#include "frames.h"
|
||||
|
||||
class Block {
|
||||
protected:
|
||||
Frame frames[64];
|
||||
public:
|
||||
Frame* getFrame( int index );
|
||||
enum blockType {
|
||||
PSX_BLOCK_INITIAL = 81,
|
||||
PSX_BLOCK_MEDIAL = 82,
|
||||
PSX_BLOCK_FINAL = 83,
|
||||
PSX_BLOCK_FORMATTED = 160,
|
||||
PSX_BLOCK_DELETED_INITIAL = 161,
|
||||
PSX_BLOCK_DELETED_MEDIAL = 162,
|
||||
PSX_BLOCK_DELETED_FINAL = 163,
|
||||
PSX_BLOCK_RESERVED = 0xFFFFFFFF
|
||||
};
|
||||
};
|
||||
|
||||
class DirectoryBlock : protected Block {
|
||||
public:
|
||||
IdentificationFrame* IDFrame();
|
||||
DirectoryFrame* Directory( int index );
|
||||
void Directory( int index, DirectoryFrame *frame );
|
||||
Frame* Reserved( int index );
|
||||
Frame* Unused( int index );
|
||||
Frame* WriteTest();
|
||||
int nextOpenBlock();
|
||||
};
|
||||
|
||||
class InitialBlock : protected Block {
|
||||
public:
|
||||
SaveHeaderFrame* Header();
|
||||
Icon* getIcon( int index );
|
||||
};
|
||||
|
||||
#endif // BLOCKS_H
|
43
build.mak
Normal file
43
build.mak
Normal file
|
@ -0,0 +1,43 @@
|
|||
CFLAGS = -g -Wall
|
||||
LDFLAGS = -L.
|
||||
|
||||
LIBVERSIONMAJOR = 0
|
||||
LIBVERSIONMINOR = 0.1
|
||||
|
||||
OBJS = blocks.o \
|
||||
frames.o \
|
||||
memcard.o \
|
||||
icon.o
|
||||
|
||||
.PHONY: clean lib-static static lib-shared shared qtdir
|
||||
|
||||
all: clean static
|
||||
qt: clean lib-shared qtdir
|
||||
|
||||
qtdir:
|
||||
make -C qt-test-cli clean all
|
||||
|
||||
clean:
|
||||
rm -f *.o *.a *.so* $(OUTPUT)
|
||||
|
||||
lib-static: $(OBJS)
|
||||
$(AR) rcs lib$(LIB).a $(OBJS)
|
||||
|
||||
lib-shared: $(OBJS)
|
||||
ifeq ($(CC),g++)
|
||||
$(LD) -shared -Wl,-soname,lib$(LIB).so.$(LIBVERSIONMAJOR) -o lib$(LIB).so.$(LIBVERSIONMAJOR).$(LIBVERSIONMINOR) $(OBJS)
|
||||
ln -fs lib$(LIB).so.$(LIBVERSIONMAJOR).$(LIBVERSIONMINOR) lib$(LIB).so.$(LIBVERSIONMAJOR)
|
||||
ln -fs lib$(LIB).so.$(LIBVERSIONMAJOR).$(LIBVERSIONMINOR) lib$(LIB).so
|
||||
else
|
||||
$(LD) -shared -Wl,-soname,lib$(LIB).so.$(LIBVERSIONMAJOR) -o lib$(LIB).dll $(OBJS)
|
||||
endif
|
||||
|
||||
static: lib-static
|
||||
$(LD) $(LDFLAGS) -static $(PROG).cpp -l$(LIB) -o $(OUTPUT)
|
||||
|
||||
shared: lib-shared $(PROG).o
|
||||
$(LD) $(LDFLAGS) -l$(LIB) $(PROG).o -o $(OUTPUT)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
4
config.mak
Normal file
4
config.mak
Normal file
|
@ -0,0 +1,4 @@
|
|||
PROG = test
|
||||
LIB = psxsave
|
||||
LIBVERSIONMAJOR = 0
|
||||
LIBVERSIONMINOR = 0.1
|
1
db
Symbolic link
1
db
Symbolic link
|
@ -0,0 +1 @@
|
|||
testdata/db
|
75
frames.cpp
Normal file
75
frames.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "frames.h"
|
||||
#include <string.h>
|
||||
|
||||
char* Frame::getString( int offset, int length ) {
|
||||
char* data = new char[length];
|
||||
strncpy( data, &bytes[offset], length );
|
||||
data[length] = 0; // Properly terminate the returned string
|
||||
return data;
|
||||
}
|
||||
|
||||
int Frame::getInt32( int offset ) {
|
||||
return *reinterpret_cast<int*>( &bytes[offset] );
|
||||
}
|
||||
int Frame::getInt16( int offset ) {
|
||||
return *reinterpret_cast<short int*>( &bytes[offset] );
|
||||
}
|
||||
void Frame::putInt32( int offset, int value ) {
|
||||
for( int i = 0; i < 4; i++ ) {
|
||||
bytes[offset + i] = ( value & ( 0xFF << ( 8 * i ) ) ) >> ( 8 * i );
|
||||
}
|
||||
}
|
||||
void Frame::putInt16( int offset, int value ) {
|
||||
for( int i = 0; i < 2; i++ ) {
|
||||
bytes[offset + i] = ( value & ( 0xFF << ( 8 * i ) ) ) >> ( 8 * i );
|
||||
}
|
||||
}
|
||||
void Frame::putString( int offset, char* value, int maxLen ) {
|
||||
maxLen = maxLen < 0 ? strlen( value ) : 0;
|
||||
maxLen = (unsigned int)maxLen > strlen( value ) ? strlen( value ) : 0;
|
||||
strncpy( &bytes[offset], value, maxLen );
|
||||
//bytes[offset+maxLen] = 0;
|
||||
}
|
||||
void Frame::putChar( int offset, char value ) {
|
||||
bytes[offset] = value;
|
||||
}
|
||||
|
||||
bool XORFrame::getXOR() {
|
||||
char x = 0;
|
||||
for( int i = 0; i < 128; i++ ) x ^= bytes[i];
|
||||
if( x == 0 ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void XORFrame::setXOR() {
|
||||
char x = 0;
|
||||
for( int i = 0; i < 127; i++ ) x ^= bytes[i];
|
||||
bytes[127] = x;
|
||||
}
|
||||
|
||||
bool IdentificationFrame::isValid() {
|
||||
if( strcmp( id(), "MC" ) == 0 ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RGB SaveHeaderFrame::paletteColor( int index ) {
|
||||
index = index < 0 || index >= 16 ? 0 : index;
|
||||
char triplet[2] = { bytes[0x60 + ( index * 2 )], bytes[0x60 + ( index * 2 + 1 )] };
|
||||
RGB color;
|
||||
color.r = ( triplet[0] & 31 ) << 3;
|
||||
color.g = ( ( triplet[0] & 224 ) >> 2 ) + ( ( triplet[1] & 3 ) << 6 );
|
||||
color.b = ( triplet[1] & 124 ) << 1;
|
||||
return color;
|
||||
}
|
||||
|
||||
int IconFrame::colorAt( int x, int y ) {
|
||||
int offset = x / 2;
|
||||
if( x % 2 == 0 ) {
|
||||
return bytes[(y*8)+offset] & 15;
|
||||
} else {
|
||||
return ( bytes[(y*8)+offset] & 240 ) >> 4;
|
||||
}
|
||||
}
|
60
frames.h
Normal file
60
frames.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef FRAMES_H
|
||||
#define FRAMES_H
|
||||
|
||||
#include "icon.h"
|
||||
|
||||
class Frame {
|
||||
protected:
|
||||
char bytes[128];
|
||||
public:
|
||||
char* getData( int offset ) { return &bytes[offset]; }
|
||||
char* getString( int offset, int length );
|
||||
int getInt32( int offset );
|
||||
int getInt16( int offset );
|
||||
void putInt32( int offset, int value );
|
||||
void putInt16( int offset, int value );
|
||||
void putString( int offset, char* value, int maxLen = -1 );
|
||||
void putChar( int offset, char value );
|
||||
};
|
||||
|
||||
class XORFrame : protected Frame {
|
||||
public:
|
||||
bool getXOR();
|
||||
void setXOR();
|
||||
};
|
||||
|
||||
class IdentificationFrame : public XORFrame {
|
||||
public:
|
||||
// I might put a byte-for-byte check here for safety and completeness, but the XOR is fine for now.
|
||||
char* id() { return getString( 0x00, 2 ); }
|
||||
bool isValid();
|
||||
};
|
||||
|
||||
class DirectoryFrame : public XORFrame {
|
||||
public:
|
||||
int blockType() { return getInt32( 0x00 ); }
|
||||
void blockType( int value ) { putInt32( 0x00, value ); }
|
||||
int size() { return getInt32( 0x04 ); }
|
||||
void size( int size ) { putInt32( 0x04, size ); }
|
||||
int nextBlock() { return getInt16( 0x08 ); }
|
||||
char* territoryCode() { return getString( 0x0A, 2 ); }
|
||||
char* licenseCode() { return getString( 0x0C, 10 ); }
|
||||
char* saveCode() { return getString( 0x16, 8 ); }
|
||||
|
||||
};
|
||||
|
||||
class SaveHeaderFrame : protected Frame {
|
||||
public:
|
||||
char* magicNumber() { return getString( 0x00, 2 ); }
|
||||
int iconDisplayType() { return bytes[0x02]; }
|
||||
int blocksUsed() { return bytes[0x03]; }
|
||||
char* SJISSaveTitle() { return getString( 0x04, 64 ); }
|
||||
RGB paletteColor( int index );
|
||||
};
|
||||
|
||||
class IconFrame : protected Frame {
|
||||
public:
|
||||
int colorAt( int x, int y );
|
||||
};
|
||||
|
||||
#endif // FRAMES_H
|
80
icon.cpp
Normal file
80
icon.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
#include "icon.h"
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Icon::Icon() {
|
||||
for( int x = 0; x < 16; x++ ) {
|
||||
palette[x] = RGB();
|
||||
for( int y = 0; y < 16; y++ ) {
|
||||
pixels[x][y] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Icon::pixel( int x, int y ) {
|
||||
x = x < 0 || x >= 16 ? 0 : x;
|
||||
y = y < 0 || y >= 16 ? 0 : y;
|
||||
return pixels[x][y];
|
||||
}
|
||||
|
||||
RGB Icon::pixelRGB( int x, int y ) {
|
||||
x = x < 0 || x >= 16 ? 0 : x;
|
||||
y = y < 0 || y >= 16 ? 0 : y;
|
||||
return paletteColor( pixels[x][y] );
|
||||
}
|
||||
|
||||
void Icon::pixel( int x, int y, int colorIndex ) {
|
||||
x = x < 0 || x >= 16 ? 0 : x;
|
||||
y = y < 0 || y >= 16 ? 0 : y;
|
||||
pixels[x][y] = colorIndex;
|
||||
}
|
||||
|
||||
RGB Icon::paletteColor( int index ) {
|
||||
index = index < 0 || index >= 16 ? 0 : index;
|
||||
return palette[index];
|
||||
}
|
||||
|
||||
void Icon::paletteColor( int index, RGB color ) {
|
||||
index = index < 0 || index >= 16 ? 0 : index;
|
||||
palette[index] = color;
|
||||
}
|
||||
|
||||
bool Icon::exportXPM( char* fileName ) {
|
||||
FILE *xpm = fopen( fileName, "w" );
|
||||
if( xpm < 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf( xpm, "/* XPM */\n" );
|
||||
fprintf( xpm, "static char *psx[] = {\n" );
|
||||
fprintf( xpm, "/* columns rows colors chars-per-pixel */\n" );
|
||||
fprintf( xpm, "\"16 16 16 1\",\n" );
|
||||
|
||||
// Palette Conversion
|
||||
|
||||
char paletteXPM[17] = " .XoO+@#$%&*=-;:";
|
||||
for( int i = 0; i < 16; i++ ) {
|
||||
RGB col = paletteColor( i );
|
||||
fprintf( xpm, "\"%c c #%.2x%.2x%.2x\",\n", paletteXPM[i], col.r, col.g, col.b );
|
||||
}
|
||||
|
||||
fprintf( xpm, "/* pixels */\n" );
|
||||
|
||||
// Pixel Conversion
|
||||
|
||||
for( int y = 0; y < 16; y++ ) {
|
||||
fprintf( xpm, "\"" );
|
||||
for( int x = 0; x < 16; x++ ) {
|
||||
fprintf( xpm, "%c", paletteXPM[ pixel( x, y ) ] );
|
||||
}
|
||||
if( y < 15 ) {
|
||||
fprintf( xpm, "\",\n" );
|
||||
} else {
|
||||
fprintf( xpm, "\"\n}" );
|
||||
}
|
||||
}
|
||||
|
||||
fclose( xpm );
|
||||
return true;
|
||||
}
|
27
icon.h
Normal file
27
icon.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef ICON_H
|
||||
#define ICON_H
|
||||
|
||||
struct RGB {
|
||||
int r;
|
||||
int g;
|
||||
int b;
|
||||
RGB( int r = 0, int g = 0, int b = 0 ) { this->r = r; this->g = g; this->b = b; }
|
||||
};
|
||||
|
||||
class Icon {
|
||||
private:
|
||||
char pixels[16][16];
|
||||
RGB palette[16];
|
||||
public:
|
||||
Icon();
|
||||
int pixel( int x, int y );
|
||||
RGB pixelRGB( int x, int y );
|
||||
void pixel( int x, int y, int colorIndex );
|
||||
RGB paletteColor( int index );
|
||||
void paletteColor( int index, RGB color );
|
||||
|
||||
bool exportXPM( char* fileName );
|
||||
};
|
||||
|
||||
#endif // ICON_H
|
||||
|
120
memcard.cpp
Normal file
120
memcard.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "memcard.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
MemoryCard::MemoryCard() {
|
||||
for( int i = 0; i < 16; i++ ) {
|
||||
this->blocks[i] = new Block();
|
||||
}
|
||||
}
|
||||
|
||||
bool MemoryCard::loadFile( char *fileName ) {
|
||||
fstream file;
|
||||
file.open( fileName, ios::in | ios::binary );
|
||||
if( !file.is_open() ) {
|
||||
cout << "'" << fileName << "' could not be opened for input, exiting.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int i = 0; i < 16; i++ ) {
|
||||
/*
|
||||
blocks[i] = new Block();
|
||||
file.read( reinterpret_cast<char*>( blocks[i] ), sizeof( Block ) );
|
||||
if( file.gcount() != sizeof( Block ) ) {
|
||||
cout << "Error reading block " << i << ", read count less than initial block size\n";
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
this->loadBlockFromFile( fileName, i );
|
||||
}
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemoryCard::loadBlockFromFile( char *fileName, int srcBlock, int dstBlock, int offset ) {
|
||||
srcBlock = srcBlock > 15 || srcBlock < 0 ? 0 : srcBlock;
|
||||
dstBlock = dstBlock > 15 || dstBlock < 0 ? srcBlock : dstBlock;
|
||||
fstream file;
|
||||
file.open( fileName, ios::in | ios::binary );
|
||||
if( !file.is_open() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file.seekg( srcBlock * sizeof( Block ) + offset );
|
||||
this->blocks[dstBlock] = new Block();
|
||||
file.read( reinterpret_cast<char*>( this->blocks[dstBlock] ), sizeof( Block ) );
|
||||
if( file.gcount() != sizeof( Block ) ) {
|
||||
cout << "Error reading block " << srcBlock << ", read count less than initial block size\n";
|
||||
return false;
|
||||
}
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemoryCard::loadMCS( char* fileName, int dstBlock ) {
|
||||
if( dstBlock <= 0 ) {
|
||||
dstBlock = this->directory()->nextOpenBlock();
|
||||
if( dstBlock <= 0 ) { return false; }
|
||||
}
|
||||
fstream file;
|
||||
file.open( fileName, ios::in | ios::binary );
|
||||
if( !file.is_open() ) {
|
||||
return false;
|
||||
}
|
||||
DirectoryFrame *dirEntry = new DirectoryFrame();
|
||||
file.read( reinterpret_cast<char*>( dirEntry ), sizeof( DirectoryFrame ) );
|
||||
file.close();
|
||||
|
||||
if( file.gcount() == sizeof( DirectoryFrame ) ) {
|
||||
this->loadBlockFromFile( fileName, 0, dstBlock, sizeof( DirectoryFrame ) );
|
||||
this->directory()->Directory( dstBlock, dirEntry );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemoryCard::saveFile( char* fileName, fileFormatCard format ) {
|
||||
fstream file;
|
||||
file.open( fileName, ios::out | ios::binary );
|
||||
if( !file.is_open() ) {
|
||||
return false;
|
||||
}
|
||||
switch( format ) {
|
||||
case FORMAT_RAW:
|
||||
default:
|
||||
for( int i = 0; i < 16; i++ ) {
|
||||
file.write( reinterpret_cast<char*>( blocks[i] ), sizeof( Block ) );
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemoryCard::saveBlockToFile( char* fileName, int block, fileFormatSingle format ) {
|
||||
fstream file;
|
||||
file.open( fileName, ios::out | ios::binary );
|
||||
if( !file.is_open() ) {
|
||||
return false;
|
||||
}
|
||||
switch( format ) {
|
||||
case FORMAT_MCS:
|
||||
default:
|
||||
file.write( reinterpret_cast<char*>( directory()->Directory( block - 1 ) ), sizeof( Frame ) );
|
||||
file.write( reinterpret_cast<char*>( blocks[block] ), sizeof( Block ) );
|
||||
break;
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
Block* MemoryCard::getBlock( int index = 0 ) {
|
||||
index = index > 15 || index < 0 ? 0 : index;
|
||||
return blocks[index];
|
||||
}
|
||||
|
||||
DirectoryBlock* MemoryCard::directory() {
|
||||
return (DirectoryBlock*)this->blocks[0];
|
||||
}
|
28
memcard.h
Normal file
28
memcard.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef MEMCARD_H
|
||||
#define MEMCARD_H
|
||||
|
||||
#include "blocks.h"
|
||||
|
||||
class MemoryCard {
|
||||
private:
|
||||
Block *blocks[16];
|
||||
public:
|
||||
MemoryCard();
|
||||
|
||||
enum fileFormatCard {
|
||||
FORMAT_RAW
|
||||
};
|
||||
enum fileFormatSingle {
|
||||
FORMAT_MCS
|
||||
};
|
||||
|
||||
bool loadFile( char* fileName );
|
||||
bool loadBlockFromFile( char *fileName, int srcBlock, int dstBlock = -1, int offset = 0 );
|
||||
bool loadMCS( char* fileName, int dstBlock = -1 );
|
||||
bool saveFile( char* fileName, fileFormatCard format = FORMAT_RAW );
|
||||
bool saveBlockToFile( char *fileName, int block, fileFormatSingle format = FORMAT_MCS );
|
||||
Block* getBlock( int index );
|
||||
DirectoryBlock* directory();
|
||||
};
|
||||
|
||||
#endif // MEMCARD_H
|
92
psxicontool.cpp
Normal file
92
psxicontool.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
#include "psxicontool.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
PSXIconTool::PSXIconTool() {
|
||||
this->error[0] = 0;
|
||||
}
|
||||
|
||||
bool PSXIconTool::loadMCS( char* filename ) {
|
||||
fstream savefile;
|
||||
savefile.open( filename, ios::in );
|
||||
if( !savefile.is_open() ) {
|
||||
sprintf( this->error, "Unable to open file \"%s\" for reading", filename );
|
||||
return false;
|
||||
}
|
||||
savefile.read( reinterpret_cast<char*>( &PSX_Save ), sizeof( _PSX_Save ) );
|
||||
savefile.close();
|
||||
|
||||
// Convert icon data
|
||||
|
||||
for( int i = 0; i < 16; i++ ) {
|
||||
icon.palette[i].red = ( PSX_Save.save_header.palette[i][0] & 31 ) << 3;
|
||||
icon.palette[i].green = ( ( PSX_Save.save_header.palette[i][0] & 224 ) >> 2 ) + ( ( PSX_Save.save_header.palette[i][1] & 3 ) << 6 );
|
||||
icon.palette[i].blue = ( PSX_Save.save_header.palette[i][1] & 124 ) << 1;
|
||||
}
|
||||
for( int y = 0; y < 16; y++ ) {
|
||||
for( int x = 0; x < 8; x++ ) {
|
||||
icon.pixels[y][x * 2] = PSX_Save.save_header.icons[0][y][x] & 15;
|
||||
icon.pixels[y][x * 2 + 1] = ( PSX_Save.save_header.icons[0][y][x] & 240 ) >> 4;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool PSXIconTool::exportXPM( char* filename ) {
|
||||
FILE *xpm = fopen( filename, "w" );
|
||||
if( xpm < 0 ) {
|
||||
sprintf( this->error, "Unable to open file \"%s\" for writing", filename );
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf( xpm, "/* XPM */\n" );
|
||||
fprintf( xpm, "static char *psx[] = {\n" );
|
||||
fprintf( xpm, "/* columns rows colors chars-per-pixel */\n" );
|
||||
fprintf( xpm, "\"16 16 16 1\",\n" );
|
||||
|
||||
// Palette Conversion
|
||||
|
||||
char palette[17] = " .XoO+@#$%&*=-;:";
|
||||
for( int i = 0; i < 16; i++ ) {
|
||||
fprintf( xpm, "\"%c c #%.2x%.2x%.2x\",\n", palette[i], icon.palette[i].red, icon.palette[i].green, icon.palette[i].blue );
|
||||
}
|
||||
|
||||
fprintf( xpm, "/* pixels */\n" );
|
||||
|
||||
// Pixel Conversion
|
||||
|
||||
for( int y = 0; y < 16; y++ ) {
|
||||
fprintf( xpm, "\"" );
|
||||
for( int x = 0; x < 16; x++ ) {
|
||||
fprintf( xpm, "%c", palette[ icon.pixels[y][x] ] );
|
||||
}
|
||||
if( y < 15 ) {
|
||||
fprintf( xpm, "\",\n" );
|
||||
} else {
|
||||
fprintf( xpm, "\"\n}" );
|
||||
}
|
||||
}
|
||||
|
||||
fclose( xpm );
|
||||
return true;
|
||||
}
|
||||
|
||||
char* PSXIconTool::errorMessage() {
|
||||
return error;
|
||||
}
|
||||
|
||||
void PSXIconTool::printInfo() {
|
||||
char* var;
|
||||
|
||||
printf( "Block Type: %d\n", PSX_Save.block_header.block_type );
|
||||
printf( "Save Size: %d\n", PSX_Save.block_header.save_size );
|
||||
printf( "Next Block: %d\n", PSX_Save.block_header.next_block );
|
||||
strncpy( var, PSX_Save.block_header.territory_code, 2 ); var[2] = 0;
|
||||
printf( "Territory Code: %s\n", var );
|
||||
strncpy( var, PSX_Save.block_header.license_code, 10 ); var[10] = 0;
|
||||
printf( "License Code: %s\n", var );
|
||||
strncpy( var, PSX_Save.block_header.save_code, 8 ); var[8] = 0;
|
||||
printf( "Save Code: %s\n", var );
|
||||
}
|
81
psxicontool.h
Normal file
81
psxicontool.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
|
||||
/**
|
||||
Stores the header data from the first block of
|
||||
playstation save data
|
||||
*/
|
||||
struct PSX_Save_Block_Header {
|
||||
int block_type;
|
||||
int save_size;
|
||||
short next_block;
|
||||
char territory_code[2];
|
||||
char license_code[10];
|
||||
char save_code[8];
|
||||
char code_end;
|
||||
char unused[94];
|
||||
char xor_code;
|
||||
};
|
||||
|
||||
/**
|
||||
Stores the header data from the first frame of
|
||||
playstation save data
|
||||
*/
|
||||
struct PSX_Save_Header {
|
||||
char magic_number[2]; //!< "SC"
|
||||
char icon_display; //!< 17 - static (1 frame), 18 - animated (2 frames), 19 - animated (3 frames)
|
||||
char blocks_used;
|
||||
char sjis_save_title[64]; //!< Save title in Shift-JIS character set, kanji only
|
||||
char padding[28];
|
||||
char palette[16][2]; //!< Stored as BBBBBGGGGGRRRRR
|
||||
char icons[3][16][8]; //!< Three icons, sixteen rows of 8 bytes (4 bits per pixel)
|
||||
};
|
||||
|
||||
/**
|
||||
Structure for holding parsed icon data
|
||||
*/
|
||||
struct Icon {
|
||||
struct _RGB {
|
||||
int red;
|
||||
int blue;
|
||||
int green;
|
||||
};
|
||||
_RGB palette[16];
|
||||
char pixels[16][16];
|
||||
};
|
||||
|
||||
|
||||
class PSXIconTool {
|
||||
private:
|
||||
struct _PSX_Save {
|
||||
PSX_Save_Block_Header block_header;
|
||||
PSX_Save_Header save_header;
|
||||
} PSX_Save;
|
||||
Icon icon;
|
||||
char error[2048];
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/** Constructor */
|
||||
PSXIconTool();
|
||||
|
||||
/**
|
||||
* Load an MCS file (raw block data for a single playstation save file)
|
||||
* @param filename
|
||||
* @return True on success, False on failure.
|
||||
* Use errorMessage() to determine the error that occurred upon failure.
|
||||
*/
|
||||
bool loadMCS( char* filename );
|
||||
|
||||
bool exportXPM( char* filename );
|
||||
bool exportPCX( char* filename );
|
||||
|
||||
Icon *getIcon() { return &icon; }
|
||||
|
||||
void printInfo();
|
||||
/**
|
||||
*
|
||||
* @return The message from the last error to occur.
|
||||
*/
|
||||
char* errorMessage();
|
||||
};
|
||||
|
BIN
qt-gui/BA.png
Normal file
BIN
qt-gui/BA.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 252 B |
BIN
qt-gui/BE.png
Normal file
BIN
qt-gui/BE.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 284 B |
BIN
qt-gui/BJ.png
Normal file
BIN
qt-gui/BJ.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 248 B |
50
qt-gui/main.cpp
Normal file
50
qt-gui/main.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include <QtGui>
|
||||
#include <iostream>
|
||||
|
||||
#include "psxsavewidget.h"
|
||||
#include "memcard.h"
|
||||
#include "psxmemcard.h"
|
||||
|
||||
int main( int argc, char *argv[] ) {
|
||||
QApplication app( argc, argv );
|
||||
|
||||
MemoryCard *memCard = new MemoryCard();
|
||||
if( argc > 1 ) {
|
||||
memCard->loadFile( argv[1] );
|
||||
if( argc > 2 ) {
|
||||
for( int i = 2; i < argc; i++ ) {
|
||||
memCard->loadMCS( argv[i] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::cout << "No filename provided, exiting.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
QMap<QString, QString> games;
|
||||
QWidget *mainWidget = new QWidget;
|
||||
QVBoxLayout *vlayout = new QVBoxLayout;
|
||||
QHBoxLayout *hlayout = new QHBoxLayout;
|
||||
|
||||
PSXMemoryCardModel *memCardModel = new PSXMemoryCardModel( memCard );
|
||||
QTreeView *tv = new QTreeView();
|
||||
tv->setModel( memCardModel );
|
||||
tv->setColumnHidden( 0, true );
|
||||
for( int i = 1; i < 5; i++ ) tv->resizeColumnToContents( i );
|
||||
vlayout->addWidget( tv );
|
||||
|
||||
QWidget *listContainer = new QWidget;
|
||||
listContainer->setLayout( vlayout );
|
||||
hlayout->addWidget( listContainer );
|
||||
PSXSaveWidget *saveWidget = new PSXSaveWidget( memCard );
|
||||
hlayout->addWidget( saveWidget );
|
||||
|
||||
QObject::connect(
|
||||
tv, SIGNAL( clicked( const QModelIndex & ) ),
|
||||
saveWidget, SLOT( setBlockFromModel( const QModelIndex & ) ) );
|
||||
|
||||
mainWidget->setLayout( hlayout );
|
||||
mainWidget->resize( 900, 400 );
|
||||
mainWidget->show();
|
||||
return app.exec();
|
||||
}
|
31
qt-gui/psxicon.cpp
Normal file
31
qt-gui/psxicon.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "psxicon.h"
|
||||
#include <QPainter>
|
||||
|
||||
PSXIcon::PSXIcon( Icon *icon, QWidget *parent ) : QWidget( parent ) {
|
||||
this->icon = icon;
|
||||
setFixedSize( 64, 64 );
|
||||
}
|
||||
|
||||
void PSXIcon::setIcon( Icon *icon ) {
|
||||
this->icon = icon;
|
||||
}
|
||||
|
||||
void PSXIcon::paintEvent( QPaintEvent *event ) {
|
||||
QImage image( 16, 16, QImage::Format_Indexed8 );
|
||||
image.setNumColors( 16 );
|
||||
for( int i = 0; i < 16; i++ ) {
|
||||
RGB col = this->icon->paletteColor( i );
|
||||
QRgb rgb = QColor::fromRgb( col.r, col.g, col.b ).rgb();
|
||||
image.setColor( i, rgb );
|
||||
}
|
||||
for( int x = 0; x < 16; x++ ) {
|
||||
for( int y = 0; y < 16; y++ ) {
|
||||
image.setPixel( x, y, icon->pixel( x, y ) );
|
||||
}
|
||||
}
|
||||
QRectF target(0.0, 0.0, 64.0, 64.0);
|
||||
QRectF source(0.0, 0.0, 16.0, 16.0);
|
||||
QPainter painter( this );
|
||||
painter.drawImage(target, image, source);
|
||||
|
||||
}
|
12
qt-gui/psxicon.h
Normal file
12
qt-gui/psxicon.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <QWidget>
|
||||
#include "memcard.h"
|
||||
|
||||
class PSXIcon : public QWidget {
|
||||
private:
|
||||
Icon *icon;
|
||||
protected:
|
||||
void paintEvent( QPaintEvent *event );
|
||||
public:
|
||||
PSXIcon( Icon *icon, QWidget *parent = 0 );
|
||||
void setIcon( Icon *icon );
|
||||
};
|
108
qt-gui/psxmemcard.cpp
Normal file
108
qt-gui/psxmemcard.cpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include "psxmemcard.h"
|
||||
#include "psxicon.h"
|
||||
#include <QTextCodec>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
PSXMemoryCardModel::PSXMemoryCardModel( MemoryCard *memCard, QObject *parent ) : QAbstractTableModel( parent ) {
|
||||
this->memCard = memCard;
|
||||
for( int i = 1; i < 16; i++ ) {
|
||||
DirectoryFrame *directory = memCard->directory()->Directory( i - 1 );
|
||||
int type = directory->blockType();
|
||||
if( type == Block::PSX_BLOCK_INITIAL ) {
|
||||
this->blocks.append( memCard->getBlock( i ) );
|
||||
this->blockId.append( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int PSXMemoryCardModel::rowCount( const QModelIndex &parent ) const {
|
||||
if( parent.isValid() ) { return 0; }
|
||||
return this->blocks.count();
|
||||
}
|
||||
|
||||
int PSXMemoryCardModel::columnCount( const QModelIndex &parent ) const {
|
||||
if( parent.isValid() ) { return 0; }
|
||||
return 5;
|
||||
}
|
||||
|
||||
QVariant PSXMemoryCardModel::data( const QModelIndex & index, int role ) const {
|
||||
if( !index.isValid() ) { return QVariant(); }
|
||||
InitialBlock *block = (InitialBlock*)blocks[index.row()];
|
||||
|
||||
switch( index.column() ) {
|
||||
case 0:
|
||||
if( role != Qt::DisplayRole ) { return QVariant(); }
|
||||
return blockId[ index.row() ];
|
||||
case 1:
|
||||
if( role == Qt::DisplayRole ) {
|
||||
QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
|
||||
if( codec == 0 ) { return QVariant(); }
|
||||
return codec->toUnicode( block->Header()->SJISSaveTitle() );
|
||||
} else if ( role == Qt::DecorationRole ) {
|
||||
Icon *icon = block->getIcon( 0 );
|
||||
QImage image( 16, 16, QImage::Format_Indexed8 );
|
||||
image.setNumColors( 16 );
|
||||
for( int i = 0; i < 16; i++ ) {
|
||||
RGB col = icon->paletteColor( i );
|
||||
QRgb rgb = QColor::fromRgb( col.r, col.g, col.b ).rgb();
|
||||
image.setColor( i, rgb );
|
||||
}
|
||||
for( int x = 0; x < 16; x++ ) {
|
||||
for( int y = 0; y < 16; y++ ) {
|
||||
image.setPixel( x, y, icon->pixel( x, y ) );
|
||||
}
|
||||
}
|
||||
return QPixmap::fromImage( image );
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if( role == Qt::DisplayRole ) {
|
||||
return QString( this->memCard->directory()->Directory( blockId[ index.row() ] - 1 )->licenseCode() );
|
||||
} else if ( role == Qt::DecorationRole ) {
|
||||
QString image = QString( this->memCard->directory()->Directory( blockId[ index.row() ] - 1 )->territoryCode() );
|
||||
image.append( ".png" );
|
||||
return QPixmap::fromImage( QImage( image ) );
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
case 3:
|
||||
if( role != Qt::DisplayRole ) { return QVariant(); }
|
||||
return QString( this->memCard->directory()->Directory( blockId[ index.row() ] - 1 )->saveCode() );
|
||||
case 4:
|
||||
if( role != Qt::DisplayRole ) { return QVariant(); }
|
||||
return ( (InitialBlock*)blocks[ index.row() ] )->Header()->blocksUsed();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PSXMemoryCardModel::headerData( int section, Qt::Orientation orientation, int role ) const {
|
||||
if( role != Qt::DisplayRole ) { return QVariant(); }
|
||||
switch( section ) {
|
||||
case 0:
|
||||
return tr( "Id" );
|
||||
case 1:
|
||||
return tr( "Save Title" );
|
||||
case 2:
|
||||
return tr( "License Code" );
|
||||
case 3:
|
||||
return tr( "Save Code" );
|
||||
case 4:
|
||||
return tr( "Blocks" );
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QString unicodeToAscii( QString text ) {
|
||||
for( int i = 0xff01; i < 0xff5f; i++ ) {
|
||||
text.replace( QChar( i ), QChar( i - 0xff00 + 0x0020 ) );
|
||||
}
|
||||
for( int i = 0; i < text.length(); i++ ) {
|
||||
if( text[i].unicode() > 0x7f ) { text[i] = 0x5f; }
|
||||
}
|
||||
return text.toAscii();
|
||||
}
|
||||
|
18
qt-gui/psxmemcard.h
Normal file
18
qt-gui/psxmemcard.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <QListView>
|
||||
#include "memcard.h"
|
||||
|
||||
class PSXMemoryCardModel : public QAbstractTableModel {
|
||||
private:
|
||||
MemoryCard *memCard;
|
||||
QList<Block*> blocks;
|
||||
QList<int> blockId;
|
||||
public:
|
||||
PSXMemoryCardModel( MemoryCard *memCard, QObject *parent = 0 );
|
||||
int rowCount( const QModelIndex & parent = QModelIndex() ) const;
|
||||
int columnCount( const QModelIndex & parent = QModelIndex() ) const;
|
||||
QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const;
|
||||
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
|
||||
};
|
||||
|
||||
QString unicodeToAscii( QString text );
|
||||
|
39
qt-gui/psxsavewidget.cpp
Normal file
39
qt-gui/psxsavewidget.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include "psxsavewidget.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QTextCodec>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
PSXSaveWidget::PSXSaveWidget( MemoryCard *memCard, int block, QWidget *parent ) : QFrame( parent ) {
|
||||
this->memCard = memCard;
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
Icon *icon = new Icon;
|
||||
QFrame *iconContainer = new QFrame;
|
||||
iconContainer->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
|
||||
QVBoxLayout *iconLayout = new QVBoxLayout;
|
||||
iconWidget = new PSXIcon( icon );
|
||||
iconLayout->addWidget( iconWidget );
|
||||
iconContainer->setLayout( iconLayout );
|
||||
mainLayout->addWidget( iconContainer );
|
||||
mainLayout->addStretch();
|
||||
label = new QLabel(); mainLayout->addWidget( label );
|
||||
this->setLayout( mainLayout );
|
||||
this->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
|
||||
this->setEnabled( false );
|
||||
if( block != 0 ) { this->setBlock( block ); }
|
||||
}
|
||||
|
||||
void PSXSaveWidget::setBlock( int id ) {
|
||||
InitialBlock *block = (InitialBlock*)memCard->getBlock( id );
|
||||
QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
|
||||
QString saveTitle = codec->toUnicode( block->Header()->SJISSaveTitle() );
|
||||
//this->label->setText( saveTitle );
|
||||
this->iconWidget->setIcon( block->getIcon( 0 ) );
|
||||
this->iconWidget->update();
|
||||
this->setEnabled( true );
|
||||
}
|
||||
|
||||
void PSXSaveWidget::setBlockFromModel( const QModelIndex &index ) {
|
||||
this->setBlock( index.model()->index( index.row(), 0 ).data().toInt() );
|
||||
}
|
||||
|
18
qt-gui/psxsavewidget.h
Normal file
18
qt-gui/psxsavewidget.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QAbstractItemModel>
|
||||
#include "memcard.h"
|
||||
#include "psxicon.h"
|
||||
|
||||
class PSXSaveWidget : public QFrame {
|
||||
Q_OBJECT
|
||||
private:
|
||||
MemoryCard *memCard;
|
||||
PSXIcon *iconWidget;
|
||||
QLabel *label;
|
||||
public:
|
||||
PSXSaveWidget( MemoryCard *memCard = 0, int block = 0, QWidget *parent = 0 );
|
||||
public slots:
|
||||
void setBlock( int id );
|
||||
void setBlockFromModel( const QModelIndex &index );
|
||||
};
|
13
qt-gui/qt-gui.pro
Normal file
13
qt-gui/qt-gui.pro
Normal file
|
@ -0,0 +1,13 @@
|
|||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) Thu Dec 6 10:48:15 2007
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += . ..
|
||||
LIBS += -L.. -lpsxsave
|
||||
|
||||
# Input
|
||||
HEADERS += psxsavewidget.h psxicon.h psxmemcard.h
|
||||
SOURCES += main.cpp psxsavewidget.cpp psxicon.cpp psxmemcard.cpp
|
1
qt-test-cli/db
Symbolic link
1
qt-test-cli/db
Symbolic link
|
@ -0,0 +1 @@
|
|||
../testdata/db
|
97
qt-test-cli/main.cpp
Normal file
97
qt-test-cli/main.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <QtGui>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "memcard.h"
|
||||
|
||||
char* decode_sjis( char* sjis ) {
|
||||
QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
|
||||
if( codec == 0 ) { return "Shift-JIS Not Supported"; }
|
||||
QString unicode = codec->toUnicode( sjis );
|
||||
return unicode.toUtf8().data();
|
||||
}
|
||||
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
QCoreApplication app( argc, argv );
|
||||
char* filename;
|
||||
char buffer[256];
|
||||
string name;
|
||||
string code;
|
||||
map<string, string> games;
|
||||
|
||||
if( argc > 1 ) {
|
||||
filename = argv[1];
|
||||
} else {
|
||||
cout << "No filename provided, exiting.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
fstream db;
|
||||
db.open( "db", ios::in );
|
||||
while( !db.eof() ) {
|
||||
db.getline( buffer, 256 );
|
||||
code = buffer;
|
||||
int offset = code.find( ";" );
|
||||
if( offset > 0 ) {
|
||||
name = code.substr( offset + 1 );
|
||||
code = code.substr( 0, offset );
|
||||
games[code] = name;
|
||||
}
|
||||
}
|
||||
db.close();
|
||||
|
||||
MemoryCard *memCard = new MemoryCard();
|
||||
memCard->loadFile( filename );
|
||||
if( argc > 2 ) {
|
||||
for( int i = 2; i < argc; i++ ) {
|
||||
cout << "Loading MCS (" << argv[i] << ")\n";
|
||||
memCard->loadMCS( argv[i] );
|
||||
}
|
||||
}
|
||||
|
||||
DirectoryBlock *directory = (DirectoryBlock*)memCard->getBlock( 0 );
|
||||
cout << "Loaded " << games.size() << " unique entries from the game database.\n";
|
||||
cout << "================================================================================\n";
|
||||
cout << "Initial block\n";
|
||||
cout << "================================================================================\n";
|
||||
cout << "ID Frame\n";
|
||||
cout << "--------------------------------------------------------------------------------\n";
|
||||
printf( "ID: %s\n", directory->IDFrame()->id() );
|
||||
printf( "XOR Valid: %s\n", directory->IDFrame()->getXOR() ? "Yes" : "No" );
|
||||
printf( "Block Valid: %s\n", directory->IDFrame()->isValid() ? "Yes" : "No" );
|
||||
for( int i = 1; i < 16; i++ ) {
|
||||
cout << "================================================================================\n";
|
||||
cout << "Block " << i << "\n";
|
||||
cout << "================================================================================\n";
|
||||
SaveHeaderFrame *h = ( ( (InitialBlock*)memCard->getBlock( i ) )->Header() );
|
||||
DirectoryFrame *dir = directory->Directory( i - 1 );
|
||||
string code = dir->licenseCode();
|
||||
if( code.size() > 5 ) { code.replace( 4, 1, "-" ); }
|
||||
printf( "Type: %d\n", dir->blockType() );
|
||||
printf( "Size: %d\n", dir->size() );
|
||||
printf( "Next Block: %d\n", dir->nextBlock() );
|
||||
printf( "Territory: %s\n", dir->territoryCode() );
|
||||
printf( "License: %s (%s)\n", dir->licenseCode(), games[code].c_str() );
|
||||
printf( "Save: %s\n", dir->saveCode() );
|
||||
printf( "XOR Valid: %s\n", dir->getXOR() ? "Yes" : "No" );
|
||||
switch( dir->blockType() ) {
|
||||
case 81:
|
||||
cout << "--------------------------------------------------------------------------------\n";
|
||||
printf( "Magic Number: %s\n", h->magicNumber() );
|
||||
printf( "Icon Display Type: %d\n", h->iconDisplayType() );
|
||||
printf( "Blocks Used: %d\n", h->blocksUsed() );
|
||||
printf( "SJIS Save Title: %s\n", decode_sjis( h->SJISSaveTitle() ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
cout << "\n\nNext Open Block: " << directory->nextOpenBlock() << "\n";
|
||||
memCard->saveFile( "test.mcr" );
|
||||
memCard->saveBlockToFile( "test.mcs", 4 );
|
||||
( (InitialBlock*)memCard->getBlock( 4 ) )->getIcon( 0 )->exportXPM( "test.xpm" );
|
||||
return 0;
|
||||
}
|
14
qt-test-cli/qt.pro
Normal file
14
qt-test-cli/qt.pro
Normal file
|
@ -0,0 +1,14 @@
|
|||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) Tue Dec 4 17:27:04 2007
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
#QT -= gui
|
||||
TARGET = qtpsx
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += . ..
|
||||
LIBS += -L.. -lpsxsave
|
||||
|
||||
|
||||
# Input
|
||||
SOURCES += main.cpp
|
84
test.cpp
Normal file
84
test.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "memcard.h"
|
||||
|
||||
char* decode_sjis( char* sjis ) {
|
||||
return sjis;
|
||||
}
|
||||
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
char* filename;
|
||||
char buffer[256];
|
||||
string name;
|
||||
string code;
|
||||
map<string, string> games;
|
||||
|
||||
if( argc > 1 ) {
|
||||
filename = argv[1];
|
||||
} else {
|
||||
cout << "No filename provided, exiting.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
fstream db;
|
||||
db.open( "db", ios::in );
|
||||
while( !db.eof() ) {
|
||||
db.getline( buffer, 256 );
|
||||
code = buffer;
|
||||
int offset = code.find( ";" );
|
||||
if( offset > 0 ) {
|
||||
name = code.substr( offset + 1 );
|
||||
code = code.substr( 0, offset );
|
||||
games[code] = name;
|
||||
}
|
||||
}
|
||||
db.close();
|
||||
|
||||
MemoryCard *memCard = new MemoryCard();
|
||||
memCard->loadFile( filename );
|
||||
if( argc > 2 ) {
|
||||
cout << "Loading MCS (" << argv[2] << ")\n";
|
||||
memCard->loadMCS( argv[2], 4 );
|
||||
}
|
||||
|
||||
DirectoryBlock *directory = (DirectoryBlock*)memCard->getBlock(0);
|
||||
cout << "Loaded " << games.size() << " unique entries from the game database.\n";
|
||||
cout << "================================================================================\n";
|
||||
cout << "Initial block\n";
|
||||
cout << "================================================================================\n";
|
||||
cout << "ID Frame\n";
|
||||
cout << "--------------------------------------------------------------------------------\n";
|
||||
printf( "ID: %s\n", directory->IDFrame()->id() );
|
||||
printf( "XOR Valid: %s\n", directory->IDFrame()->getXOR() ? "Yes" : "No" );
|
||||
printf( "Block Valid: %s\n", directory->IDFrame()->isValid() ? "Yes" : "No" );
|
||||
for( int i = 1; i < 16; i++ ) {
|
||||
cout << "================================================================================\n";
|
||||
cout << "Block " << i << "\n";
|
||||
cout << "================================================================================\n";
|
||||
SaveHeaderFrame *h = ( ( (InitialBlock*)memCard->getBlock( i ) )->Header() );
|
||||
DirectoryFrame *dir = directory->Directory( i - 1 );
|
||||
printf( "Type: %d\n", dir->blockType() );
|
||||
printf( "Size: %d\n", dir->size() );
|
||||
printf( "Next Block: %d\n", dir->nextBlock() );
|
||||
printf( "Territory: %s\n", dir->territoryCode() );
|
||||
printf( "License: %s (%s)\n", dir->licenseCode(), games[dir->licenseCode()].c_str() );
|
||||
printf( "Save: %s\n", dir->saveCode() );
|
||||
printf( "XOR Valid: %s\n", dir->getXOR() ? "Yes" : "No" );
|
||||
switch( dir->blockType() ) {
|
||||
case 81:
|
||||
cout << "--------------------------------------------------------------------------------\n";
|
||||
printf( "Magic Number: %s\n", h->magicNumber() );
|
||||
printf( "Icon Display Type: %d\n", h->iconDisplayType() );
|
||||
printf( "Blocks Used: %d\n", h->blocksUsed() );
|
||||
printf( "SJIS Save Title: %s\n", decode_sjis( h->SJISSaveTitle() ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
BIN
testdata/ALUNDRA2 FILE1 Cabin.mcs
vendored
Normal file
BIN
testdata/ALUNDRA2 FILE1 Cabin.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 01.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 01.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 02.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 02.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 03.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 03.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 04.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 04.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 05.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 05.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 06.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 06.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 07.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 07.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 08.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 08.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/CHRONO CROSS 09.mcs
vendored
Normal file
BIN
testdata/CHRONO CROSS 09.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/DW7 01 Phoe L01 0 00.mcs
vendored
Executable file
BIN
testdata/DW7 01 Phoe L01 0 00.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/FF7 SAVE01 64 05.mcs
vendored
Executable file
BIN
testdata/FF7 SAVE01 64 05.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/FF7 SAVE01 64 23.mcs
vendored
Normal file
BIN
testdata/FF7 SAVE01 64 23.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/FF7 SAVE02 32 17.mcs
vendored
Normal file
BIN
testdata/FF7 SAVE02 32 17.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/FF7 SAVE02 47 20.mcs
vendored
Executable file
BIN
testdata/FF7 SAVE02 47 20.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/FF7 SAVE03 65 03.mcs
vendored
Executable file
BIN
testdata/FF7 SAVE03 65 03.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/FF8 01 14 05.mcs
vendored
Normal file
BIN
testdata/FF8 01 14 05.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/FF9 FILE01 14 01.mcs
vendored
Executable file
BIN
testdata/FF9 FILE01 14 01.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/FF9 FILE06 58 04.mcs
vendored
Executable file
BIN
testdata/FF9 FILE06 58 04.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/FFT FILE01 02 28 48.mcs
vendored
Executable file
BIN
testdata/FFT FILE01 02 28 48.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/FFT FILE01 13 01 48.mcs
vendored
Executable file
BIN
testdata/FFT FILE01 13 01 48.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/GRANDIA 1 Gadwin s House 272 07.mcs
vendored
Normal file
BIN
testdata/GRANDIA 1 Gadwin s House 272 07.mcs
vendored
Normal file
Binary file not shown.
BIN
testdata/Intelligent Qube.mcs
vendored
Executable file
BIN
testdata/Intelligent Qube.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/Legend of Legaia 01 Time 09 53.mcs
vendored
Executable file
BIN
testdata/Legend of Legaia 01 Time 09 53.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/MGS EZ 01 40 U Grnd Pssge.mcs
vendored
Executable file
BIN
testdata/MGS EZ 01 40 U Grnd Pssge.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/MGS EZ 04 45 Spply Rte.mcs
vendored
Executable file
BIN
testdata/MGS EZ 04 45 Spply Rte.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/MGS NM 00 29 Cell.mcs
vendored
Executable file
BIN
testdata/MGS NM 00 29 Cell.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/MGS NM 08 21 U Grnd Base 3.mcs
vendored
Executable file
BIN
testdata/MGS NM 08 21 U Grnd Base 3.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/MGS VR Training Data.mcs
vendored
Executable file
BIN
testdata/MGS VR Training Data.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/Saiyuki01 Lv23 Ch 2 19 43 Map.mcs
vendored
Executable file
BIN
testdata/Saiyuki01 Lv23 Ch 2 19 43 Map.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/Saiyuki02 Lv25 Ch 2 20 53 In B.mcs
vendored
Executable file
BIN
testdata/Saiyuki02 Lv25 Ch 2 20 53 In B.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/Saiyuki03 Lv26 Ch 2 21 05 In B.mcs
vendored
Executable file
BIN
testdata/Saiyuki03 Lv26 Ch 2 21 05 In B.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/THE KING OF FIGHTERS 99.mcs
vendored
Executable file
BIN
testdata/THE KING OF FIGHTERS 99.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/VALKYRIE PROFILE No 1 LV 18.mcs
vendored
Executable file
BIN
testdata/VALKYRIE PROFILE No 1 LV 18.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/WO3 CFG.mcs
vendored
Executable file
BIN
testdata/WO3 CFG.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/WO3 Venom PortKr Pirna 1 45 06.mcs
vendored
Executable file
BIN
testdata/WO3 Venom PortKr Pirna 1 45 06.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/Wild Arms FILE01 LV13.mcs
vendored
Executable file
BIN
testdata/Wild Arms FILE01 LV13.mcs
vendored
Executable file
Binary file not shown.
BIN
testdata/Wild Arms FILE01 LV14.mcs
vendored
Executable file
BIN
testdata/Wild Arms FILE01 LV14.mcs
vendored
Executable file
Binary file not shown.
10107
testdata/db
vendored
Normal file
10107
testdata/db
vendored
Normal file
File diff suppressed because it is too large
Load diff
10110
testdata/dbase.ps1
vendored
Normal file
10110
testdata/dbase.ps1
vendored
Normal file
File diff suppressed because it is too large
Load diff
BIN
testdata/epsxe000.mcr
vendored
Executable file
BIN
testdata/epsxe000.mcr
vendored
Executable file
Binary file not shown.
BIN
testdata/ff7.mcs
vendored
Executable file
BIN
testdata/ff7.mcs
vendored
Executable file
Binary file not shown.
Loading…
Reference in a new issue