Closed GoogleCodeExporter closed 8 years ago
Note, whether this feature gets implemented or not depends on if any developers
are
interested in doing it and how similar the formats of the PJ64 and mupen64
statesaves
are.
Original comment by ebenbl...@gmail.com
on 14 Apr 2008 at 7:10
Original comment by ebenbl...@gmail.com
on 14 Apr 2008 at 7:11
Which 'save files' are wanted? It seems that PJ64 has several different save
files -
.SRA, .EEP, and .PJ. Since PJ64 is closed source it's going to be difficult to
implement this feature.
Original comment by richard...@gmail.com
on 14 Apr 2008 at 7:17
SRA and EEP files are generic as they are fit to the Nintendo64 standard, the
.pj
files can possibly be ported by looking at the source from 1.4.
Original comment by sgorman07@gmail.com
on 17 Apr 2008 at 6:33
Aren't PJ64 .pj savestates just byteswapped copies of the RAM?
Original comment by Wareya@gmail.com
on 7 Jul 2008 at 8:01
I'm fairly sure its just that, the registers, and some header info, sometimes
zipped. 1964 can also use Project64 saves, and Zilmar told me they haven't
changed
from 1.0 so its in the open source 1.4 code.
EDITTED (basically the first time I went looking I couldn't find the Project64
savestate code, its not in a neat savestate.c like ours ;)) Well... you got me
to
do some work. The Project64 code is in the
BOOL Machine_LoadState(void) / BOOL Machine_SaveState(void) functions in cpu.c.
The
difference is mupen states are gzipped instead of zipped (and we don't have
uncompressed fallback) and the registers / memories are in a different order.
Project64 also has slightly different header info, they save the full header,
we
just save the MD5.
It shouldn't take too much time to port those functions over. Sadly between the
netplay code / bug hunting / Input and RCS issues I don't think any devs have
had
time. At least with this info. anyone can do it now.
Original comment by sknau...@wesleyan.edu
on 8 Jul 2008 at 2:26
One potential problem is that Mupen64plus also loads/saves a list of pending
interrupts and the 'virtual clock cycle' when these interrupts will fire. Even
if
PJ64 saves the same kind of data, since the cores are different the timing will
not
be the same. It is possible that the game will not run properly without this
state
information, and if we cannot do some kind of translation into our own timing
units
it might not work.
Original comment by richard...@gmail.com
on 8 Jul 2008 at 5:56
I would like to give this one a shot.
Original comment by olejl77@gmail.com
on 22 Dec 2008 at 11:00
I have done some initial work on this. It is not working yet (and I don't know
if it
ever will).
I think that I'm now reading all the information correct from the pj64
savestate (it
is difficult to verify since I don't know what it is supposed to be). Most of
the
changes has been implemented in savestate.c, and all my current
questions/issues has
been marked with 'TODO' in this file.
I have also done some minor changes around to be able to test it.
When I try to load a pj64 savestate, m64p is stuck in an endless loop, and
nothing
happens (I didn't expect it to work). The most likely problem is the TLB and
vi_interupt which I am not sure how to convert between pj64 and m64p.
Anyone able to shed some light on the issues?
(A patch file is attached. Highly experimental!!!)
Original comment by olejl77@gmail.com
on 23 Dec 2008 at 9:57
Attachments:
Wow. I was quite surprised, but I actually made a one time load of a PJ64
savestate.
I have not been able to reproduce the "accident". All the other tries seems to
end in
some sort of "audio loop".
Patch is attached. Did some fixes on the vi_interupt handling.
Original comment by olejl77@gmail.com
on 1 Jan 2009 at 4:48
Attachments:
Ok now I have the first beta version available for testing. Any feedback /
testing is
welcomed.
I have successfully loaded PJ64 savestates from the following games:
- Legend of Zelda, The - Ocarina of Time (U) (V1.0) [!]
- Super Mario 64 (U) [!]
- Perfect Dark (U) (V1.0) [!]
- Mario Kart 64 (U) [!]
- GoldenEye 007 (U) [!]
Almost working
- Paper Mario (U) [!] (some graphic gliches after load)
- Banjo-Tooie (U) [!] (freezes short after loading)
There are still issues, but maybe it is easier to do them on a case by case
basis?
Original comment by olejl77@gmail.com
on 6 Jan 2009 at 1:26
Attachments:
Same as above only that I removed all the core and gui changes I made. Now it
simply
try to load the savestate as a PJ64 savestate if the initial mupen one fails.
Changes
only to savestates.c, savestates.h, memory.c, memory.h (last two only makes some
internal functions available from savestates.c)
Original comment by olejl77@gmail.com
on 12 Jan 2009 at 5:07
Attachments:
The patch from comment #12 was committed to the trunk in rev 1295, with a few
small
changes.
Original comment by richard...@gmail.com
on 25 Jan 2009 at 1:12
attached is a patch for 'savestates_save_pj64'. It currently is not hooked up in
core. This is what I did to test it:
Index: r4300/interupt.c
===================================================================
--- r4300/interupt.c (revision 1321)
+++ r4300/interupt.c (working copy)
@@ -610,8 +617,8 @@
if (savestates_job & SAVESTATE)
{
- savestates_save();
- savestates_job &= ~SAVESTATE;
+ if (savestates_save_pj64() != -1)
+ savestates_job &= ~SAVESTATE;
}
}
Somebody should find a nice way to do this...
Original comment by olejl77@gmail.com
on 16 Feb 2009 at 3:27
Attachments:
As of r1336 Project64 savestates should be fully supported, besides some minor
timestamp variables that do not seem to be used by Project64.
Original comment by sknau...@wesleyan.edu
on 22 Feb 2009 at 12:08
Re-opened, there appears to be some issue in the load code, Olejl found this
patch
helps:
Index: main/savestates.c
===================================================================
--- main/savestates.c (revision 1331)
+++ main/savestates.c (working copy)
@@ -605,33 +605,98 @@
unzReadCurrentFile(zipstatefile, &sp_register.sp_dram_addr_reg, 4);
unzReadCurrentFile(zipstatefile, &sp_register.sp_rd_len_reg, 4);
unzReadCurrentFile(zipstatefile, &sp_register.sp_wr_len_reg, 4);
- unzReadCurrentFile(zipstatefile, &sp_register.w_sp_status_reg, 4);
+ unzReadCurrentFile(zipstatefile, &sp_register.sp_status_reg, 4);
unzReadCurrentFile(zipstatefile, &sp_register.sp_dma_full_reg, 4);
unzReadCurrentFile(zipstatefile, &sp_register.sp_dma_busy_reg, 4);
unzReadCurrentFile(zipstatefile, &sp_register.sp_semaphore_reg, 4);
unzReadCurrentFile(zipstatefile, &value, 4); // SP_PC_REG -> Not part of mupen
savestate. Dummy read.
unzReadCurrentFile(zipstatefile, &value, 4); // SP_IBIST_REG -> Not part of
mupen savestate. Dummy read.
+
+ unsigned int *w_sp = &sp_register.w_sp_status_reg; // Only done to reduce
the
amount
+ unsigned int *sp = &sp_register.sp_status_reg; // of character in the
below ifs / elses
+ *w_sp = 0;
+ if ((*sp & 0x0001) == 0) { *w_sp |= 0x0000001; }
+ else { *w_sp |= 0x0000002; }
+ if ((*sp & 0x0002) == 0) { *w_sp |= 0x0000004; }
+ if ((*sp & 0x001c) == 0) { *w_sp |= 0x0000008; } // TODO: Unsecure if this
is
correct
+ else { *w_sp |= 0x0000010; } // TODO: --- " ---
+ if ((*sp & 0x0020) == 0) { *w_sp |= 0x0000020; }
+ else { *w_sp |= 0x0000040; }
+ if ((*sp & 0x0040) == 0) { *w_sp |= 0x0000080; }
+ else { *w_sp |= 0x0000100; }
+ if ((*sp & 0x0080) == 0) { *w_sp |= 0x0000200; }
+ else { *w_sp |= 0x0000400; }
+ if ((*sp & 0x0100) == 0) { *w_sp |= 0x0000800; }
+ else { *w_sp |= 0x0001000; }
+ if ((*sp & 0x0200) == 0) { *w_sp |= 0x0002000; }
+ else { *w_sp |= 0x0004000; }
+ if ((*sp & 0x0400) == 0) { *w_sp |= 0x0008000; }
+ else { *w_sp |= 0x0010000; }
+ if ((*sp & 0x0800) == 0) { *w_sp |= 0x0020000; }
+ else { *w_sp |= 0x0040000; }
+ if ((*sp & 0x1000) == 0) { *w_sp |= 0x0080000; }
+ else { *w_sp |= 0x0100000; }
+ if ((*sp & 0x2000) == 0) { *w_sp |= 0x0200000; }
+ else { *w_sp |= 0x0400000; }
+ if ((*sp & 0x4000) == 0) { *w_sp |= 0x0800000; }
+ else { *w_sp |= 0x1000000; }
update_SP();
// dpc_register
unzReadCurrentFile(zipstatefile, &dpc_register.dpc_start, 4);
unzReadCurrentFile(zipstatefile, &dpc_register.dpc_end, 4);
unzReadCurrentFile(zipstatefile, &dpc_register.dpc_current, 4);
- unzReadCurrentFile(zipstatefile, &dpc_register.w_dpc_status, 4);
+ unzReadCurrentFile(zipstatefile, &dpc_register.dpc_status, 4);
unzReadCurrentFile(zipstatefile, &dpc_register.dpc_clock, 4);
unzReadCurrentFile(zipstatefile, &dpc_register.dpc_bufbusy, 4);
unzReadCurrentFile(zipstatefile, &dpc_register.dpc_pipebusy, 4);
unzReadCurrentFile(zipstatefile, &dpc_register.dpc_tmem, 4);
unzReadCurrentFile(zipstatefile, &value, 4); // Dummy read
unzReadCurrentFile(zipstatefile, &value, 4); // Dummy read
+ unsigned int *w_dpc = &dpc_register.w_dpc_status;
+ unsigned int *dpc = &dpc_register.dpc_status;
+ *w_dpc = 0;
+ if ((*dpc & 0x0001) == 0) { *w_dpc |= 0x0000001; }
+ else { *w_dpc |= 0x0000002; }
+ if ((*dpc & 0x0002) == 0) { *w_dpc |= 0x0000004; }
+ else { *w_dpc |= 0x0000008; }
+ if ((*dpc & 0x0004) == 0) { *w_dpc |= 0x0000010; }
+ else { *w_dpc |= 0x0000020; }
update_DPC();
// mi_register
- unzReadCurrentFile(zipstatefile, &MI_register.w_mi_init_mode_reg, 4);
+ unzReadCurrentFile(zipstatefile, &MI_register.mi_init_mode_reg, 4);
unzReadCurrentFile(zipstatefile, &MI_register.mi_version_reg, 4);
unzReadCurrentFile(zipstatefile, &MI_register.mi_intr_reg, 4);
- unzReadCurrentFile(zipstatefile, &MI_register.w_mi_intr_mask_reg, 4);
+ unzReadCurrentFile(zipstatefile, &MI_register.mi_intr_mask_reg, 4);
+ MI_register.w_mi_init_mode_reg = MI_register.mi_init_mode_reg & 0x7F;
+ if ((MI_register.mi_init_mode_reg & 0x080) == 0)
+ { MI_register.w_mi_init_mode_reg |= 0x0000080;
+ } else {
+ MI_register.w_mi_init_mode_reg |= 0x0000100;
+ }
+ if ((MI_register.mi_init_mode_reg & 0x200) == 0) {
+ MI_register.w_mi_init_mode_reg |= 0x0001000;
+ } else {
+ MI_register.w_mi_init_mode_reg |= 0x0002000;
+ }
+ // TODO: Unsecure about 'clear DP interrupt'
(MI_register.w_mi_init_mode_reg[11])
update_MI_intr_mask_reg();
+ unsigned int *w_mi = (unsigned int *) &MI_register.w_mi_intr_mask_reg;
+ unsigned int *mi = (unsigned int *) &MI_register.mi_intr_mask_reg;
+ *w_mi = 0;
+ if ((*mi & 0x01) == 0) { *w_mi |= 0x0000001; }
+ else { *w_mi |= 0x0000002; }
+ if ((*mi & 0x02) == 0) { *w_mi |= 0x0000004; }
+ else { *w_mi |= 0x0000008; }
+ if ((*mi & 0x04) == 0) { *w_mi |= 0x0000010; }
+ else { *w_mi |= 0x0000020; }
+ if ((*mi & 0x08) == 0) { *w_mi |= 0x0000040; }
+ else { *w_mi |= 0x0000080; }
+ if ((*mi & 0x10) == 0) { *w_mi |= 0x0000100; }
+ else { *w_mi |= 0x0000200; }
+ if ((*mi & 0x20) == 0) { *w_mi |= 0x0000400; }
+ else { *w_mi |= 0x0000800; }
update_MI_init_mode_reg();
// vi_register
@@ -640,9 +705,9 @@
// ai_register
unzReadCurrentFile(zipstatefile, &ai_register, 4*6);
- // TODO: Not avialable in PJ64 savestate
+ // TODO: Not avialable in PJ64 savestate. Leave it as is.
// ai_register.next_delay = 0; ai_register.next_len = 0;
- // ai_register.current_delay = 0;//804629; ai_register.current_len = 0;
+ // ai_register.current_delay = 0; ai_register.current_len = 0;
// pi_register
unzReadCurrentFile(zipstatefile, &pi_register, sizeof(PI_register));
I think there needs to be a better way.
Original comment by sknau...@wesleyan.edu
on 22 Feb 2009 at 4:42
Here is one savestate that fail without the above patch
Original comment by olejl77@gmail.com
on 22 Feb 2009 at 5:06
Attachments:
patch committed in rev 1416, the SM64 state file loads now. Thanks olejl77 and
sknauert, sorry it took so long to get it in SVN
Original comment by richard...@gmail.com
on 2 Oct 2009 at 3:23
Wow. I am looking to implement an USF audio player plugin using Mupen64Plus as
a base
— and for this I need a PJ64 savestate loader. October 01, you say ? I'm
lucky :)
Hurray, one less thing to do !
Original comment by kemenaran
on 16 Oct 2009 at 3:04
Hello, I can not seem to get mupen64plus to load Zelda Majoras Mask savestate.
Is there any thing that may possibly be done?
Original comment by kno0...@gmail.com
on 1 Oct 2010 at 1:44
HI !! I'm sure your patch's awesome ! But I can't understand how to use it....
Do you have to say "open *.pj0" "open *.pj0.zip", or is it something else than
open ???
Original comment by pere.so...@gmail.com
on 18 Oct 2010 at 5:41
Original issue reported on code.google.com by
ebenbl...@gmail.com
on 14 Apr 2008 at 6:52