mupen64plus-oldsvn/glN64/glN64.cpp

434 lines
11 KiB
C++

#ifndef __LINUX__ //Change me...
#include <windows.h>
#include <commctrl.h>
#include <process.h>
#else
#include <string.h>
#include "../main/winlnxdefs.h"
#endif
#ifdef QT4_GUI
# include <QMessageBox>
#endif
#include <SDL_opengl.h>
#include "glN64.h"
#include "Debug.h"
#include "Zilmar GFX 1.3.h"
#include "OpenGL.h"
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "VI.h"
#include "Config.h"
#include "Textures.h"
#include "Combiner.h"
#ifndef __LINUX__
HWND hWnd;
HWND hStatusBar;
//HWND hFullscreen;
HWND hToolBar;
HINSTANCE hInstance;
#endif // !__LINUX__
char pluginName[] = "glN64 v0.4.1";
char *screenDirectory;
u32 last_good_ucode = 0;
void (*CheckInterrupts)( void );
char configdir[PATH_MAX] = {0};
void (*renderCallback)() = NULL;
#ifndef __LINUX__
LONG windowedStyle;
LONG windowedExStyle;
RECT windowedRect;
HMENU windowedMenu;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
hInstance = hinstDLL;
if (dwReason == DLL_PROCESS_ATTACH)
{
Config_LoadConfig();
RSP.thread = NULL;
OGL.hRC = NULL;
OGL.hDC = NULL;
/* OGL.hPbufferRC = NULL;
OGL.hPbufferDC = NULL;
OGL.hPbuffer = NULL;*/
// hFullscreen = NULL;
}
return TRUE;
}
#else
void
_init( void )
{
Config_LoadConfig();
OGL.hScreen = NULL;
# ifdef RSPTHREAD
RSP.thread = NULL;
# endif
}
#endif // !__LINUX__
EXPORT void CALL CaptureScreen ( char * Directory )
{
screenDirectory = Directory;
#ifdef RSPTHREAD
if (RSP.thread)
{
SetEvent( RSP.threadMsg[RSPMSG_CAPTURESCREEN] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
}
#else
OGL_SaveScreenshot();
#endif
}
EXPORT void CALL ChangeWindow (void)
{
#ifdef RSPTHREAD
// Textures seem to get corrupted when changing video modes (at least on my Radeon), so destroy them
SetEvent( RSP.threadMsg[RSPMSG_DESTROYTEXTURES] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
if (!OGL.fullscreen)
{
DEVMODE fullscreenMode;
memset( &fullscreenMode, 0, sizeof(DEVMODE) );
fullscreenMode.dmSize = sizeof(DEVMODE);
fullscreenMode.dmPelsWidth = OGL.fullscreenWidth;
fullscreenMode.dmPelsHeight = OGL.fullscreenHeight;
fullscreenMode.dmBitsPerPel = OGL.fullscreenBits;
fullscreenMode.dmDisplayFrequency = OGL.fullscreenRefresh;
fullscreenMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
if (ChangeDisplaySettings( &fullscreenMode, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL)
{
MessageBox( NULL, "Failed to change display mode", pluginName, MB_ICONERROR | MB_OK );
return;
}
ShowCursor( FALSE );
windowedMenu = GetMenu( hWnd );
if (windowedMenu)
SetMenu( hWnd, NULL );
if (hStatusBar)
ShowWindow( hStatusBar, SW_HIDE );
windowedExStyle = GetWindowLong( hWnd, GWL_EXSTYLE );
windowedStyle = GetWindowLong( hWnd, GWL_STYLE );
SetWindowLong( hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST );
SetWindowLong( hWnd, GWL_STYLE, WS_POPUP );
GetWindowRect( hWnd, &windowedRect );
OGL.fullscreen = TRUE;
OGL_ResizeWindow();
}
else
{
ChangeDisplaySettings( NULL, 0 );
ShowCursor( TRUE );
if (windowedMenu)
SetMenu( hWnd, windowedMenu );
if (hStatusBar)
ShowWindow( hStatusBar, SW_SHOW );
SetWindowLong( hWnd, GWL_STYLE, windowedStyle );
SetWindowLong( hWnd, GWL_EXSTYLE, windowedExStyle );
SetWindowPos( hWnd, NULL, windowedRect.left, windowedRect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE );
OGL.fullscreen = FALSE;
OGL_ResizeWindow();
}
SetEvent( RSP.threadMsg[RSPMSG_INITTEXTURES] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
#else // RSPTHREAD
# ifdef __LINUX__
SDL_WM_ToggleFullScreen( OGL.hScreen );
# endif // __LINUX__
#endif // !RSPTHREAD
}
EXPORT void CALL CloseDLL (void)
{
}
EXPORT void CALL DllAbout ( HWND hParent )
{
#ifndef __LINUX__
MessageBox( hParent, "glN64 v0.4 by Orkin\n\nWebsite: http://gln64.emulation64.com/\n\nThanks to Clements, Rice, Gonetz, Malcolm, Dave2001, cryhlove, icepir8, zilmar, Azimer, and StrmnNrmn", pluginName, MB_OK | MB_ICONINFORMATION );
#else
# ifdef QT4_GUI
QMessageBox::about(QWidget::find(hParent),
"About glN64",
"glN64 v0.4 by Orkin\nWebsite: http://gln64.emulation64.com/\n\nThanks to Clements, Rice, Gonetz, Malcolm, Dave2001, cryhlove, icepir8, zilmar, Azimer, and StrmnNrmn\nported by blight\nQt4 interface by slougi");
# else
puts( "glN64 v0.4 by Orkin\nWebsite: http://gln64.emulation64.com/\n\nThanks to Clements, Rice, Gonetz, Malcolm, Dave2001, cryhlove, icepir8, zilmar, Azimer, and StrmnNrmn\nported by blight" );
# endif // QT4_GUI
#endif
}
EXPORT void CALL DllConfig ( HWND hParent )
{
Config_DoConfig(hParent);
}
EXPORT void CALL DllTest ( HWND hParent )
{
#ifdef QT4_GUI
QMessageBox::information(QWidget::find(hParent),
"glN64 Test",
"This plugin has nothing to test.");
#endif
}
EXPORT void CALL DrawScreen (void)
{
}
EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo )
{
PluginInfo->Version = 0x103;
PluginInfo->Type = PLUGIN_TYPE_GFX;
strcpy( PluginInfo->Name, pluginName );
PluginInfo->NormalMemory = FALSE;
PluginInfo->MemoryBswaped = TRUE;
}
#ifndef __LINUX__
BOOL CALLBACK FindToolBarProc( HWND hWnd, LPARAM lParam )
{
if (GetWindowLong( hWnd, GWL_STYLE ) & RBS_VARHEIGHT)
{
hToolBar = hWnd;
return FALSE;
}
return TRUE;
}
#endif // !__LINUX__
EXPORT BOOL CALL InitiateGFX (GFX_INFO Gfx_Info)
{
#ifndef __LINUX__
hWnd = Gfx_Info.hWnd;
hStatusBar = Gfx_Info.hStatusBar;
hToolBar = NULL;
EnumChildWindows( hWnd, FindToolBarProc,0 );
#else // !__LINUX__
Config_LoadConfig();
OGL.hScreen = NULL;
# ifdef RSPTHREAD
RSP.thread = NULL;
# endif
#endif // __LINUX__
DMEM = Gfx_Info.DMEM;
IMEM = Gfx_Info.IMEM;
RDRAM = Gfx_Info.RDRAM;
REG.MI_INTR = (u32*) Gfx_Info.MI_INTR_REG;
REG.DPC_START = (u32*) Gfx_Info.DPC_START_REG;
REG.DPC_END = (u32*) Gfx_Info.DPC_END_REG;
REG.DPC_CURRENT = (u32*) Gfx_Info.DPC_CURRENT_REG;
REG.DPC_STATUS = (u32*) Gfx_Info.DPC_STATUS_REG;
REG.DPC_CLOCK = (u32*) Gfx_Info.DPC_CLOCK_REG;
REG.DPC_BUFBUSY = (u32*) Gfx_Info.DPC_BUFBUSY_REG;
REG.DPC_PIPEBUSY = (u32*) Gfx_Info.DPC_PIPEBUSY_REG;
REG.DPC_TMEM = (u32*) Gfx_Info.DPC_TMEM_REG;
REG.VI_STATUS = (u32*) Gfx_Info.VI_STATUS_REG;
REG.VI_ORIGIN = (u32*) Gfx_Info.VI_ORIGIN_REG;
REG.VI_WIDTH = (u32*) Gfx_Info.VI_WIDTH_REG;
REG.VI_INTR = (u32*) Gfx_Info.VI_INTR_REG;
REG.VI_V_CURRENT_LINE = (u32*) Gfx_Info.VI_V_CURRENT_LINE_REG;
REG.VI_TIMING = (u32*) Gfx_Info.VI_TIMING_REG;
REG.VI_V_SYNC = (u32*) Gfx_Info.VI_V_SYNC_REG;
REG.VI_H_SYNC = (u32*) Gfx_Info.VI_H_SYNC_REG;
REG.VI_LEAP = (u32*) Gfx_Info.VI_LEAP_REG;
REG.VI_H_START = (u32*) Gfx_Info.VI_H_START_REG;
REG.VI_V_START = (u32*) Gfx_Info.VI_V_START_REG;
REG.VI_V_BURST = (u32*) Gfx_Info.VI_V_BURST_REG;
REG.VI_X_SCALE = (u32*) Gfx_Info.VI_X_SCALE_REG;
REG.VI_Y_SCALE = (u32*) Gfx_Info.VI_Y_SCALE_REG;
CheckInterrupts = Gfx_Info.CheckInterrupts;
return TRUE;
}
EXPORT void CALL MoveScreen (int xpos, int ypos)
{
}
EXPORT void CALL ProcessDList(void)
{
#ifdef RSPTHREAD
if (RSP.thread)
{
SetEvent( RSP.threadMsg[RSPMSG_PROCESSDLIST] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
}
#else
RSP_ProcessDList();
#endif
}
EXPORT void CALL ProcessRDPList(void)
{
//*REG.DPC_CURRENT = *REG.DPC_START;
/* RSP.PCi = 0;
RSP.PC[RSP.PCi] = *REG.DPC_CURRENT;
RSP.halt = FALSE;
while (RSP.PC[RSP.PCi] < *REG.DPC_END)
{
RSP.cmd0 = *(DWORD*)&RDRAM[RSP.PC[RSP.PCi]];
RSP.cmd1 = *(DWORD*)&RDRAM[RSP.PC[RSP.PCi] + 4];
RSP.PC[RSP.PCi] += 8;
*/
/* if ((RSP.cmd0 >> 24) == 0xE9)
{
*REG.MI_INTR |= MI_INTR_DP;
CheckInterrupts();
}
if ((RSP.cmd0 >> 24) == 0xCD)
RSP.cmd0 = RSP.cmd0;
GFXOp[RSP.cmd0 >> 24]();*/
//*REG.DPC_CURRENT += 8;
// }
}
EXPORT void CALL RomClosed (void)
{
#ifdef RSPTHREAD
int i;
if (RSP.thread)
{
// if (OGL.fullscreen)
// ChangeWindow();
if (RSP.busy)
{
RSP.halt = TRUE;
WaitForSingleObject( RSP.threadFinished, INFINITE );
}
SetEvent( RSP.threadMsg[RSPMSG_CLOSE] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
for (i = 0; i < 4; i++)
if (RSP.threadMsg[i])
CloseHandle( RSP.threadMsg[i] );
CloseHandle( RSP.threadFinished );
CloseHandle( RSP.thread );
}
RSP.thread = NULL;
#else
OGL_Stop();
#endif
#ifdef DEBUG
CloseDebugDlg();
#endif
}
EXPORT void CALL RomOpen (void)
{
#ifdef RSPTHREAD
# ifndef __LINUX__
DWORD threadID;
int i;
// Create RSP message events
for (i = 0; i < 6; i++)
{
RSP.threadMsg[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
if (RSP.threadMsg[i] == NULL)
{
MessageBox( hWnd, "Error creating video thread message events, closing video thread...", "glN64 Error", MB_OK | MB_ICONERROR );
return;
}
}
// Create RSP finished event
RSP.threadFinished = CreateEvent( NULL, FALSE, FALSE, NULL );
if (RSP.threadFinished == NULL)
{
MessageBox( hWnd, "Error creating video thread finished event, closing video thread...", "glN64 Error", MB_OK | MB_ICONERROR );
return;
}
RSP.thread = CreateThread( NULL, 4096, RSP_ThreadProc, NULL, NULL, &threadID );
WaitForSingleObject( RSP.threadFinished, INFINITE );
# else // !__LINUX__
# endif // __LINUX__
#else
RSP_Init();
#endif
OGL_ResizeWindow();
#ifdef DEBUG
OpenDebugDlg();
#endif
}
EXPORT void CALL ShowCFB (void)
{
}
EXPORT void CALL UpdateScreen (void)
{
#ifdef RSPTHREAD
if (RSP.thread)
{
SetEvent( RSP.threadMsg[RSPMSG_UPDATESCREEN] );
WaitForSingleObject( RSP.threadFinished, INFINITE );
}
#else
VI_UpdateScreen();
#endif
}
EXPORT void CALL ViStatusChanged (void)
{
}
EXPORT void CALL ViWidthChanged (void)
{
}
EXPORT void CALL ReadScreen (void **dest, int *width, int *height)
{
OGL_ReadScreen( dest, width, height );
}
EXPORT void CALL SetConfigDir (char *configDir)
{
strncpy(configdir, configDir, PATH_MAX);
}
EXPORT void CALL SetRenderingCallback(void (*callback)())
{
renderCallback = callback;
}