#ifndef __LINUX__ //Change me... #include #include #include #else #include #include "../main/winlnxdefs.h" #endif #ifdef QT4_GUI # include #endif #include #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; }