Final Fantasy Forums > Gameplay Mods
Battles playing at 60fps
Obesebear:
Project Goal
To get Final Fantasy 7 battles playing at 60 frames per second.
Current Completion Progress
Model animations updated... 0% (Kimera needs a bit of tweaking first)
Limit Break animations updated... 0% (Need to find where these are stored. Potentially within .s files)
Camera animations updated... 80% (still may be a few instances of the camera being handled elsewhere)
Texture animations updated... 10% (Aali seems to have decompiled the .s data, but that information has yet to be harnessed)
Tifa, Cait's limit slots, battle square slots updated... 25% (DLPB will probably knock this out shortly)
Important Information
In order to get the game running battles at 60fps, the following values need to be hex edited in the ff7.exe:
0x3BF506 from 2E to 5E, 0x3BF50E from 2C to 5C, and 0x3BF516 from 2E to 5E.
.S Files Dump
--- Quote from: Aali on 2011-12-03 21:08:32 ---I wrote these tools to help me read and edit .s files, maybe you can put them to good use. Simply adding more frames to the animations just caused it to cut out early when I tried it but maybe you can figure that out.
sptdump.c: .s file -> text format
--- Code: ---#include <stdio.h>
#include "spt.h"
int main(int argc, char *argv[])
{
FILE *f;
struct spt_header header;
int i;
int j;
if(argc < 2)
{
printf("usage: sptdump <file>\n");
exit(1);
}
f = fopen(argv[1], "rb");
fread(&header, sizeof(header), 1, f);
printf("File type: %p\n", header.file_type);
printf("Version: %p\n", header.version);
printf("Number of SPT entries: %i\n", header.num_spt_entries);
printf("\n");
for(i = 0; i < header.num_spt_entries; i++)
{
struct spt_entry entry;
fread(&entry, sizeof(entry), 1, f);
printf(" SPT Entry %i: %p, %i\n", i, entry.field_0, entry.num_spt_struc_183);
for(j = 0; j < entry.num_spt_struc_183; j++)
{
struct spt_struc_183 struc_183;
fread(&struc_183, sizeof(struc_183), 1, f);
printf(" %i: %p %5i %5i %5i %5i %5i %5i 0x%04x %3u %3u %3u %3u\n", j, struc_183.flags, struc_183.x, struc_183.y, struc_183.field_8, struc_183.field_A, struc_183.texture_page, (struc_183.field_E & 0x3F) << 4, struc_183.field_E >> 6, struc_183.w1, struc_183.w2, struc_183.h1, struc_183.h2);
}
}
return 0;
}
--- End code ---
sptbuilder.c: text format -> .s file
--- Code: ---#include <stdio.h>
#include <string.h>
#include "spt.h"
const char file_type[] = "File type: ";
const char version[] = "Version: ";
const char num_spt_entries[] = "Number of SPT entries: ";
int main(int argc, char *argv[])
{
FILE *f;
FILE *of;
struct spt_header header;
int i;
int j;
char line[4096];
if(argc < 3)
{
printf("usage: sptbuilder <infile> <outfile>\n");
exit(1);
}
f = fopen(argv[1], "r");
of = fopen(argv[2], "wb");
if(!f)
{
perror("input file");
exit(1);
}
if(!of)
{
perror("output file");
exit(1);
}
while(1)
{
fgets(line, sizeof(line), f);
printf("%s", line);
if(!strncmp(line, file_type, sizeof(file_type) - 1)) sscanf(strstr(&line[sizeof(file_type)], "x") + 1, "%hhx", &header.file_type);
else if(!strncmp(line, version, sizeof(version) - 1)) sscanf(strstr(&line[sizeof(version)], "x") + 1, "%hhx", &header.version);
else if(!strncmp(line, num_spt_entries, sizeof(num_spt_entries) - 1)) sscanf(&line[sizeof(num_spt_entries) - 1], "%i", &header.num_spt_entries);
else break;
}
printf("Done parsing headers\n");
header.field_2 = 0;
fwrite(&header, sizeof(header), 1, of);
for(i = 0; i < header.num_spt_entries; i++)
{
struct spt_entry entry;
printf("Parsing SPT entry %i\n", i);
fgets(line, sizeof(line), f);
printf("%s", line);
strtok(line, ":,");
sscanf(strstr(strtok(0, ":,"), "x") + 1, "%hx", &entry.field_0);
sscanf(strtok(0, ":,"), "%hi", &entry.num_spt_struc_183);
fwrite(&entry, sizeof(entry), 1, of);
for(j = 0; j < entry.num_spt_struc_183; j++)
{
struct spt_struc_183 struc_183;
int tmp1;
int tmp2;
printf("%i\n", j);
fgets(line, sizeof(line), f);
printf("%s\n", strtok(line, ":"));
//printf("%s\n", strtok(0, ":"));
sscanf(strstr(strtok(0, ":"), "x") + 1, "%x %5hi %5hi %5hi %5hi %5hi %5i %p %3hhi %3hhi %3hhi %3hhi", &struc_183.flags, &struc_183.x, &struc_183.y, &struc_183.field_8, &struc_183.field_A, &struc_183.texture_page, &tmp1, &tmp2, &struc_183.w1, &struc_183.w2, &struc_183.h1, &struc_183.h2);
struc_183.field_E = tmp2 << 6;
struc_183.field_E |= tmp1 >> 4;
fwrite(&struc_183, sizeof(struc_183), 1, of);
}
}
fclose(of);
return 0;
}
--- End code ---
spt.h: data structures used in both programs
--- Code: ---#ifndef _SPT_H_
#define _SPT_H_
struct spt_header
{
unsigned char file_type;
unsigned char version;
unsigned short field_2;
unsigned int num_spt_entries;
} __attribute__((__packed__));
struct spt_entry
{
unsigned short field_0;
unsigned short num_spt_struc_183;
} __attribute__((__packed__));
struct spt_struc_183
{
unsigned int flags;
short x;
short y;
short field_8;
short field_A;
unsigned short texture_page;
short field_E;
unsigned char w1;
unsigned char w2;
unsigned char h1;
unsigned char h2;
} __attribute__((__packed__));
#endif
--- End code ---
--- End quote ---
Proof of Concept Videos
http://www.youtube.com/watch?v=D6ziBsBNSfI
http://www.youtube.com/watch?v=rx3DHs4iMzA
--- Quote from: DLPB on 2010-10-02 09:13:04 ---I found a few values in the exe which make the items on the menu smoother. So far I have only found the side menu values but with Kranmer I am guessing the rest (like Gil Box) can also be found. Have a go yourself:
FF7.exe
Edit address 002C8EA0 to 50
Edit address 002C8EAB to 12
Then open the menu and pay attention to the side menu (other values need altering to make it look perfect but this should give you a good idea)
--- End quote ---
DLPB:
if you have gone from 15 to 60 shouldn't that be 4X faster?
edit.
Let me know how you get on....I would be surprised if it was possible to change it all to 60 fps and get everything working without some major changes, but maybe it isn't working like I expect....
Obesebear:
Well I added 3 duplicate frames after each change in animation, but it seemed a little too slow. Granted that could very likely be from watching everything else move insanely fast, so I changed it to 2 instead. Not sure if it's too fast or slow. We can get it perfect later :)
The camera also moves too fast, but I think Proud Clod is able to mess with that, so no problem there. SFX plays at normal speed, the only problem I've found so far is the texture animations play too fast :(. So we either need to learn how to edit the .s files, or hope that someone finds a way to force them to play at normal operating speed.
I'll be pretty surprised as well. Besides being tedious there has to be a reason no one did this before.
sl1982:
Just looked into it. Made the fps 45 and obesebear's redone animations look good at this speed. So definately need more animation frames for 60fps.
Obesebear:
Yeah my bad, watching everything move so fast while I experimented with it messed me up. Adding 3 duplicate frames for every change in animation looks perfect at 60 fps.
To increase the speed to 60 fps change 0x3BF506 from 2E to 5E, 0x3BF50E from 2C to 5C, and 0x3BF516 from 2E to 5E.
--Edited for correct values and changes--
Navigation
[0] Message Index
[#] Next page
Go to full version