Joined: 4/11/2006
Posts: 487
Location: North of Russia :[
Yes, if was fwrite :) Now it does not look that hopeless ^^ You understood everything correctly and writing crc of executable file is a good idea... Sorry if I say discouraging or cruel things, I just want it to be done really well ) And if you keep getting better this way you can succeed~ ^^
struct MovieHeader {
char Sig[4];
char Ver[4];
long InputCount[4];
long FrameCount[4];
char DiskID[14];
long Controllers[1];
long Disks[1];
char RunName[16];
char RunnerName[16];
char GfxPlugin[32];
char SndPlugin[32];
char CDPlugin[32];
char BIOS[32];
char Pad1Plugin[32];
char Pad2Plugin[32];
char RunComments[256];
char ReservedSpace[512];
};
-----EDIT-----
Forgot the rest of the post ;)
The header totals 1024 Bytes. The movie file's input should start immediatly afterward for this and all versions until recording from a savestate is implimented.
BoltR : I'm not bothering with no fairy demons
BoltR : I'm going right for time itself
BoltR : Right in the eye
You know "long" is 4 bytes (8 on x86_64). Why are you using an array of size 4 for these? Do you need the frame counter to have a range from 0 to 340282366920938463463374607431768211456?
I've tried these two functions. The first one doesn't load the data at all, and the second one crashes at the last line(because it's loading from file as string instead of long).
Doing it that way is considered bad form. sizeof(long)==4 on 32 bit systems, sizeof(long)==8 on 64 bit systems. If you want to call fread() to bulk read the structure, here's what you should do.
First, use sizeof(MovieHeader) rather than assuming the size of the structure. Second, if you're using GCC to compile this, make sure you use __attribute__ ((packed)) to prevent dead space from being added. Finally, use the various uint32_t style fields to ensure fields remain the same size.
Or even better, read fields individually and use ntohs and ntohl class functions to regulate byte ordering. Not all hardware orders bytes the same way. This is the little/big endian system problem. Pentium and compatible hardware are little endian, and that's the major platform, but that might not be true for everybody.
Doing it that way is considered bad form. sizeof(long)==4 on 32 bit systems, sizeof(long)==8 on 64 bit systems. If you want to call fread() to bulk read the structure, here's what you should do.
First, use sizeof(MovieHeader) rather than assuming the size of the structure. Second, if you're using GCC to compile this, make sure you use __attribute__ ((packed)) to prevent dead space from being added. Finally, use the various uint32_t style fields to ensure fields remain the same size.
Or even better, read fields individually and use ntohs and ntohl class functions to regulate byte ordering. Not all hardware orders bytes the same way. This is the little/big endian system problem. Pentium and compatible hardware are little endian, and that's the major platform, but that might not be true for everybody.
I only understood about 50% of what you just said O.o
Using the following sample file and file read code I can get what's in the screenshot.
Hmm, is it possible for you to make movie file to remember what plugin's config are?
I can't see the point, the GFX plugin settings only really determine how it looks, not how it emulates. Besides that, the config is loaded by the plugin itself and not the emulator, so it's out of my reach.
BoltR : I'm not bothering with no fairy demons
BoltR : I'm going right for time itself
BoltR : Right in the eye
A little on a little off topic question here.
Are there any games that don't emulate right? I remember playing through FFIX on EpcxE (or something) and it froze at a certain cut scene. Only an older version worked. Are there any like that in this emu?
I am just a silhouette, a silhouette of a memory of a solitary night .. nothing more.
Right now, I'm not really concerned with that. I can debug things like that later and try to track down errors. The entire point of this is to impliment recording that works.
On that note, I'm looking into how the emulator handles input, so I can see how to properly record it. I still can't read the long value properly, because fgets is for strings and doesn't return hex or anything else, which I could use. If anyone can find the function to read hex from a file, that would be great.
BoltR : I'm not bothering with no fairy demons
BoltR : I'm going right for time itself
BoltR : Right in the eye
Joined: 4/11/2006
Posts: 487
Location: North of Russia :[
I can't see the point, the GFX plugin settings only really determine how it looks, not how it emulates
OBJECTION! ^__^
it may affect timing of events at very least.
EDIT: I would be more concerned with SFX plugin settings. I believe sometimes game waits until some sound is over, and it's affected by spu...
If my assessment of the source code is right, the emulator just dumps the raw data on the plugin, and leaves the decoding and rendering of the data to it. Graphics are one-way, while sound, pad, CD, and BIOS are all two-way exchanges. The point is though, that most options in the plugins themselves don't effect the emulation process. Only the Special Game Fixes effect it, the rest just determine how the decoded data is sent to the computer's hardware(IE DirectX or OpenGL, resolution, or in the case of sound, output quality). Any options in the plugin that effect emulation are for that plugin only, and not in all plugins. Besides this, there is no way to get plugin settings from within the emulator. When the emulator gets settings, it consults the DLL on-the-fly to open it's configure screen. The configure screen isn't in the emulator, it's in the DLL.
BoltR : I'm not bothering with no fairy demons
BoltR : I'm going right for time itself
BoltR : Right in the eye
This struct looks promising for recording and playing...
typedef struct
{
// controler type - fill it withe predefined values above
unsigned char controllerType;
// status of buttons - every controller fills this field
unsigned short buttonStatus;
// for analog pad fill those next 4 bytes
// values are analog in range 0-255 where 128 is center position
unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY;
// for mouse fill those next 2 bytes
// values are in range -128 - 127
unsigned char moveX, moveY;
unsigned char reserved[91];
} PadDataS;
Also, here's what it looks like so far.
BoltR : I'm not bothering with no fairy demons
BoltR : I'm going right for time itself
BoltR : Right in the eye
Is that "Movie - You" going to stay like that? I think I much rather see "Movie's Setting - Your Setting"
The disks thing, I just came up thought. I haven't tried this emu before, can you possible make emu prepares multiple ISO before running movie?
Like load in FF7 disc 1 (as #1), FF7 disc 2 (as #2), FF7 disc 3 (as #3), then record movie and it records open tray, close tray, changed iso to other #.
I don't think I can. The emulator emulates everything properly. There's only one function to read a file from a CD, and no real way to prepare a disk ahead of time without re-writing the entire disk read functions. What will happen is when recording, when you change disks with the emu, it will write a flag to the movie file instead of input that frame. When the playback gets to that point, it will pause the emu and ask for the next disk.
The info window is ever changing. The "Movie You" thing wasn't even there until I wanted to take the screenshot. I'm working more on the code than the looks right now. On that note, I'm looking into the actual recording aspect now. After I get it to record and replay some input, I'll compile the exe and post a link to the exe and source.
BoltR : I'm not bothering with no fairy demons
BoltR : I'm going right for time itself
BoltR : Right in the eye
It's already been stated, but I hope the plugins don't have any say in emulation. eg. the sound output driver should merely be an OS interface, and not actually do SPU work. The video CD-ROM plugin shouldn't get to decide (directly or otherwise) how long seeking takes.
And will there be Linux support? I might be able to assist with that, if you keep the Windows specific stuff separate from the generic backend. Last person to add rerecording to emulators made it for Windows and f**ked up all the rest of the operating systems.
OK, let's talk movie file structure. How should the movie file be arranged?
Two paths to go: fixed offsets or variable-length blocks. Fixed offsets are easier for hex-editing, but not flexible.
I'd suggest that in any case the header has either a length field that describes its size, or a field that stores the offset of the input data.
zefiris wrote:
also if I remember right there's such thing as internal clock in ps, so you should set movie starting internal time and record it and always fix during playback as I am pretty sure that random number generator relies on it heavily...
Definitely.
zefiris wrote:
I think you should start with 4-byte header(PSX\$1A), then address of data start or header length and only then start data.
Why 4 bytes? It can be of any length, preferably the name of the movie file format.
zefiris wrote:
...and please, don't store numbers as strings
It doesn't really matter. ;)
Valarnin wrote:
I've tried these two functions. The first one doesn't load the data at all, and the second one crashes at the last line(because it's loading from file as string instead of long).
Use fopen(moviefile, "rb") for binary mode. (Not related to the crash.)
You shouldn't need any calls to fseek.
Valarnin wrote:
If anyone can find the function to read hex from a file, that would be great.
Don't look for built-in mega-functions. ;) Read the raw data and convert it internally with library functions. You could write your own functions though that do the converting.
Valarnin wrote:
This struct looks promising for recording and playing...
typedef struct
{
// controler type - fill it withe predefined values above
unsigned char controllerType;
// status of buttons - every controller fills this field
unsigned short buttonStatus;
// for analog pad fill those next 4 bytes
// values are analog in range 0-255 where 128 is center position
unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY;
// for mouse fill those next 2 bytes
// values are in range -128 - 127
unsigned char moveX, moveY;
unsigned char reserved[91];
} PadDataS;
How about this?
typedef struct tPadData {
uint32_t ControllerType; // controler type - fill it withe predefined values above
uint32_t ButtonStatus; // status of buttons - every controller fills this field
uint32_t JoyL_X, JoyL_Y; // analog values of 0 to 255, 128 = center
uint32_t JoyR_X, JoyR_Y;
int32_t MouseMove_X; // values = -128 to 127
int32_t MouseMove_Y;
uint8_t reserved[91];
};
tPadData PadData
I also suggest using structs for Joystick L and R, and for the mouse.
Nononono, that struct is already in the emu. I mean I can get the button status and stuff with it. But anyways, progress is halted until I can find the function that gets button status from the plugin...
BoltR : I'm not bothering with no fairy demons
BoltR : I'm going right for time itself
BoltR : Right in the eye
Edit: and if the avatar isn't a dead giveaway, Linux support with all these movie and savestate features would be nice. It only has to be enough to boot up and play/record movies correctly, doesn't need an overly fancy GUI. AVI support I will be adding/modding myself.
how about linux support for 3d acceleration? until that comes, i won't be able to do much with any of this. though, i'll greatly enjoy seeing psx runs.