mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: add a loader to replay gs file. Quite shaky but probably enough for debug :)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5052 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
53a5089d7b
commit
21724ddbf8
|
@ -8,6 +8,8 @@ endif(NOT TOP_CMAKE_WAS_SOURCED)
|
|||
|
||||
# plugin name
|
||||
set(Output GSdx-0.1.16)
|
||||
set(Replay pcsx2_GSReplayLoader)
|
||||
set(Static GSdx-static)
|
||||
|
||||
set(CommonFlags
|
||||
-D_LINUX
|
||||
|
@ -179,38 +181,47 @@ set(GSdxHeaders
|
|||
xbyak/xbyak_util.h
|
||||
)
|
||||
|
||||
# add additional include directories
|
||||
include_directories(.)
|
||||
|
||||
# add library
|
||||
add_library(${Output} SHARED
|
||||
${GSdxSources}
|
||||
${GSdxHeaders}
|
||||
)
|
||||
add_library(${Output} SHARED ${GSdxSources} ${GSdxHeaders})
|
||||
|
||||
add_library(${Static} STATIC ${GSdxSources} ${GSdxHeaders})
|
||||
|
||||
add_executable(${Replay} linux_replay.cpp)
|
||||
|
||||
# link target with X11
|
||||
target_link_libraries(${Output} ${X11_LIBRARIES})
|
||||
target_link_libraries(${Output} ${GLEW_LIBRARY})
|
||||
target_link_libraries(${Output} ${OPENGL_LIBRARIES})
|
||||
|
||||
if(projectSDL)
|
||||
target_link_libraries(${Output} ${SDL_LIBRARY})
|
||||
endif(projectSDL)
|
||||
|
||||
# link target with glew
|
||||
target_link_libraries(${Output} ${GLEW_LIBRARY})
|
||||
target_link_libraries(${Replay} ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(${Replay} ${X11_LIBRARIES})
|
||||
target_link_libraries(${Replay} ${GLEW_LIBRARY})
|
||||
target_link_libraries(${Replay} ${GTK2_LIBRARIES})
|
||||
target_link_libraries(${Replay} ${Static})
|
||||
|
||||
|
||||
# User flags options
|
||||
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
||||
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
|
||||
endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
||||
|
||||
if(PACKAGE_MODE)
|
||||
install(TARGETS ${Replay} DESTINATION bin)
|
||||
|
||||
install(TARGETS ${Output} DESTINATION ${PLUGIN_DIR})
|
||||
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${PLUGIN_DIR})
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${PLUGIN_DIR})
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${PLUGIN_DIR})
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/tfx.glsl DESTINATION ${PLUGIN_DIR})
|
||||
else(PACKAGE_MODE)
|
||||
install(TARGETS ${Replay} DESTINATION ${CMAKE_SOURCE_DIR}/bin)
|
||||
|
||||
install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
||||
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
|
||||
|
|
|
@ -1084,3 +1084,190 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _LINUX
|
||||
|
||||
// Note
|
||||
EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
|
||||
{
|
||||
|
||||
|
||||
// lpszCmdLine:
|
||||
// First parameter is the renderer.
|
||||
// Second parameter is the gs file to load and run.
|
||||
|
||||
//EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
|
||||
#if 0
|
||||
int renderer = -1;
|
||||
|
||||
{
|
||||
char* start = lpszCmdLine;
|
||||
char* end = NULL;
|
||||
long n = strtol(lpszCmdLine, &end, 10);
|
||||
if(end > start) {renderer = n; lpszCmdLine = end;}
|
||||
}
|
||||
|
||||
while(*lpszCmdLine == ' ') lpszCmdLine++;
|
||||
|
||||
::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);
|
||||
#endif
|
||||
|
||||
if(FILE* fp = fopen(lpszCmdLine, "rb"))
|
||||
{
|
||||
//Console console("GSdx", true);
|
||||
|
||||
GSinit();
|
||||
|
||||
uint8 regs[0x2000];
|
||||
GSsetBaseMem(regs);
|
||||
|
||||
s_vsync = !!theApp.GetConfig("vsync", 0);
|
||||
|
||||
void* hWnd = NULL;
|
||||
|
||||
_GSopen((void**)&hWnd, "", renderer);
|
||||
|
||||
uint32 crc;
|
||||
fread(&crc, 4, 1, fp);
|
||||
GSsetGameCRC(crc, 0);
|
||||
|
||||
GSFreezeData fd;
|
||||
fread(&fd.size, 4, 1, fp);
|
||||
fd.data = new uint8[fd.size];
|
||||
fread(fd.data, fd.size, 1, fp);
|
||||
GSfreeze(FREEZE_LOAD, &fd);
|
||||
delete [] fd.data;
|
||||
|
||||
fread(regs, 0x2000, 1, fp);
|
||||
|
||||
long start = ftell(fp);
|
||||
|
||||
GSvsync(1);
|
||||
|
||||
struct Packet {uint8 type, param; uint32 size, addr; vector<uint8> buff;};
|
||||
|
||||
list<Packet*> packets;
|
||||
vector<uint8> buff;
|
||||
int type;
|
||||
|
||||
while((type = fgetc(fp)) != EOF)
|
||||
{
|
||||
Packet* p = new Packet();
|
||||
|
||||
p->type = (uint8)type;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
|
||||
p->param = (uint8)fgetc(fp);
|
||||
|
||||
fread(&p->size, 4, 1, fp);
|
||||
|
||||
switch(p->param)
|
||||
{
|
||||
case 0:
|
||||
p->buff.resize(0x4000);
|
||||
p->addr = 0x4000 - p->size;
|
||||
fread(&p->buff[p->addr], p->size, 1, fp);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
p->buff.resize(p->size);
|
||||
fread(&p->buff[0], p->size, 1, fp);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
p->param = (uint8)fgetc(fp);
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
fread(&p->size, 4, 1, fp);
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
p->buff.resize(0x2000);
|
||||
|
||||
fread(&p->buff[0], 0x2000, 1, fp);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
packets.push_back(p);
|
||||
}
|
||||
|
||||
sleep(30);
|
||||
// FIXME too slow :p
|
||||
// sleep(100);
|
||||
|
||||
//while(IsWindowVisible(hWnd))
|
||||
//FIXME map?
|
||||
while(true)
|
||||
{
|
||||
for(auto i = packets.begin(); i != packets.end(); i++)
|
||||
{
|
||||
Packet* p = *i;
|
||||
|
||||
switch(p->type)
|
||||
{
|
||||
case 0:
|
||||
|
||||
switch(p->param)
|
||||
{
|
||||
case 0: GSgifTransfer1(&p->buff[0], p->addr); break;
|
||||
case 1: GSgifTransfer2(&p->buff[0], p->size / 16); break;
|
||||
case 2: GSgifTransfer3(&p->buff[0], p->size / 16); break;
|
||||
case 3: GSgifTransfer(&p->buff[0], p->size / 16); break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
GSvsync(p->param);
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
if(buff.size() < p->size) buff.resize(p->size);
|
||||
|
||||
GSreadFIFO2(&buff[0], p->size / 16);
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
memcpy(regs, &p->buff[0], 0x2000);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto i = packets.begin(); i != packets.end(); i++)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
|
||||
packets.clear();
|
||||
|
||||
sleep(100);
|
||||
|
||||
GSclose();
|
||||
GSshutdown();
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
s = glGetString(GL_VERSION);
|
||||
if (s == NULL) return false;
|
||||
|
||||
GLuint dot;
|
||||
GLuint dot = 0;
|
||||
while (s[dot] != '\0' && s[dot] != '.') dot++;
|
||||
if (dot == 0) return false;
|
||||
|
||||
|
|
|
@ -331,18 +331,11 @@ GSWnd::~GSWnd()
|
|||
}
|
||||
}
|
||||
|
||||
bool GSWnd::Attach(void* handle, bool managed)
|
||||
bool GSWnd::CreateContext(int major, int minor)
|
||||
{
|
||||
m_Xwindow = *(Window*)handle;
|
||||
m_managed = managed;
|
||||
|
||||
m_renderer = theApp.GetConfig("renderer", 0) / 3;
|
||||
if (m_renderer != 2) {
|
||||
m_XDisplay = XOpenDisplay(NULL);
|
||||
|
||||
if ( !m_XDisplay )
|
||||
if ( !m_XDisplay || !m_Xwindow )
|
||||
{
|
||||
fprintf( stderr, "Failed to open X display\n" );
|
||||
fprintf( stderr, "Wrong X11 display/window\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -371,29 +364,56 @@ bool GSWnd::Attach(void* handle, bool managed)
|
|||
// Create a context
|
||||
int context_attribs[] =
|
||||
{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
// Note: 4.2 crash on latest nvidia drivers!
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, major,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, minor,
|
||||
// FIXME : Request a debug context to ease opengl development
|
||||
// Note: don't support deprecated feature (pre openg 3.1)
|
||||
//GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
|
||||
None
|
||||
};
|
||||
|
||||
m_context = glXCreateContextAttribsARB(m_XDisplay, fbc[0], 0, true, context_attribs);
|
||||
XSync( m_XDisplay, false);
|
||||
|
||||
if (!m_context) return false;
|
||||
glXMakeCurrent(m_XDisplay, m_Xwindow, m_context);
|
||||
|
||||
// Check the status
|
||||
XSync( m_XDisplay, false);
|
||||
}
|
||||
|
||||
void GSWnd::AttachContext()
|
||||
{
|
||||
glXMakeCurrent(m_XDisplay, m_Xwindow, m_context);
|
||||
}
|
||||
|
||||
void GSWnd::DetachContext()
|
||||
{
|
||||
glXMakeCurrent(m_XDisplay, None, NULL);
|
||||
}
|
||||
|
||||
void GSWnd::CheckContext()
|
||||
{
|
||||
int glxMajorVersion, glxMinorVersion;
|
||||
glXQueryVersion(m_XDisplay, &glxMajorVersion, &glxMinorVersion);
|
||||
if (glXIsDirect(m_XDisplay, m_context))
|
||||
fprintf(stderr, "glX-Version %d.%d with Direct Rendering\n", glxMajorVersion, glxMinorVersion);
|
||||
else
|
||||
fprintf(stderr, "glX-Version %d.%d with Indirect Rendering !!! It will be slow\n", glxMajorVersion, glxMinorVersion);
|
||||
}
|
||||
|
||||
bool GSWnd::Attach(void* handle, bool managed)
|
||||
{
|
||||
m_Xwindow = *(Window*)handle;
|
||||
m_managed = managed;
|
||||
|
||||
m_renderer = theApp.GetConfig("renderer", 0) / 3;
|
||||
if (m_renderer != 2) {
|
||||
m_XDisplay = XOpenDisplay(NULL);
|
||||
|
||||
// Note: 4.2 crash on latest nvidia drivers!
|
||||
if (!CreateContext(3, 3)) return false;
|
||||
|
||||
AttachContext();
|
||||
|
||||
CheckContext();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -412,7 +432,7 @@ void GSWnd::Detach()
|
|||
}
|
||||
#endif
|
||||
} else {
|
||||
glXMakeCurrent(m_XDisplay, None, NULL);
|
||||
DetachContext();
|
||||
if (m_context) glXDestroyContext(m_XDisplay, m_context);
|
||||
}
|
||||
if (m_XDisplay) {
|
||||
|
@ -462,7 +482,43 @@ bool GSWnd::Create(const string& title, int w, int h)
|
|||
|
||||
return (m_window != NULL);
|
||||
#else
|
||||
return false;
|
||||
|
||||
// note this part must be only executed when replaying .gs debug file
|
||||
m_managed = true;
|
||||
|
||||
m_XDisplay = XOpenDisplay(NULL);
|
||||
|
||||
int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 24,
|
||||
None
|
||||
};
|
||||
XVisualInfo* vi = glXChooseVisual(m_XDisplay, DefaultScreen(m_XDisplay), attrListDbl);
|
||||
|
||||
/* create a color map */
|
||||
XSetWindowAttributes attr;
|
||||
attr.colormap = XCreateColormap(m_XDisplay, RootWindow(m_XDisplay, vi->screen),
|
||||
vi->visual, AllocNone);
|
||||
attr.border_pixel = 0;
|
||||
attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask |
|
||||
StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask |
|
||||
EnterWindowMask | LeaveWindowMask | FocusChangeMask ;
|
||||
|
||||
// Create a window at the last position/size
|
||||
m_Xwindow = XCreateWindow(m_XDisplay, RootWindow(m_XDisplay, vi->screen),
|
||||
0 , 0 , w, h, 0, vi->depth, InputOutput, vi->visual,
|
||||
CWBorderPixel | CWColormap | CWEventMask, &attr);
|
||||
|
||||
XMapWindow (m_XDisplay, m_Xwindow);
|
||||
XFree(vi);
|
||||
|
||||
if (!CreateContext(3, 3)) return false;
|
||||
|
||||
AttachContext();
|
||||
|
||||
return (m_Xwindow != 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -480,7 +536,8 @@ Display* GSWnd::GetDisplay()
|
|||
|
||||
return wminfo.subsystem == SDL_SYSWM_X11 ? wminfo.info.x11.display : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
// note this part must be only executed when replaying .gs debug file
|
||||
return m_XDisplay;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ class GSWnd
|
|||
#endif
|
||||
Window m_Xwindow;
|
||||
Display* m_XDisplay;
|
||||
|
||||
bool m_managed;
|
||||
int m_renderer;
|
||||
GLXContext m_context;
|
||||
|
@ -123,6 +124,11 @@ public:
|
|||
void SetWindow(SDL_Window* current_window) { if (current_window) m_window = current_window; }
|
||||
#endif
|
||||
|
||||
bool CreateContext(int major, int minor);
|
||||
void AttachContext();
|
||||
void DetachContext();
|
||||
void CheckContext();
|
||||
|
||||
void Show();
|
||||
void Hide();
|
||||
void HideFrame();
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) 20011-2012 Hainaut gregory
|
||||
*
|
||||
* This Program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This Program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
EXPORT_C GSsetSettingsDir(const char* dir);
|
||||
EXPORT_C GSReplay(char* lpszCmdLine, int renderer);
|
||||
|
||||
|
||||
void help()
|
||||
{
|
||||
fprintf(stderr, "Loader gs file\n");
|
||||
fprintf(stderr, "ARG1 Ini directory\n");
|
||||
fprintf(stderr, "ARG2 .gs file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main ( int argc, char *argv[] )
|
||||
{
|
||||
if ( argc != 3 ) help();
|
||||
|
||||
GSsetSettingsDir(argv[1]);
|
||||
GSReplay(argv[2], 12);
|
||||
}
|
Loading…
Reference in New Issue