Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - FF7ExpNeg1

Pages: [1]
1
Q-Gears / Re: Little update and announce!!!
« on: 2007-07-01 03:18:49 »
However once he releases his RPG Studio, if the source uses a part of Q-gears, then he needs to release the source too.

I agree (and the source he releases must be under the GPL or a GPL compatible license).

An example from me. I'm working on "Pineapple Chronicles". A lot of stuff I'm using takes ideas from Q-gears, but I'm taking no code and rewriting from scratch. The code is mine, and will not be releasing it as Open Source.

BTW, what is Pineapple Chronicles?

2
Q-Gears / Re: Little update and announce!!!
« on: 2007-07-01 00:28:11 »

2) As Q-gears is GPL, and by extention your RPG Studio, you need to release your changes so we can work on them. I can give you Shell/FTP access to the Q-Gears project Sourceforge so you can upload your work via FTP and we can take it from there. I can do several things for you. I can create a new sourceforge project for you, and make you an admin. I can manage the SVN imports if you just want to upload your code via FTP. This will also give you a FTP spot for your own project and a website. I think you are making out like a bandit in this deal. ^_^


Not trying to nitpick here, but technically, the GPL is a distribution license, so Akari only has to release his changes under the GPL when he distributes his fork in either binary or source form.

3
Q-Gears / Re: Q-Gears 0.12
« on: 2007-03-30 00:29:29 »
Hi, I would like to help coding in this project.
I have mac os x and would be nice to make and osx port.

I actually ported q-gears to Mac OS X (10.3.9 PPC) way back in rev 26 but I am sure it is _way_ out of date now.  Take a look here to see what changes I made back then.  Maybe it can give you a head start:

http://sourceforge.net/tracker/index.php?func=detail&aid=1478991&group_id=165417&atid=835303

4
Scripting and Reverse Engineering / Re: KAWAI Opcode
« on: 2006-06-25 06:25:11 »
...

Also, as a side mention.

I can't seem to "unlzs" the SCEAP.LZS without it bombing. Am I using an old version of lzs? Anyone heard of this bug? I'm cerious to see what's in that.

To answer your second question, here is some C code I whipped up when I was investigating what SCEAP.LZS was a month back (this code isn't too good, I have a much better way to unlzs this using a 4k buffer so there isn't any compilcated offset instruction).  It does, however, write the uncompressed data to a 640x480 bitmap named "test.bmp". Pass in SCEAP.LZS as the only argument.

Code: [Select]
#include <stdio.h>

typedef unsigned char byte;

