1 |
william |
31 |
/* PCSX2 - PS2 Emulator for PCs |
2 |
|
|
* Copyright (C) 2002-2010 PCSX2 Dev Team |
3 |
|
|
* |
4 |
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms |
5 |
|
|
* of the GNU Lesser General Public License as published by the Free Software Found- |
6 |
|
|
* ation, either version 3 of the License, or (at your option) any later version. |
7 |
|
|
* |
8 |
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
9 |
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
10 |
|
|
* PURPOSE. See the GNU General Public License for more details. |
11 |
|
|
* |
12 |
|
|
* You should have received a copy of the GNU General Public License along with PCSX2. |
13 |
|
|
* If not, see <http://www.gnu.org/licenses/>. |
14 |
|
|
*/ |
15 |
|
|
|
16 |
|
|
#include "PrecompiledHeader.h" |
17 |
|
|
|
18 |
|
|
#include <list> |
19 |
|
|
|
20 |
|
|
#include "GS.h" |
21 |
|
|
|
22 |
|
|
#ifdef PCSX2_DEVBUILD |
23 |
|
|
|
24 |
|
|
// GS Playback |
25 |
|
|
int g_SaveGSStream = 0; // save GS stream; 1 - prepare, 2 - save |
26 |
|
|
int g_nLeftGSFrames = 0; // when saving, number of frames left |
27 |
|
|
static ScopedPtr<memSavingState> g_fGSSave; |
28 |
|
|
|
29 |
|
|
// fixme - need to take this concept and make it MTGS friendly. |
30 |
|
|
#ifdef _STGS_GSSTATE_CODE |
31 |
|
|
void GSGIFTRANSFER1(u32 *pMem, u32 addr) { |
32 |
|
|
if( g_SaveGSStream == 2) { |
33 |
|
|
u32 type = GSRUN_TRANS1; |
34 |
|
|
u32 size = (0x4000-(addr))/16; |
35 |
|
|
g_fGSSave->Freeze( type ); |
36 |
|
|
g_fGSSave->Freeze( size ); |
37 |
|
|
g_fGSSave->FreezeMem( ((u8*)pMem)+(addr), size*16 ); |
38 |
|
|
} |
39 |
|
|
GSgifTransfer1(pMem, addr); |
40 |
|
|
} |
41 |
|
|
|
42 |
|
|
void GSGIFTRANSFER2(u32 *pMem, u32 size) { |
43 |
|
|
if( g_SaveGSStream == 2) { |
44 |
|
|
u32 type = GSRUN_TRANS2; |
45 |
|
|
u32 _size = size; |
46 |
|
|
g_fGSSave->Freeze( type ); |
47 |
|
|
g_fGSSave->Freeze( size ); |
48 |
|
|
g_fGSSave->FreezeMem( pMem, _size*16 ); |
49 |
|
|
} |
50 |
|
|
GSgifTransfer2(pMem, size); |
51 |
|
|
} |
52 |
|
|
|
53 |
|
|
void GSGIFTRANSFER3(u32 *pMem, u32 size) { |
54 |
|
|
if( g_SaveGSStream == 2 ) { |
55 |
|
|
u32 type = GSRUN_TRANS3; |
56 |
|
|
u32 _size = size; |
57 |
|
|
g_fGSSave->Freeze( type ); |
58 |
|
|
g_fGSSave->Freeze( size ); |
59 |
|
|
g_fGSSave->FreezeMem( pMem, _size*16 ); |
60 |
|
|
} |
61 |
|
|
GSgifTransfer3(pMem, size); |
62 |
|
|
} |
63 |
|
|
|
64 |
|
|
__forceinline void GSVSYNC(void) { |
65 |
|
|
if( g_SaveGSStream == 2 ) { |
66 |
|
|
u32 type = GSRUN_VSYNC; |
67 |
|
|
g_fGSSave->Freeze( type ); |
68 |
|
|
} |
69 |
|
|
} |
70 |
|
|
#endif |
71 |
|
|
|
72 |
|
|
/*void SaveGSState(const wxString& file) |
73 |
|
|
{ |
74 |
|
|
if( g_SaveGSStream ) return; |
75 |
|
|
|
76 |
|
|
Console.WriteLn( "Saving GS State..." ); |
77 |
|
|
Console.WriteLn( L"\t%s", file.c_str() ); |
78 |
|
|
|
79 |
|
|
SafeArray<u8> buf; |
80 |
|
|
g_fGSSave = new memSavingState( buf ); |
81 |
|
|
|
82 |
|
|
g_SaveGSStream = 1; |
83 |
|
|
g_nLeftGSFrames = 2; |
84 |
|
|
|
85 |
|
|
g_fGSSave->Freeze( g_nLeftGSFrames ); |
86 |
|
|
} |
87 |
|
|
|
88 |
|
|
void LoadGSState(const wxString& file) |
89 |
|
|
{ |
90 |
|
|
int ret; |
91 |
|
|
|
92 |
|
|
Console.WriteLn( "Loading GS State..." ); |
93 |
|
|
|
94 |
|
|
wxString src( file ); |
95 |
|
|
|
96 |
|
|
//if( !wxFileName::FileExists( src ) ) |
97 |
|
|
// src = Path::Combine( g_Conf->Folders.Savestates, src ); |
98 |
|
|
|
99 |
|
|
if( !wxFileName::FileExists( src ) ) |
100 |
|
|
return; |
101 |
|
|
|
102 |
|
|
SafeArray<u8> buf; |
103 |
|
|
memLoadingState f( buf ); |
104 |
|
|
|
105 |
|
|
// Always set gsIrq callback -- GS States are always exclusionary of MTGS mode |
106 |
|
|
GSirqCallback( gsIrq ); |
107 |
|
|
|
108 |
|
|
ret = GSopen(&pDsp, "PCSX2", 0); |
109 |
|
|
if (ret != 0) |
110 |
|
|
throw Exception::PluginOpenError( PluginId_GS ); |
111 |
|
|
|
112 |
|
|
ret = PADopen((void *)&pDsp); |
113 |
|
|
|
114 |
|
|
f.Freeze(g_nLeftGSFrames); |
115 |
|
|
f.gsFreeze(); |
116 |
|
|
|
117 |
|
|
GetPluginManager().Freeze( PluginId_GS, f ); |
118 |
|
|
|
119 |
|
|
RunGSState( f ); |
120 |
|
|
|
121 |
|
|
GetCorePlugins().Close( PluginId_GS ); |
122 |
|
|
GetCorePlugins().Close( PluginId_PAD ); |
123 |
|
|
} |
124 |
|
|
|
125 |
|
|
struct GSStatePacket |
126 |
|
|
{ |
127 |
|
|
u32 type; |
128 |
|
|
std::vector<u8> mem; |
129 |
|
|
}; |
130 |
|
|
|
131 |
|
|
// runs the GS |
132 |
|
|
// (this should really be part of the AppGui) |
133 |
|
|
void RunGSState( memLoadingState& f ) |
134 |
|
|
{ |
135 |
|
|
u32 newfield; |
136 |
|
|
std::list< GSStatePacket > packets; |
137 |
|
|
|
138 |
|
|
while( !f.IsFinished() ) |
139 |
|
|
{ |
140 |
|
|
int type, size; |
141 |
|
|
f.Freeze( type ); |
142 |
|
|
|
143 |
|
|
if( type != GSRUN_VSYNC ) f.Freeze( size ); |
144 |
|
|
|
145 |
|
|
packets.push_back(GSStatePacket()); |
146 |
|
|
GSStatePacket& p = packets.back(); |
147 |
|
|
|
148 |
|
|
p.type = type; |
149 |
|
|
|
150 |
|
|
if( type != GSRUN_VSYNC ) { |
151 |
|
|
p.mem.resize(size*16); |
152 |
|
|
f.FreezeMem( &p.mem[0], size*16 ); |
153 |
|
|
} |
154 |
|
|
} |
155 |
|
|
|
156 |
|
|
std::list<GSStatePacket>::iterator it = packets.begin(); |
157 |
|
|
g_SaveGSStream = 3; |
158 |
|
|
|
159 |
|
|
// first extract the data |
160 |
|
|
while(1) { |
161 |
|
|
|
162 |
|
|
switch(it->type) { |
163 |
|
|
case GSRUN_TRANS1: |
164 |
|
|
GSgifTransfer1((u32*)&it->mem[0], 0); |
165 |
|
|
break; |
166 |
|
|
case GSRUN_TRANS2: |
167 |
|
|
GSgifTransfer2((u32*)&it->mem[0], it->mem.size()/16); |
168 |
|
|
break; |
169 |
|
|
case GSRUN_TRANS3: |
170 |
|
|
GSgifTransfer3((u32*)&it->mem[0], it->mem.size()/16); |
171 |
|
|
break; |
172 |
|
|
case GSRUN_VSYNC: |
173 |
|
|
// flip |
174 |
|
|
newfield = (*(u32*)(PS2MEM_GS+0x1000)&0x2000) ? 0 : 0x2000; |
175 |
|
|
*(u32*)(PS2MEM_GS+0x1000) = (*(u32*)(PS2MEM_GS+0x1000) & ~(1<<13)) | newfield; |
176 |
|
|
|
177 |
|
|
GSvsync(newfield); |
178 |
|
|
|
179 |
|
|
// fixme : Process pending app messages here. |
180 |
|
|
//SysUpdate(); |
181 |
|
|
|
182 |
|
|
if( g_SaveGSStream != 3 ) |
183 |
|
|
return; |
184 |
|
|
break; |
185 |
|
|
|
186 |
|
|
jNO_DEFAULT |
187 |
|
|
} |
188 |
|
|
|
189 |
|
|
++it; |
190 |
|
|
if( it == packets.end() ) |
191 |
|
|
it = packets.begin(); |
192 |
|
|
} |
193 |
|
|
}*/ |
194 |
|
|
#endif |
195 |
|
|
|
196 |
|
|
////////////////////////////////////////////////////////////////////////////////////////// |
197 |
|
|
// |
198 |
|
|
void vSyncDebugStuff( uint frame ) |
199 |
|
|
{ |
200 |
|
|
#ifdef OLD_TESTBUILD_STUFF |
201 |
|
|
if( g_TestRun.enabled && g_TestRun.frame > 0 ) { |
202 |
|
|
if( frame > g_TestRun.frame ) { |
203 |
|
|
// take a snapshot |
204 |
|
|
if( g_TestRun.pimagename != NULL && GSmakeSnapshot2 != NULL ) { |
205 |
|
|
if( g_TestRun.snapdone ) { |
206 |
|
|
g_TestRun.curimage++; |
207 |
|
|
g_TestRun.snapdone = 0; |
208 |
|
|
g_TestRun.frame += 20; |
209 |
|
|
if( g_TestRun.curimage >= g_TestRun.numimages ) { |
210 |
|
|
// exit |
211 |
|
|
g_EmuThread->Cancel(); |
212 |
|
|
} |
213 |
|
|
} |
214 |
|
|
else { |
215 |
|
|
// query for the image |
216 |
|
|
GSmakeSnapshot2(g_TestRun.pimagename, &g_TestRun.snapdone, g_TestRun.jpgcapture); |
217 |
|
|
} |
218 |
|
|
} |
219 |
|
|
else { |
220 |
|
|
// exit |
221 |
|
|
g_EmuThread->Cancel(); |
222 |
|
|
} |
223 |
|
|
} |
224 |
|
|
} |
225 |
|
|
|
226 |
|
|
GSVSYNC(); |
227 |
|
|
|
228 |
|
|
if( g_SaveGSStream == 1 ) { |
229 |
|
|
freezeData fP; |
230 |
|
|
|
231 |
|
|
g_SaveGSStream = 2; |
232 |
|
|
g_fGSSave->gsFreeze(); |
233 |
|
|
|
234 |
|
|
if (GSfreeze(FREEZE_SIZE, &fP) == -1) { |
235 |
|
|
safe_delete( g_fGSSave ); |
236 |
|
|
g_SaveGSStream = 0; |
237 |
|
|
} |
238 |
|
|
else { |
239 |
|
|
fP.data = (s8*)malloc(fP.size); |
240 |
|
|
if (fP.data == NULL) { |
241 |
|
|
safe_delete( g_fGSSave ); |
242 |
|
|
g_SaveGSStream = 0; |
243 |
|
|
} |
244 |
|
|
else { |
245 |
|
|
if (GSfreeze(FREEZE_SAVE, &fP) == -1) { |
246 |
|
|
safe_delete( g_fGSSave ); |
247 |
|
|
g_SaveGSStream = 0; |
248 |
|
|
} |
249 |
|
|
else { |
250 |
|
|
g_fGSSave->Freeze( fP.size ); |
251 |
|
|
if (fP.size) { |
252 |
|
|
g_fGSSave->FreezeMem( fP.data, fP.size ); |
253 |
|
|
free(fP.data); |
254 |
|
|
} |
255 |
|
|
} |
256 |
|
|
} |
257 |
|
|
} |
258 |
|
|
} |
259 |
|
|
else if( g_SaveGSStream == 2 ) { |
260 |
|
|
|
261 |
|
|
if( --g_nLeftGSFrames <= 0 ) { |
262 |
|
|
safe_delete( g_fGSSave ); |
263 |
|
|
g_SaveGSStream = 0; |
264 |
|
|
Console.WriteLn("Done saving GS stream"); |
265 |
|
|
} |
266 |
|
|
} |
267 |
|
|
#endif |
268 |
|
|
} |