// drkPvr.cpp : Defines the entry point for the DLL application. // /* Plugin structure Interface SPG TA Renderer */ #include #include "drkPvr.h" #include "ta.h" #include "spg.h" #include "regs.h" #include "Renderer_if.h" #include "threadedPvr.h" //RaiseInterruptFP* RaiseInterrupt; //void* Hwnd; char emu_name_pvr[512]; pvr_init_params params; _drkpvr_settings_type drkpvr_settings; /* BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } */ class Optiongroup { public: Optiongroup() { root_menu=0; format=0; } u32 root_menu; char* format; struct itempair { u32 id;int value;char* ex_name;}; vector items; void (*callback) (int val) ; void Add(u32 id,int val,char* ex_name) { itempair t={id,val,ex_name}; items.push_back(t); } void Add(u32 root,char* name,int val,char* ex_name=0,int style=0) { if (root_menu==0) root_menu=root; u32 ids=emu.AddMenuItem(root,-1,name,handler,0); emu.SetMenuItemStyle(ids,style,style); MenuItem t; t.PUser=this; emu.SetMenuItem(ids,&t,MIM_PUser); Add(ids,val,ex_name); } static void EXPORT_CALL handler(u32 id,void* win,void* puser) { Optiongroup* pthis=(Optiongroup*)puser; pthis->handle(id); } void SetValue(int val) { for (u32 i=0;i width of rect to be adjusted //dst[1] -> height //src: w,h of rect to be matched void CalcRect(float* dst,float* src) { if (drkpvr_settings.Enhancements.AspectRatioMode!=0) { //printf("New rect %d %d\n",sx,sy); float nw=((float)src[0]/(float)src[1])*dst[1]; float nh=((float)src[1]/(float)src[0])*dst[0]; if (nhwidth; int sy=Xe_GetFramebufferSurface(xe)->height; if (osx!=sx || osy!=sy) { osx=sx; osy=sy; oldmode=-1; } float win_wh[2]={(float)sx,(float)sy}; CalcRect(dc_wh,win_wh); } rect[0]=(dc_wh[0]-640)/2; rect[2]=dc_wh[0]; rect[1]=(dc_wh[1]-480)/2; rect[3]=dc_wh[1]; SetRenderRect(rect,oldmode!=drkpvr_settings.Enhancements.AspectRatioMode); oldmode=drkpvr_settings.Enhancements.AspectRatioMode; } void FASTCALL vramLockCB (vram_block* block,u32 addr) { VramLockedWrite(block,addr); } #include using std::vector; extern volatile bool render_restart; void EXPORT_CALL handler_Vsync (u32 id,void* win,void* puser) { if (drkpvr_settings.Video.VSync) drkpvr_settings.Video.VSync=0; else drkpvr_settings.Video.VSync=1; emu.SetMenuItemStyle(id,drkpvr_settings.Video.VSync?MIS_Checked:0,MIS_Checked); SaveSettingsPvr(); render_restart=true; } void EXPORT_CALL handler_ShowStats(u32 id,void* win,void* puser) { if (drkpvr_settings.OSD.ShowStats) drkpvr_settings.OSD.ShowStats=0; else drkpvr_settings.OSD.ShowStats=1; emu.SetMenuItemStyle(id,drkpvr_settings.OSD.ShowStats?MIS_Checked:0,MIS_Checked); SaveSettingsPvr(); } void EXPORT_CALL handler_ShowFps(u32 id,void* win,void* puser) { if (drkpvr_settings.OSD.ShowFPS) drkpvr_settings.OSD.ShowFPS=0; else drkpvr_settings.OSD.ShowFPS=1; emu.SetMenuItemStyle(id,drkpvr_settings.OSD.ShowFPS?MIS_Checked:0,MIS_Checked); SaveSettingsPvr(); } void handler_widemode(int mode) { drkpvr_settings.Enhancements.AspectRatioMode=mode; SaveSettingsPvr(); UpdateRRect(); } void handler_resmode(int mode) { drkpvr_settings.Video.ResolutionMode=mode; SaveSettingsPvr(); HandleEvent(NDE_GUI_RESIZED,0); } void handler_PalMode(int mode) { drkpvr_settings.Emulation.PaletteMode=mode; SaveSettingsPvr(); } void handler_ModVolMode(int mode) { drkpvr_settings.Emulation.ModVolMode=mode; SaveSettingsPvr(); } void handler_TexCacheMode(int mode) { drkpvr_settings.Emulation.TexCacheMode=mode; SaveSettingsPvr(); } void handler_ZBufferMode(int mode) { drkpvr_settings.Emulation.ZBufferMode=mode; SaveSettingsPvr(); render_restart=true; } u32 AA_mid_menu; u32 AA_mid_0; struct resolution { u32 w; u32 h; u32 rr; }; bool operator<(const resolution &left, const resolution &right) { /* put any condition you want to sort on here */ if (left.h*(u64)left.w>right.h*(u64)right.w) return true; else if (left.h*(u64)left.w==right.h*(u64)right.w) return left.rr>right.rr; else return false; } void EXPORT_CALL handle_About(u32 id,void* w,void* p) { // MessageBox((HWND)w,"Made by the nullDC Team","About nullDC PVR...",MB_ICONINFORMATION); } u32 sort_menu; u32 sort_sm[3]; u32 ssm(u32 nm) { nm=min(nm,2); return nm; } void handler_SSM(int val) { drkpvr_settings.Emulation.AlphaSortMode=val; SaveSettingsPvr(); } void CreateSortMenu() { sort_menu=emu.AddMenuItem(emu.RootMenu,-1,"Sort : %s",0,0); menu_sortmode.format="Sort : %s"; menu_sortmode.callback=handler_SSM; menu_sortmode.Add(sort_menu,"Off (Fastest, lowest accuracy)",0,"Off"); menu_sortmode.Add(sort_menu,"Per Strip",1,"Strip"); menu_sortmode.Add(sort_menu,"Per Triangle (Slowest, highest accuracy)",2,"Triangle"); menu_sortmode.SetValue(drkpvr_settings.Emulation.AlphaSortMode); } //called when plugin is used by emu (you should do first time init here) s32 FASTCALL LoadPvr(emu_info* emu_inf) { // char temp[512]; // Unreferenced memcpy(&emu,emu_inf,sizeof(emu)); emu.ConfigLoadStr("emu","shortname",emu_name_pvr,0); LoadSettingsPvr(); u32 RSM=emu.AddMenuItem(emu.RootMenu,-1,"Render Resolution: %s",0,0); menu_resolution.format="Resolution: %s"; menu_resolution.callback=handler_resmode; menu_resolution.Add(RSM,"Maximum Supported (Highest quality)",0); menu_resolution.Add(RSM,"Maximum, but up to 1280x800",1); menu_resolution.Add(RSM,"Native (640x480)",2); menu_resolution.Add(RSM,"Half of maximum pixels",3); menu_resolution.Add(RSM,"Quarter of maximum pixels (Lowest quality)",4); menu_resolution.SetValue(drkpvr_settings.Video.ResolutionMode); u32 WSM=emu.AddMenuItem(emu.RootMenu,-1,"Aspect Ratio: %s",0,0); menu_widemode.format="Aspect Ratio: %s"; menu_widemode.callback=handler_widemode; menu_widemode.Add(WSM,"Stretch",0); menu_widemode.Add(WSM,"Borders",1); menu_widemode.Add(WSM,"Extra Geom",2); menu_widemode.SetValue(drkpvr_settings.Enhancements.AspectRatioMode); u32 PMT=emu.AddMenuItem(emu.RootMenu,-1,"Palette Handling",0,0); menu_palmode.callback=handler_PalMode; menu_palmode.format="Paletted Textures: %s"; menu_palmode.Add(PMT,"Static",0); menu_palmode.Add(PMT,"Versioned",1); AddSeperator(PMT); menu_palmode.Add(PMT,"Dynamic, Point",2); menu_palmode.Add(PMT,"Dynamic, Full",3); menu_palmode.SetValue(drkpvr_settings.Emulation.PaletteMode); CreateSortMenu(); u32 MVM=emu.AddMenuItem(emu.RootMenu,-1,"Modifier Volumes: %s",0,0); menu_modvolmode.format="Modifier Volumes: %s"; menu_modvolmode.callback=handler_ModVolMode; menu_modvolmode.Add(MVM,"Normal And Clip (Slowest, highest accuracy)",MVM_NormalAndClip); menu_modvolmode.Add(MVM,"Normal (Good speed, good accuracy)",MVM_Normal); menu_modvolmode.Add(MVM,"Off (Fastest, no shadows)",MVM_Off); menu_modvolmode.Add(MVM,"Volumes (For debuging)",MVM_Volume); menu_modvolmode.SetValue(drkpvr_settings.Emulation.ModVolMode); u32 ZBM=emu.AddMenuItem(emu.RootMenu,-1,"Z Buffer Mode: %s",0,0); menu_zbuffer.format="Z Buffer Mode: %s"; menu_zbuffer.callback=handler_ZBufferMode; menu_zbuffer.Add(ZBM,"D24S8 Adaptive Linear (New, Buggy still)",4); menu_zbuffer.Add(ZBM,"D24FS8 (Fast when avaiable, Best Precision)",0); menu_zbuffer.Add(ZBM,"D24S8+FPE (Slow, Good Precision)",1); menu_zbuffer.Add(ZBM,"D24S8 Mode 1 (Lower Precision)",2); menu_zbuffer.Add(ZBM,"D24S8 Mode 2 (Lower Precision)",3); menu_zbuffer.SetValue(drkpvr_settings.Emulation.ZBufferMode); u32 TCM=emu.AddMenuItem(emu.RootMenu,-1,"Texture Cache Mode: %s",0,0); menu_TCM.format="Texture Cache Mode: %s"; menu_TCM.callback=handler_TexCacheMode; menu_TCM.Add(TCM,"Delete old",0); menu_TCM.Add(TCM,"Delete invalidated",1); menu_TCM.SetValue(drkpvr_settings.Emulation.TexCacheMode); AddSeperator(emu.RootMenu); emu.AddMenuItem(emu.RootMenu,-1,"Vsync",handler_Vsync,drkpvr_settings.Video.VSync); emu.AddMenuItem(emu.RootMenu,-1,"Show Fps",handler_ShowFps,drkpvr_settings.OSD.ShowFPS); emu.AddMenuItem(emu.RootMenu,-1,"Show Stats",handler_ShowStats,drkpvr_settings.OSD.ShowStats); AddSeperator(emu.RootMenu); emu.AddMenuItem(emu.RootMenu,-1,"About",handle_About,0); return rv_ok; } //called when plugin is unloaded by emu , olny if dcInitPvr is called (eg , not called to enumerate plugins) void FASTCALL UnloadPvr() { } //It's suposed to reset anything but vram (vram is set to 0 by emu) void FASTCALL ResetPvr(bool Manual) { Regs_Reset(Manual); spg_Reset(Manual); ResetRenderer(Manual); } //called when entering sh4 thread , from the new thread context (for any thread speciacific init) s32 FASTCALL InitPvr(pvr_init_params* param) { memcpy(¶ms,param,sizeof(params)); extern void BuildTwiddleTables(); BuildTwiddleTables(); if ((!Regs_Init())) { //failed return rv_error; } if (!spg_Init()) { //failed return rv_error; } if (!InitRenderer()) { //failed return rv_error; } UpdateRRect(); threaded_init(); return rv_ok; } //called when exiting from sh4 thread , from the new thread context (for any thread speciacific de init) :P void FASTCALL TermPvr() { threaded_wait(true); threaded_term(); TermRenderer(); spg_Term(); Regs_Term(); } //Helper functions float GetSeconds() { return timeGetTime()/1000.0f; } void EXPORT_CALL EventHandler(u32 id,void*p) { HandleEvent(id,p); } //Give to the emu pointers for the PowerVR interface void EXPORT_CALL drkPvrGetInterface(plugin_interface* info) { #define c info->common #define p info->pvr info->InterfaceVersion=PLUGIN_I_F_VERSION; c.Type=Plugin_PowerVR; c.InterfaceVersion=PVR_PLUGIN_I_F_VERSION; strcpy(c.Name,"nullDC PowerVR -- " REND_NAME " [" __DATE__ "]"); c.Load=LoadPvr; c.Unload=UnloadPvr; c.EventHandler=EventHandler; p.ExeptionHanlder=0; p.Init=InitPvr; p.Reset=ResetPvr; p.Term=TermPvr; p.ReadReg=ReadPvrRegister; p.WriteReg=WritePvrRegister; p.UpdatePvr=spgUpdatePvr; p.TaDMA=threaded_TADma; p.TaSQ=threaded_TASQ; p.LockedBlockWrite=vramLockCB; #undef c #undef p } //End AutoResetEvent int cfgGetIntPvr(char* key,int def) { return emu.ConfigLoadInt("drkpvr",key,def); } void cfgSetIntPvr(char* key,int val) { emu.ConfigSaveInt("drkpvr",key,val); } void LoadSettingsPvr() { drkpvr_settings.Emulation.AlphaSortMode = cfgGetIntPvr("Emulation.AlphaSortMode",1); drkpvr_settings.Emulation.PaletteMode = cfgGetIntPvr("Emulation.PaletteMode",1); drkpvr_settings.Emulation.ModVolMode = cfgGetIntPvr("Emulation.ModVolMode",MVM_NormalAndClip); drkpvr_settings.Emulation.ZBufferMode = cfgGetIntPvr("Emulation.ZBufferMode",0); drkpvr_settings.Emulation.TexCacheMode = cfgGetIntPvr("Emulation.TexCacheMode",0); drkpvr_settings.OSD.ShowFPS = cfgGetIntPvr("OSD.ShowFPS",0); drkpvr_settings.OSD.ShowStats = cfgGetIntPvr("OSD.ShowStats",0); drkpvr_settings.Video.ResolutionMode = cfgGetIntPvr("Video.ResolutionMode",0); drkpvr_settings.Video.VSync = cfgGetIntPvr("Video.VSync",0); drkpvr_settings.Enhancements.MultiSampleCount = cfgGetIntPvr("Enhancements.MultiSampleCount",0); drkpvr_settings.Enhancements.MultiSampleQuality = cfgGetIntPvr("Enhancements.MultiSampleQuality",0); drkpvr_settings.Enhancements.AspectRatioMode = cfgGetIntPvr("Enhancements.AspectRatioMode",1); drkpvr_settings.Emulation.ZBufferMode=2; drkpvr_settings.Emulation.AlphaSortMode=1; drkpvr_settings.Emulation.PaletteMode=1; // drkpvr_settings.Emulation.TexCacheMode=1; drkpvr_settings.Emulation.ModVolMode=MVM_Off; } void SaveSettingsPvr() { cfgSetIntPvr("Emulation.AlphaSortMode",drkpvr_settings.Emulation.AlphaSortMode); cfgSetIntPvr("Emulation.PaletteMode",drkpvr_settings.Emulation.PaletteMode); cfgSetIntPvr("Emulation.ModVolMode",drkpvr_settings.Emulation.ModVolMode); cfgSetIntPvr("Emulation.ZBufferMode",drkpvr_settings.Emulation.ZBufferMode); cfgSetIntPvr("Emulation.TexCacheMode",drkpvr_settings.Emulation.TexCacheMode); cfgSetIntPvr("OSD.ShowFPS",drkpvr_settings.OSD.ShowFPS); cfgSetIntPvr("OSD.ShowStats",drkpvr_settings.OSD.ShowStats); cfgSetIntPvr("Video.ResolutionMode",drkpvr_settings.Video.ResolutionMode); cfgSetIntPvr("Video.VSync",drkpvr_settings.Video.VSync); cfgSetIntPvr("Enhancements.MultiSampleCount",drkpvr_settings.Enhancements.MultiSampleCount); cfgSetIntPvr("Enhancements.MultiSampleQuality",drkpvr_settings.Enhancements.MultiSampleQuality); cfgSetIntPvr("Enhancements.AspectRatioMode",drkpvr_settings.Enhancements.AspectRatioMode); }