int main(int argc, char *argv[])
{
FILE *f;
int out_len; //compressed length
uint size;
byte control;
byte *data;
byte *out;
byte buf[4];
int buf_size;
int read;
int pos;
int control_pos;
int raw_offset;
int marker;
int len;
int i;
byte *flipped, *src, *dest;
FILE *outf;

if (argc != 2) {
printf("lzsexpand -- Uncompress a LZS file\n");
printf("\n");
printf("USAGE: lzsepand [lzs file]\n");
}

f = fopen(argv[1], "rb");
fread(buf, 4, 1, f);
size = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
printf("Size: %d\n", size);

//read in the data
data = (byte*)calloc(size, 1);
read = fread(data, size, 1, f);
printf("Bytes read: %d\n", read);

pos = 0;
out_len = 0;
buf_size = 4096;
out = (byte*)malloc(buf_size);
while (pos < size) {
if (out_len + 8 * 18 > buf_size) {
buf_size += 4096;
out = (byte*)realloc(out, buf_size);
}
control = data[pos];
pos++;
for (control_pos = 0; control_pos < 8; control_pos++) {
if (control & 1) {
out[out_len] = data[pos];
pos++;
out_len++;
}
else {
raw_offset = data[pos] | ((data[pos + 1] & 0xF0) << 4);
len = (data[pos + 1] & 0xF) + 3;
marker = out_len - ((out_len - 18 - raw_offset) & 0xFFF);
pos += 2;

for (i = 0; i < len; i++) {
if (marker < 0)
out[out_len] = 0x00;
else {
out[out_len] = out[marker];
}
out_len++;
marker++;
}
}
control >>= 1;
if (pos >= size)
break;
}
}

/* the lines in the bitmap are upside, after some research
* this is to be expected. allocate enough memory for one
* vertical line and start reversing
* 640 pixels * 2 bytes per pixel = 1280 bytes
*/
flipped = (byte*)malloc(640 * 480 * 2);
dest = flipped;
src = out + 640 * 479 * 2;
for (i = 0; i < 480; i++) {
memcpy(dest, src, 1280);
dest += 1280;
src -= 1280;
}

free(out);
out = flipped;

free(data);
fclose(f);

outf = fopen("test.bmp", "wb");

{
byte header[] = {
0x42, 0x4d, 0x36, 0xb4, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xe0, 0x01,
0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//calc size real quick
unsigned int fsize = 640 * 480 * 2 + sizeof(header);
header[2] = fsize & 0xFF;
header[3] = (fsize >> 8) & 0xFF;
header[4] = (fsize >> 16) & 0xFF;
header[5] = (fsize >> 24) & 0xFF;

printf("Size of header %X\n", sizeof(header));
fwrite(header, sizeof(header), 1, outf);
}

fwrite(out,  out_len, 1, outf);
free(out);
fclose(outf);

return 0;
}


5
Q-Gears / Re: Q-gears logo/Splash Screen contest.
« on: 2006-06-03 15:44:22 »
Do we want to encode this splash screen in LZS?  I have been studying the LZS format (and have found a simpler formula to calculate the offset) used in FF7 (PSX) and should have some code to compress into LZS format shortly. 

The reason I ask this is because on the PSX disc there is a file called SCEAP.LZS (Sony Computer Entertainment America Presents) which is a 640 by 320 16bit raw image compressed in LSZ.

6
Q-Gears / Re: Subversion and that initial Checkout
« on: 2006-05-21 14:52:12 »
I had this same problem on Mac OS X when I compiled subversion.  I had to ./configure again using --with-ssl.  Everything worked fine after that.

7
Q-Gears / Re: I'm getting tierd of makefile maintainance
« on: 2006-05-18 04:07:03 »
I was starting to think along similar lines.  Autoconf is the way to go.  Let me know if you need any help.

8
Writing the structs directly will pose a problem for systems in big endian though.

9
Q-Gears / Re: About defines and platform specific.
« on: 2006-05-10 04:04:46 »
I started out using main() on Mac OS X and got it to compile, but when I tried to run it, it crashed and burned.  After doing some quick searching on the net, one option was to use SDL_main instead.  After I switched it to that, everything seemed to work.

I do agree with your point though, it should be encapsulated in another class, not in main.cpp.

10
Scripting and Reverse Engineering / Introducing Q-Gears
« on: 2006-04-12 11:19:00 »
This is truly amazing!  Good idea halkun!

11
Scripting and Reverse Engineering / Assemble source code
« on: 2005-11-19 18:37:44 »
Wouldn't it be easier to disassemble the PSX version since there would be no DirectX C++ and could easily be run through an emulator?

12
I don't know of any IsNumeric method on the TextBox class, but here is a method you could use to test any String value if it is a number or not:

Code: [Select]

    Public Function IsNumeric(ByVal str As String) As Boolean
        Try
            Integer.Parse(str)
        Catch ex As Exception
            Return False
        End Try
        Return True
    End Function

13
Good catch, I switched the 2 and the 6, now fixed. Thanks!

14
For this particular file I am pretty sure it is from 0x800 (2k) to the end of the file.  The reason I say this is because most of the data between what I displayed above and 0x800 is zero and looking at the data beginning at 0x800 I see the following:

Code: [Select]

0x00000800  D4 15 01 80 9C 15 01 80 AC 15 01 80 BC 15 01 80  ................
0x00000810  CC 15 01 80 62 61 74 74 6C 65 2E 78 00 00 00 00  ....battle.x....
0x00000820  00 00 00 00 E0 01 D8 01 7C 1E 01 80 8C 1E 01 80  ........|.......
0x00000830  9C 21 01 80 8C 1E 01 80 28 22 01 80 08 25 01 80  .!......("...%..
0x00000840  4C 25 01 80 90 25 01 80 18 26 01 80 BC 26 01 80  L%...%...&...&..
0x00000850  5C 26 01 80 88 24 01 80 A0 23 01 80 D4 25 01 80  \&...$...#...%..
0x00000860  38 27 01 80 0C 22 01 80 BC 22 01 80 D4 22 01 80  8'..."..."..."..
0x00000870  FC 22 01 80 14 23 01 80 84 23 01 80 84 23 01 80  ."...#...#...#..
0x00000880  84 23 01 80 84 23 01 80 4C 23 01 80 84 23 01 80  .#...#..L#...#..
0x00000890  84 23 01 80 84 23 01 80 5C 23 01 80 74 23 01 80  .#...#..\#..t#..


A string 'battle.x' and a bunch of memory addresses. Thanks for the input!

15
FF7 Engineering Part I

On the first PSX FF7 disc there is a file in the root drive named SYSTEM.CNF (the .CNF might not be visible due to Windows).  This is just a plain text file that we can open in Notepad.  The first line contains the following:
Code: [Select]
BOOT = cdrom:\SCUS_941.63;1

This tells us that the PlayStation will launch the file SCUS_941.63 on boot.  If we look on the root of the disc we can see this file.

SCUS_941.63 happens to be a binary file that we can't really look at using Notepad.  We will write a simple Java program to display the binary data in a more readable form.  This code does just that:
Code: [Select]

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class HexDump {
public static void main(String[] args) {
if (args.length < 3) {
System.out.print("USAGE: java HexDump [filename] [start hex address] [num lines]");
System.exit(1);
}
File f = new File(args[0]);
if (!f.exists()) {
System.out.println("ERROR: File not found!");
System.exit(1);
}
RandomAccessFile in = null;
try {
in = new RandomAccessFile(f, "r");
} catch (FileNotFoundException e) {e.printStackTrace(); System.exit(1);}
long startAddress = 0;
int numLines = 0;
try {
startAddress = Long.parseLong(args[1], 16); //base 16, hexadecimal
numLines = Integer.parseInt(args[2]);
} catch (NumberFormatException e) {e.printStackTrace(); System.exit(1);}
try {
in.seek(startAddress);
} catch (IOException e) {e.printStackTrace(); System.exit(1);}
byte[] buf = new byte[16]; //one line of hexadecimal values
try {
for (int i = 0; i < numLines; i++) {
in.read(buf);
System.out.printf("0x%08X  ", startAddress);
StringBuilder ascii = new StringBuilder();
for (int j = 0; j < 16; j++) {
System.out.printf("%02X ", buf[j]);
if (buf[j] < 32 || buf[j] > 127)
ascii.append('.');
else
ascii.append((char)buf[j]);
}
System.out.print(" ");
System.out.println(ascii.toString());
startAddress += 16;
}
in.read(buf);
} catch (IOException e) {e.printStackTrace(); System.exit(1);}
try {
in.close();
} catch (IOException e) {e.printStackTrace(); System.exit(1);}
}
}


The program above can be compiled on the command line:
Code: [Select]
javac HexDump.java

Now make sure the command prompt's current working directory contains the SCUS_941.63 file.  We can now run the above program and look at the first few bytes of the boot file:

Code: [Select]
java HexDump SCUS_941.63 0 10

This produces the following:
Code: [Select]

0x00000000  50 53 2D 58 20 45 58 45 00 00 00 00 00 00 00 00  PS-X EXE........
0x00000010  C0 10 01 80 00 00 00 00 00 00 01 80 00 08 06 00  ................
0x00000020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x00000030  F0 FF 1F 80 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x00000040  00 00 00 00 00 00 00 00 00 00 00 00 53 6F 6E 79  ............Sony
0x00000050  20 43 6F 6D 70 75 74 65 72 20 45 6E 74 65 72 74   Computer Entert
0x00000060  61 69 6E 6D 65 6E 74 20 49 6E 63 2E 20 66 6F 72  ainment Inc. for
0x00000070  20 4E 6F 72 74 68 20 41 6D 65 72 69 63 61 20 61   North America a
0x00000080  72 65 61 00 00 00 00 00 00 00 00 00 00 00 00 00  rea.............
0x00000090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................


We can definitely see that this is a PlayStation executable by looking at the first line.  Lets now look at three important values on the second line (address 0x00000010).

The last four bytes are 00 08 06 00. All four byte integer values in this file are in little-endian format so to get a better look at a particular integer we need to byteswap it.  To do this we make the first byte the last, the second the third, the third the second, and the last the first.  Byteswapping the current four bytes we are looking at produces 00 06 08 00 or just 0x60800.  If we convert this to a decimal value we get the value 395,264.  

Hmmm, this is quite interesting.  Why?  Take a look at the size of SCUS_941.63: 397,312.  This is exactly 2048 byte (2k) difference.  We can make the safe assumption that a PlayStation executable header is 2k in length.  We can then reason that the PlayStation loads the data starting at offset 2k and with a length of 0x60800.  This would take us to the end of the file.  But where does it load the data to?

To answer this question let us look at the second to last four bytes on line two: 00 00 01 80.  If we byteswap these we get 0x80010000, which is a valid memory location on the PlayStation.

Once the the data is loaded in memory, execution must begin at some address.  For this we turn to the first four bytes of line two (byteswapped of course): 0x800110C0.  This is where execution of Final Fantasy 7 begins (well, not really, there is a ton of startup and initialization code).

This concludes part I.  In the next installment we will go through dis-assembling the first few MIPS opcodes. Feedback appreciated!

16
Scripting and Reverse Engineering / FF7 PSX Code Location
« on: 2005-09-25 05:05:45 »
Hello,

I have been digging into the PSX version of FF7 for about 10 days now.  I wrote a simple disassembler in Java to look at some of the code in SCUS_941.63 (the file on the root of disc 1).  Is there any MIPS code in other files on the disc, or does this file contain all of the executable code? (I know from reading gears.pdf that there is cross-platform script code in other files).

Thank you!
(This forum has a wealth of great information, keep up the good work!)

Pages: [1]