mirror of
https://github.com/mupen64plus/mupen64plus-oldsvn.git
synced 2024-05-23 14:27:51 -04:00
434 lines
11 KiB
C++
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;
|
|
}
|
|
|