/* Copyright (C) 2002 Rice1964 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 of the License, 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "stdafx.h" #include "_BldNum.h" #ifndef _WIN32 #include #include #include "messagebox.h" #endif PluginStatus status; HINSTANCE myhInst = NULL; IniFile *g_pIniFile = NULL; GFX_INFO g_GraphicsInfo; DWORD dwTvSystem = TV_SYSTEM_NTSC; float fRatio = 0.75f; DWORD g_dwRamSize = 0x400000; DWORD* g_pu32RamBase = NULL; signed char *g_ps8RamBase = NULL; unsigned char *g_pu8RamBase = NULL; unsigned char * g_pu8SpMemBase = NULL; CCritSect g_CritialSection; ///#define USING_THREAD #ifdef USING_THREAD HANDLE videoThread; HANDLE threadMsg[5]; HANDLE threadFinished; #define RSPMSG_CLOSE 0 #define RSPMSG_SWAPBUFFERS 1 #define RSPMSG_PROCESSDLIST 2 #define RSPMSG_CHANGEWINDOW 3 #define RSPMSG_PROCESSRDPLIST 4 #endif //======================================================= // User Options RECT frameWriteByCPURect; std::vector frameWriteRecord; int g_DlistCount=0; void InitGammaValues(); //--------------------------------------------------------------------------------------- #ifdef _WIN32 BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle DWORD fdwReason, // reason called LPVOID lpvReserved) // reserved { myhInst = hinstDLL; switch (fdwReason) { case DLL_PROCESS_ATTACH: CProfiler::Create(); InitConfiguration(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: CProfiler::Destroy(); delete g_pIniFile; // Will write ini file if changed g_pIniFile = NULL; break; } return TRUE; } #endif void GetPluginDir( char * Directory ) { #ifdef _WIN32 char path_buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR]; char fname[_MAX_FNAME],ext[_MAX_EXT]; GetModuleFileName(myhInst,path_buffer,sizeof(path_buffer)); _splitpath( path_buffer, drive, dir, fname, ext ); strcpy(Directory,drive); strcat(Directory,dir); #else // _WIN32 int n = readlink("/proc/self/exe", Directory, MAX_PATH); if (n == -1) strcpy(Directory, "./"); else { Directory[n] = '\0'; while(Directory[strlen(Directory)-1] != '/') Directory[strlen(Directory)-1] = '\0'; } strcat(Directory, "plugins/"); #endif //_WIN32 } //------------------------------------------------------------------------------------- __declspec(dllexport) void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo ) { #ifdef _DEBUG sprintf(PluginInfo->Name, "Rice's Daedalus Debug %d.%d.%d",FILE_VERSION0,FILE_VERSION1,FILE_VERSION2); #else sprintf(PluginInfo->Name, "Rice's Daedalus %d.%d.%d",FILE_VERSION0,FILE_VERSION1,FILE_VERSION2); #endif PluginInfo->Version = 0x0102; PluginInfo->Type = PLUGIN_TYPE_GFX; PluginInfo->NormalMemory = FALSE; PluginInfo->MemoryBswaped = TRUE; } //--------------------------------------------------------------------------------------- __declspec(dllexport) void CALL DllAbout ( HWND hParent ) { char temp[300]; sprintf(temp,"Rice's Daedalus %d.%d.%d (build %d) \nDirectX 8.1+\nOpenGL 1.1-1.4/ATI/Nvidia TNT/Geforce Extension",FILE_VERSION0,FILE_VERSION1,FILE_VERSION2,BUILD_NUMBER) ; MsgInfo(temp); } //--------------------------------------------------------------------------------------- __declspec(dllexport) void CALL DllTest ( HWND hParent ) { MsgInfo("TODO: Test"); } __declspec(dllexport) void CALL DllConfig ( HWND hParent ) { #ifdef _WIN32 DialogBox(myhInst, "Config", hParent, (DLGPROC)ConfigDialog); #else ShowConfigBox(); #endif } void ChangeWindowStep2() { windowSetting.bDisplayFullscreen = 1-windowSetting.bDisplayFullscreen; g_CritialSection.Lock(); windowSetting.bDisplayFullscreen = CGraphicsContext::Get()->ToggleFullscreen(); #ifdef _WIN32 if( windowSetting.bDisplayFullscreen ) { if( g_GraphicsInfo.hStatusBar != NULL ) { ShowWindow(g_GraphicsInfo.hStatusBar, SW_HIDE); } ShowCursor(FALSE); } else { if( g_GraphicsInfo.hStatusBar != NULL ) { ShowWindow(g_GraphicsInfo.hStatusBar, SW_SHOW); } ShowCursor(TRUE); } #endif CGraphicsContext::Get()->Clear(CLEAR_COLOR_AND_DEPTH_BUFFER); CGraphicsContext::Get()->SwapBuffer(); CGraphicsContext::Get()->Clear(CLEAR_COLOR_AND_DEPTH_BUFFER); CGraphicsContext::Get()->SwapBuffer(); CGraphicsContext::Get()->Clear(CLEAR_COLOR_AND_DEPTH_BUFFER); CGraphicsContext::Get()->SwapBuffer(); g_CritialSection.Unlock(); } __declspec(dllexport) void CALL ChangeWindow () { #ifdef USING_THREAD SetEvent( threadMsg[RSPMSG_CHANGEWINDOW] ); WaitForSingleObject( threadFinished, INFINITE ); #else ChangeWindowStep2(); #endif } #ifdef _WIN32 void ChangeWinSize( void ) { ShowWindow(g_GraphicsInfo.hWnd, SW_HIDE); WINDOWPLACEMENT wndpl; RECT rc1, swrect; wndpl.length = sizeof(wndpl); GetWindowPlacement( g_GraphicsInfo.hWnd, &wndpl); if ( g_GraphicsInfo.hStatusBar != NULL ) { GetClientRect( g_GraphicsInfo.hStatusBar, &swrect ); SetRect( &rc1, 0, 0, windowSetting.uDisplayWidth, (windowSetting.uDisplayWidth >> 2) * 3 + swrect.bottom ); } else { SetRect( &rc1, 0, 0, windowSetting.uDisplayWidth, (windowSetting.uDisplayWidth >> 2) * 3 ); } AdjustWindowRectEx( &rc1,GetWindowLong( g_GraphicsInfo.hWnd, GWL_STYLE ), GetMenu( g_GraphicsInfo.hWnd ) != NULL, GetWindowLong( g_GraphicsInfo.hWnd, GWL_EXSTYLE ) ); MoveWindow( g_GraphicsInfo.hWnd, wndpl.rcNormalPosition.left, wndpl.rcNormalPosition.top, rc1.right - rc1.left, rc1.bottom - rc1.top, TRUE ); ShowWindow(g_GraphicsInfo.hWnd, SW_SHOW); Sleep(100); } #endif //--------------------------------------------------------------------------------------- __declspec(dllexport) void CALL DrawScreen (void) { } //--------------------------------------------------------------------------------------- __declspec(dllexport) void CALL MoveScreen (int xpos, int ypos) { } void Ini_GetRomOptions(LPROMINFO pRomInfo); void Ini_StoreRomOptions(LPROMINFO pRomInfo); void GenerateCurrentRomOptions(); void StartVideo(void) { g_CritialSection.Lock(); memcpy(&g_curRomInfo.rh, g_GraphicsInfo.HEADER, sizeof(ROMHeader)); ROM_ByteSwap_3210( &g_curRomInfo.rh, sizeof(ROMHeader) ); ROM_GetRomNameFromHeader(g_curRomInfo.szGameName, &g_curRomInfo.rh); Ini_GetRomOptions(&g_curRomInfo); GenerateCurrentRomOptions(); dwTvSystem = CountryCodeToTVSystem(g_curRomInfo.rh.nCountryID); if( dwTvSystem == TV_SYSTEM_NTSC ) fRatio = 0.75f; else fRatio = 9/11.0f;; if (g_curRomInfo.bDisableTextureCRC) g_bCRCCheck = FALSE; else g_bCRCCheck = TRUE; #ifdef _WIN32 __try{ uint32 dummy; dummy = g_GraphicsInfo.RDRAM[0x400000]; dummy = g_GraphicsInfo.RDRAM[0x500000]; dummy = g_GraphicsInfo.RDRAM[0x600000]; dummy = g_GraphicsInfo.RDRAM[0x700000]; dummy = g_GraphicsInfo.RDRAM[0x7FFFFC]; g_dwRamSize = 0x800000; } __except(NULL, EXCEPTION_EXECUTE_HANDLER) { g_dwRamSize = 0x400000; } ChangeWinSize(); #else // _WIN32 g_dwRamSize = 0x800000; #endif // _WIN32 CDeviceBuilder::GetBuilder()->CreateGraphicsContext(); HRESULT hr = CGraphicsContext::Get()->Initialize(g_GraphicsInfo.hWnd, g_GraphicsInfo.hStatusBar, 640, 480, TRUE); CDeviceBuilder::GetBuilder()->CreateRender(); CDaedalusRender::GetRender()->Initialize(); if( SUCCEEDED(hr) ) { DLParser_Init(); } status.bGameIsRunning = true; g_DlistCount = 0; //status.gRDPFrame = 0; g_CritialSection.Unlock(); CProfiler::Get()->Reset(); } void StopVideo() { g_CritialSection.Lock(); status.bGameIsRunning = false; try { gTextureCache.DropTextures(); RDP_Cleanup(); } catch(...) { TRACE0("Some exceptions during RomClosed"); } CGraphicsContext::Get()->CleanUp(); CDeviceBuilder::GetBuilder()->DeleteRender(); CDeviceBuilder::GetBuilder()->DeleteGraphicsContext(); g_CritialSection.Unlock(); #ifdef ENABLE_PROFILER CProfiler::Get()->Display(); #endif DEBUGGER_ONLY({delete surfTlut;}); } #ifdef USING_THREAD void ChangeWindowStep2(); void UpdateScreenStep2 (void); void ProcessDListStep2(void); //BOOL WINAPI SwitchToThread(VOID); DWORD WINAPI VideoThreadProc( LPVOID lpParameter ) { BOOL res; StartVideo(); SetEvent( threadFinished ); while(true) { switch (WaitForMultipleObjects( 5, threadMsg, FALSE, INFINITE )) { case (WAIT_OBJECT_0 + RSPMSG_PROCESSDLIST): ProcessDListStep2(); SetEvent( threadFinished ); break; case (WAIT_OBJECT_0 + RSPMSG_SWAPBUFFERS): //res = SwitchToThread(); //Sleep(1); UpdateScreenStep2(); SetEvent( threadFinished ); break; case (WAIT_OBJECT_0 + RSPMSG_CLOSE): StopVideo(); SetEvent( threadFinished ); return 1; case (WAIT_OBJECT_0 + RSPMSG_CHANGEWINDOW): ChangeWindowStep2(); SetEvent( threadFinished ); break; case (WAIT_OBJECT_0 + RSPMSG_PROCESSRDPLIST): g_DlistCount++; try { RDP_DLParser_Process(); } catch (...) { ErrorMsg("Unknown Error in Daedalus plugin ProcessRDPList"); //TriggerDPInterrupt(); } SetEvent( threadFinished ); break; } } return 0; } #endif //--------------------------------------------------------------------------------------- __declspec(dllexport) void CALL RomClosed (void) { #ifdef USING_THREAD if(videoThread) { SetEvent( threadMsg[RSPMSG_CLOSE] ); WaitForSingleObject( threadFinished, INFINITE ); for (int i = 0; i < 5; i++) { if (threadMsg[i]) CloseHandle( threadMsg[i] ); } CloseHandle( threadFinished ); CloseHandle( videoThread ); } videoThread = NULL; #else StopVideo(); #endif Ini_StoreRomOptions(&g_curRomInfo); } __declspec(dllexport) void CALL RomOpen (void) { #ifndef _WIN32 CProfiler::Create(); InitConfiguration(); #endif InitGammaValues(); #ifdef _DEBUG if( debuggerPause ) { debuggerPause = FALSE; Sleep(100); } #endif #ifdef USING_THREAD DWORD threadID; for(int i = 0; i < 5; i++) { threadMsg[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); if (threadMsg[i] == NULL) { ErrorMsg( "Error creating thread message events"); return; } } threadFinished = CreateEvent( NULL, FALSE, FALSE, NULL ); if (threadFinished == NULL) { ErrorMsg( "Error creating video thread finished event"); return; } videoThread = CreateThread( NULL, 4096, VideoThreadProc, NULL, NULL, &threadID ); #else StartVideo(); #endif } void SetVIScales() { if( g_curRomInfo.VIHeight>0 && g_curRomInfo.VIWidth>0 ) { windowSetting.fViWidth = windowSetting.uViWidth = g_curRomInfo.VIWidth; windowSetting.fViHeight = windowSetting.uViHeight = g_curRomInfo.VIHeight; } else { float xscale, yscale; DWORD val = *g_GraphicsInfo.VI_X_SCALE_REG & 0xFFF; xscale = (float)val / (1<<10); DWORD start = *g_GraphicsInfo.VI_H_START_REG >> 16; DWORD end = *g_GraphicsInfo.VI_H_START_REG&0xFFFF; DWORD width = *g_GraphicsInfo.VI_WIDTH_REG; windowSetting.fViWidth = (end-start)*xscale; if( abs((int)(windowSetting.fViWidth - width) ) < 8 ) { windowSetting.fViWidth = (float)width; } else { //DebuggerAppendMsg("fViWidth = %f, Width Reg=%d", windowSetting.fViWidth, width); } val = (*g_GraphicsInfo.VI_Y_SCALE_REG & 0xFFF);// - ((*g_GraphicsInfo.VI_Y_SCALE_REG>>16) & 0xFFF); if( val == 0x3FF ) val = 0x400; yscale = (float)val / (1<<10); start = *g_GraphicsInfo.VI_V_START_REG >> 16; end = *g_GraphicsInfo.VI_V_START_REG&0xFFFF; windowSetting.fViHeight = (end-start)/2*yscale; if( yscale == 0 ) { windowSetting.fViHeight = windowSetting.fViWidth*fRatio; } else { if( *g_GraphicsInfo.VI_WIDTH_REG > 0x300 ) windowSetting.fViHeight *= 2; if( windowSetting.fViWidth*fRatio > windowSetting.fViHeight && (*g_GraphicsInfo.VI_X_SCALE_REG & 0xFF) != 0 ) { if( abs(int(windowSetting.fViWidth*fRatio - windowSetting.fViHeight)) < 8 ) { windowSetting.fViHeight = windowSetting.fViWidth*fRatio; } /* else { if( abs(windowSetting.fViWidth*fRatio-windowSetting.fViHeight) > windowSetting.fViWidth*0.1f ) { if( fRatio > 0.8 ) windowSetting.fViHeight = windowSetting.fViWidth*3/4; //windowSetting.fViHeight = (*g_GraphicsInfo.VI_V_SYNC_REG - 0x2C)/2; } } */ } if( windowSetting.fViHeight<100 || windowSetting.fViWidth<100 ) { //At sometime, value in VI_H_START_REG or VI_V_START_REG are 0 windowSetting.fViWidth = (float)*g_GraphicsInfo.VI_WIDTH_REG; windowSetting.fViHeight = windowSetting.fViWidth*fRatio; } } windowSetting.uViWidth = (unsigned short)(windowSetting.fViWidth/4); windowSetting.fViWidth = windowSetting.uViWidth *= 4; windowSetting.uViHeight = (unsigned short)(windowSetting.fViHeight/4); windowSetting.fViHeight = windowSetting.uViHeight *= 4; u16 optimizeHeight = u16(windowSetting.uViWidth*fRatio); if( windowSetting.uViHeight != optimizeHeight ) { if( abs(windowSetting.uViHeight-optimizeHeight) <= 8 ) windowSetting.fViHeight = windowSetting.uViHeight = optimizeHeight; } if( gRDP.scissor.left == 0 && gRDP.scissor.top == 0 && gRDP.scissor.right != 0 ) { if( (*g_GraphicsInfo.VI_X_SCALE_REG & 0xFF) != 0x0 && gRDP.scissor.right == windowSetting.uViWidth ) { // Mario Tennis if( abs(int( windowSetting.fViHeight - gRDP.scissor.bottom )) < 8 ) { windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom; } else if( windowSetting.fViHeight < gRDP.scissor.bottom ) { windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom; } windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom; } else if( gRDP.scissor.right == windowSetting.uViWidth - 1 && gRDP.scissor.bottom != 0 ) { if( !(fRatio == 0.75 && windowSetting.uViHeight == optimizeHeight) ) windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom + gRDP.scissor.top + 1; } else if( gRDP.scissor.right == windowSetting.uViWidth && gRDP.scissor.bottom != 0 && fRatio != 0.75 ) { if( !(fRatio == 0.75 && windowSetting.uViHeight == optimizeHeight) ) windowSetting.fViHeight = windowSetting.uViHeight = gRDP.scissor.bottom; } } } SetScreenMult(windowSetting.uDisplayWidth/windowSetting.fViWidth, windowSetting.uDisplayHeight/windowSetting.fViHeight); } //--------------------------------------------------------------------------------------- void SetAddrUsedByVIOrigin(u32 addr); void UpdateScreenStep2 (void) { status.bVIOriginIsUpdated = false; if( g_bUsingFakeCI ) SaveFakeFrameBuffer(); SetAddrUsedByVIOrigin(*g_GraphicsInfo.VI_ORIGIN_REG); if( g_DlistCount == 0 ) { // CPU frame buffer update u32 width = *g_GraphicsInfo.VI_WIDTH_REG; if( (*g_GraphicsInfo.VI_ORIGIN_REG & (g_dwRamSize-1) ) > width*2 && *g_GraphicsInfo.VI_H_START_REG != 0 ) { SetVIScales(); CDaedalusRender::GetRender()->DrawFrameBuffer(true); CGraphicsContext::Get()->SwapBuffer(); } return; } if( currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_VI_UPDATE ) { CGraphicsContext::Get()->SwapBuffer(); #ifdef _DEBUG if( pauseAtNext ) { DebuggerAppendMsg("Update Screen: VIORIG=%08X", *g_GraphicsInfo.VI_ORIGIN_REG); } DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_FRAME); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_SET_CIMG); #endif return; } if( currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_VI_CHANGE ) { if( *g_GraphicsInfo.VI_ORIGIN_REG != status.curVIOriginReg ) { if( *g_GraphicsInfo.VI_ORIGIN_REG < status.curDisplayBuffer || *g_GraphicsInfo.VI_ORIGIN_REG > status.curDisplayBuffer+0x2000 ) { status.curDisplayBuffer = *g_GraphicsInfo.VI_ORIGIN_REG; status.curVIOriginReg = status.curDisplayBuffer; //status.curRenderBuffer = NULL; CGraphicsContext::Get()->SwapBuffer(); #ifdef _DEBUG if( pauseAtNext ) { DebuggerAppendMsg("Update Screen: VIORIG=%08X", *g_GraphicsInfo.VI_ORIGIN_REG); } DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_FRAME); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_SET_CIMG); #endif } else { status.curDisplayBuffer = *g_GraphicsInfo.VI_ORIGIN_REG; status.curVIOriginReg = status.curDisplayBuffer; DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_FRAME, {DebuggerAppendMsg("Skip Screen Update, closed to the display buffer, VIORIG=%08X", *g_GraphicsInfo.VI_ORIGIN_REG);}); } } else { DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_FRAME, {DebuggerAppendMsg("Skip Screen Update, the same VIORIG=%08X", *g_GraphicsInfo.VI_ORIGIN_REG);}); } return; } if( currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_CI_CHANGE ||currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1st_PRIMITIVE ) { status.bVIOriginIsUpdated=true; DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_FRAME, {DebuggerAppendMsg("VI ORIG is updated to %08X", *g_GraphicsInfo.VI_ORIGIN_REG);}); return; } #ifdef _DEBUG if( pauseAtNext ) { DebuggerAppendMsg("VI is updated, No screen update: VIORIG=%08X", *g_GraphicsInfo.VI_ORIGIN_REG); } DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_FRAME); DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_SET_CIMG); #endif } __declspec(dllexport) void CALL UpdateScreen (void) { #ifdef USING_THREAD if (videoThread) { SetEvent( threadMsg[RSPMSG_SWAPBUFFERS] ); WaitForSingleObject( threadFinished, INFINITE ); } #else UpdateScreenStep2(); #endif } //--------------------------------------------------------------------------------------- __declspec(dllexport) void CALL ViStatusChanged (void) { SetVIScales(); CDaedalusRender::g_pRender->UpdateClipRectangle(); } //--------------------------------------------------------------------------------------- __declspec(dllexport) void CALL ViWidthChanged (void) { SetVIScales(); CDaedalusRender::g_pRender->UpdateClipRectangle(); } __declspec(dllexport) BOOL CALL InitiateGFX(GFX_INFO Gfx_Info) { #ifdef _DEBUG OpenDialogBox(); #endif windowSetting.bDisplayFullscreen = FALSE; memcpy(&g_GraphicsInfo, &Gfx_Info, sizeof(GFX_INFO)); g_pu8RamBase = Gfx_Info.RDRAM; g_pu32RamBase = (DWORD*)Gfx_Info.RDRAM; g_ps8RamBase = (signed char *)Gfx_Info.RDRAM; g_pu8SpMemBase = (u8*)Gfx_Info.DMEM; windowSetting.fViWidth = 320; windowSetting.fViHeight = 240; InitConfiguration(); return(TRUE); } void __cdecl MsgInfo (char * Message, ...) { char Msg[400]; va_list ap; va_start( ap, Message ); vsprintf( Msg, Message, ap ); va_end( ap ); char str[200]; sprintf(str, "Rice's Daedalus %d.%d.%d",FILE_VERSION0,FILE_VERSION1,FILE_VERSION2); #ifdef _WIN32 MessageBox(NULL,Msg,"str",MB_OK|MB_ICONINFORMATION); #else messagebox(str, MB_OK|MB_ICONINFORMATION, Msg); #endif } void __cdecl ErrorMsg (char * Message, ...) { char Msg[400]; va_list ap; va_start( ap, Message ); vsprintf( Msg, Message, ap ); va_end( ap ); char str[200]; sprintf(str, "Rice's Daedalus %d.%d.%d",FILE_VERSION0,FILE_VERSION1,FILE_VERSION2); #ifdef _WIN32 MessageBox(NULL,Msg,"str",MB_OK|MB_ICONERROR); #else //messagebox(str, MB_OK|MB_ICONERROR, Msg); printf("%s:%s\n", str, Msg); #endif } void __cdecl DebuggerAppendMsg(const char * Message, ...) { /* char Msg[400]; va_list ap; va_start( ap, Message ); vsprintf( Msg, Message, ap ); va_end( ap ); printf("RICE'S PLUGIN:%s\n", Msg);*/ } //--------------------------------------------------------------------------------------- __declspec(dllexport) void CALL CloseDLL (void) { delete g_pIniFile; // Will write ini file if changed g_pIniFile = NULL; #ifdef _DEBUG CloseDialogBox(); #endif #ifndef _WIN32 CProfiler::Destroy(); #endif } void ProcessDListStep2(void) { g_DlistCount++; g_CritialSection.Lock(); #ifdef _DEBUG DLParser_Process((OSTask *)(g_GraphicsInfo.DMEM + 0x0FC0)); #else try { DLParser_Process((OSTask *)(g_GraphicsInfo.DMEM + 0x0FC0)); } catch (...) { #ifdef _DEBUG ErrorMsg("Unknown Error in Daedalus D3D plugin ProcessDList"); #else #endif TriggerDPInterrupt(); } #endif g_CritialSection.Unlock(); } __declspec(dllexport) DWORD CALL ProcessDListCountCycles(void) { #ifdef USING_THREAD if (videoThread) { SetEvent( threadMsg[RSPMSG_PROCESSDLIST] ); WaitForSingleObject( threadFinished, INFINITE ); } return 0; #else g_CritialSection.Lock(); g_DlistCount++; status.SPCycleCount = 100; status.DPCycleCount = 0; #ifdef _DEBUG DLParser_Process((OSTask *)(g_GraphicsInfo.DMEM + 0x0FC0)); #else try { DLParser_Process((OSTask *)(g_GraphicsInfo.DMEM + 0x0FC0)); } catch (...) { #ifdef _DEBUG ErrorMsg("Unknown Error in Rice's Daedalus plugin ProcessDListCountCycles"); #endif TriggerDPInterrupt(); } #endif status.SPCycleCount *= 6; //status.DPCycleCount += status.SPCycleCount; //status.DPCycleCount *=4; //status.DPCycleCount = min(200,status.DPCycleCount); status.DPCycleCount *= 15; status.DPCycleCount += status.SPCycleCount; g_CritialSection.Unlock(); return (status.DPCycleCount<<16)+status.SPCycleCount; #endif } __declspec(dllexport) void CALL ProcessRDPList(void) { #ifdef USING_THREAD if (videoThread) { SetEvent( threadMsg[RSPMSG_PROCESSRDPLIST] ); WaitForSingleObject( threadFinished, INFINITE ); } #else g_DlistCount++; try { RDP_DLParser_Process(); } catch (...) { ErrorMsg("Unknown Error in Daedalus plugin ProcessRDPList"); //TriggerDPInterrupt(); } #endif } __declspec(dllexport) void CALL ProcessDList(void) { #ifdef USING_THREAD if (videoThread) { SetEvent( threadMsg[RSPMSG_PROCESSDLIST] ); WaitForSingleObject( threadFinished, INFINITE ); } #else ProcessDListStep2(); #endif } //--------------------------------------------------------------------------------------- void TriggerDPInterrupt(void) { *(g_GraphicsInfo.MI_INTR_REG) |= MI_INTR_DP; g_GraphicsInfo.CheckInterrupts(); } /****************************************************************** Function: FrameBufferWriteList Purpose: This function is called to notify the dll that the frame buffer has been modified by CPU at the given address. input: FrameBufferModifyEntry *plist size = size of the plist, max = 1024 output: none *******************************************************************/ __declspec(dllexport) void CALL FBWList(FrameBufferModifyEntry *plist, DWORD size) { } /****************************************************************** Function: FrameBufferRead Purpose: This function is called to notify the dll that the frame buffer memory is beening read at the given address. DLL should copy content from its render buffer to the frame buffer in N64 RDRAM DLL is responsible to maintain its own frame buffer memory addr list DLL should copy 4KB block content back to RDRAM frame buffer. Emulator should not call this function again if other memory is read within the same 4KB range input: addr rdram address val val size 1 = BYTE, 2 = WORD, 4 = DWORD output: none *******************************************************************/ void FrameBufferWriteByCPU(u32 addr, u32 size); void FrameBufferReadByCPU( u32 addr ); extern SetImgInfo g_CI; __declspec(dllexport) void CALL FBRead(DWORD addr) { FrameBufferReadByCPU(addr); } /****************************************************************** Function: FrameBufferWrite Purpose: This function is called to notify the dll that the frame buffer has been modified by CPU at the given address. input: addr rdram address val val size 1 = BYTE, 2 = WORD, 4 = DWORD output: none *******************************************************************/ __declspec(dllexport) void CALL FBWrite(DWORD addr, DWORD size) { FrameBufferWriteByCPU(addr, size); } void InitGammaValues() { float gamma = 1; switch( options.gamma_correction ) { case 0: // No gamma correction gamma = 1; break; case 1: // Lighter gamma = 0.9f; break; case 2: // Lighter gamma = 0.8f; break; case 3: // Lighter gamma = 0.65f; break; case 4: // Lightest gamma = 0.5f; break; case 5: // darker gamma = 1.25f; break; case 6: // Darkest gamma = 1.5f; break; } if( options.gamma_correction == 0 ) { for( int i=0; i<256; i++ ) { g_gammaValues[i] = i; } } else { for( int i=0; i<256; i++ ) { double val = pow((i/255.0f),gamma)*256; g_gammaValues[i] = BYTE(val); } } }