From cc1bc8d12286b34975f5f9f6501f2d6914968185 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 18 Sep 2009 00:11:27 +0000 Subject: [PATCH] GSopen2: synched with trunk to pick up various gui fixes. git-svn-id: http://pcsx2.googlecode.com/svn/branches/GSopen2@1848 96395faa-99c1-11dd-bbfe-3dabce05a288 --- clean_msvc.cmd | 2 +- common/src/Utilities/ThreadTools.cpp | 2 + pcsx2-codeblocks.workspace | 4 +- pcsx2/FiFo.cpp | 18 +- pcsx2/Linux/pcsx2.cbp | 1 + pcsx2/VifDma.cpp | 330 +++++++++++------------ pcsx2/gui/App.h | 2 + pcsx2/gui/AppMain.cpp | 17 +- pcsx2/gui/ConsoleLogger.cpp | 3 +- pcsx2/gui/MainFrame.cpp | 11 +- pcsx2/gui/MainFrame.h | 2 +- pcsx2/gui/MainMenuClicks.cpp | 6 +- pcsx2/gui/Panels/PluginSelectorPanel.cpp | 8 +- pcsx2/gui/Panels/SpeedhacksPanel.cpp | 11 +- pcsx2/gui/Plugins.cpp | 184 ++++++++----- 15 files changed, 326 insertions(+), 275 deletions(-) diff --git a/clean_msvc.cmd b/clean_msvc.cmd index 581f69efbb..351ad92128 100644 --- a/clean_msvc.cmd +++ b/clean_msvc.cmd @@ -9,4 +9,4 @@ :: so, don't go running this batch file in your root c:\ folder. It's probably not a wise action. :: Enjoy. :) -del /s *.ncb;*.ilk;*.pdb;*.bsc;*.sbr;*.res \ No newline at end of file +del /s *.ncb;*.ilk;*.pdb;*.bsc;*.sbr;*.res;*.pch \ No newline at end of file diff --git a/common/src/Utilities/ThreadTools.cpp b/common/src/Utilities/ThreadTools.cpp index 934f77def7..5d79f2ac70 100644 --- a/common/src/Utilities/ThreadTools.cpp +++ b/common/src/Utilities/ThreadTools.cpp @@ -165,6 +165,8 @@ namespace Threading bool PersistentThread::IsRunning() const { + if (!m_running) return false; + if( !!m_detached ) return !!m_running; else diff --git a/pcsx2-codeblocks.workspace b/pcsx2-codeblocks.workspace index 1268984b69..6aa305ae6e 100644 --- a/pcsx2-codeblocks.workspace +++ b/pcsx2-codeblocks.workspace @@ -1,7 +1,7 @@ - + @@ -22,6 +22,6 @@ - + diff --git a/pcsx2/FiFo.cpp b/pcsx2/FiFo.cpp index e89c47525f..113b5288d9 100644 --- a/pcsx2/FiFo.cpp +++ b/pcsx2/FiFo.cpp @@ -1,6 +1,6 @@ /* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2009 PCSX2 Dev Team - * + * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -52,7 +52,7 @@ extern int FOreadpos; void __fastcall ReadFIFO_page_4(u32 mem, u64 *out) { jASSUME( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) ); - + VIF_LOG("ReadFIFO/VIF0 0x%08X", mem); //out[0] = psHu64(mem ); //out[1] = psHu64(mem+8); @@ -93,7 +93,7 @@ void __fastcall ReadFIFO_page_6(u32 mem, u64 *out) //out[1] = psHu64(mem+8); out[0] = psHu64(0x6000); - out[1] = psHu64(0x6008); + out[1] = psHu64(0x6008); } void __fastcall ReadFIFO_page_7(u32 mem, u64 *out) @@ -126,24 +126,24 @@ void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value) jASSUME( (mem >= VIF0_FIFO) && (mem < VIF1_FIFO) ); VIF_LOG("WriteFIFO/VIF0, addr=0x%08X", mem); - + //psHu64(mem ) = value[0]; //psHu64(mem+8) = value[1]; psHu64(0x4000) = value[0]; psHu64(0x4008) = value[1]; - + vif0ch->qwc += 1; int ret = VIF0transfer((u32*)value, 4, 0); assert( ret == 0 ); // vif stall code not implemented } - + void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value) { jASSUME( (mem >= VIF1_FIFO) && (mem < GIF_FIFO) ); VIF_LOG("WriteFIFO/VIF1, addr=0x%08X", mem); - + //psHu64(mem ) = value[0]; //psHu64(mem+8) = value[1]; @@ -175,14 +175,14 @@ void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value) psHu64(0x6008) = value[1]; FreezeRegs(1); - const uint count = mtgsThread->PrepDataPacket(GIF_PATH_3, nloop0_packet, 1); + mtgsThread->PrepDataPacket(GIF_PATH_3, nloop0_packet, 1); u64* data = (u64*)mtgsThread->GetDataPacketPtr(); data[0] = value[0]; data[1] = value[1]; mtgsThread->SendDataPacket(); FreezeRegs(0); } - + void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value) { jASSUME( (mem >= IPUout_FIFO) && (mem < D0_CHCR) ); diff --git a/pcsx2/Linux/pcsx2.cbp b/pcsx2/Linux/pcsx2.cbp index 151eef722c..180fbaaf3a 100644 --- a/pcsx2/Linux/pcsx2.cbp +++ b/pcsx2/Linux/pcsx2.cbp @@ -282,6 +282,7 @@ + diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index a545e9db69..b133423590 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -1,6 +1,6 @@ /* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2009 PCSX2 Dev Team - * + * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -57,7 +57,7 @@ static const unsigned int VIF0dmanum = 0; static const unsigned int VIF1dmanum = 1; int g_vifCycles = 0; -Path3Modes Path3progress = STOPPED_MODE; +Path3Modes Path3progress = STOPPED_MODE; static PCSX2_ALIGNED16( u32 splittransfer[4] ); u32 splitptr = 0; @@ -155,7 +155,7 @@ extern "C" { \ UNPACK_SkippingWrite_##name##_##sign##_WriteMask_0, \ UNPACK_SkippingWrite_##name##_##sign##_WriteMask_1, \ UNPACK_SkippingWrite_##name##_##sign##_WriteMask_2 \ - + #define _UNPACK_TABLE_SSE_NULL \ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL @@ -211,7 +211,7 @@ static const VIFSSEUnpackTable VIFfuncTableSSE[16] = __forceinline void vif0FLUSH() { int _cycles = VU0.cycle; - + // fixme: this code should call _vu0WaitMicro instead? I'm not sure if // it's purposefully ignoring ee cycles or not (see below for more) @@ -250,7 +250,7 @@ __forceinline static int _limit(int a, int max) static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int VIFdmanum) { const VIFUnpackFuncTable *unpack; - + unpack = &VIFfuncTable[ unpackType ]; switch (unpackType) @@ -313,7 +313,7 @@ static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int } //Append any skips in to the equasion - + if (vifRegs->cycle.cl > vifRegs->cycle.wl) { VIFUNPACK_LOG("Old addr %x CL %x WL %x", vif->tag.addr, vifRegs->cycle.cl, vifRegs->cycle.wl); @@ -327,11 +327,11 @@ static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int VIFUNPACK_LOG("addr aligned to %x", vif->tag.addr); vif->tag.addr = (vif->tag.addr & ~0xf) + (vifRegs->offset * 4); } - if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if(vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) { vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); } - + } static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int VIFdmanum) @@ -369,21 +369,21 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int VIF_LOG("VIF%d UNPACK Align: Mode=%x, v->size=%d, size=%d, v->addr=%x v->num=%x", VIFdmanum, v->cmd & 0xf, v->size, size, v->addr, vifRegs->num); - + // The unpack type unpackType = v->cmd & 0xf; - + ft = &VIFfuncTable[ unpackType ]; func = vif->usn ? ft->funcU : ft->funcS; size <<= 2; - + #ifdef PCSX2_DEBUG memsize = size; #endif - + if(vifRegs->offset != 0) - { + { int unpacksize; //This is just to make sure the alignment isnt loopy on a split packet @@ -399,13 +399,13 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int DevCon::Error("Wasn't enough left size/dsize = %x left to write %x", (size / ft->dsize), (ft->qsize - vifRegs->offset)); } unpacksize = min((size / ft->dsize), (ft->qsize - vifRegs->offset)); - + VIFUNPACK_LOG("Increasing dest by %x from offset %x", (4 - ft->qsize) + unpacksize, vifRegs->offset); - + func(dest, (u32*)cdata, unpacksize); size -= unpacksize * ft->dsize; - + if(vifRegs->offset == 0) { vifRegs->num--; @@ -430,13 +430,13 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int vif->tag.addr += ((4 - ft->qsize) + unpacksize) * 4; dest += (4 - ft->qsize) + unpacksize; } - - if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + + if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) { vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); dest = (u32*)(VU->Mem + v->addr); } - + cdata += unpacksize * ft->dsize; vif->cl = 0; VIFUNPACK_LOG("Aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr); @@ -447,13 +447,13 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int { vif->tag.addr += ((4 - ft->qsize) + unpacksize) * 4; dest += (4 - ft->qsize) + unpacksize; - - if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + + if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) { vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); dest = (u32*)(VU->Mem + v->addr); } - + cdata += unpacksize * ft->dsize; VIFUNPACK_LOG("Aligning packet done size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr); } @@ -465,7 +465,7 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int if (vifRegs->cycle.cl >= vifRegs->cycle.wl) // skipping write { - if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) { vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); dest = (u32*)(VU->Mem + v->addr); @@ -473,7 +473,7 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int // continuation from last stream VIFUNPACK_LOG("Continuing last stream size = %d offset %d addr %x", size, vifRegs->offset, vif->tag.addr); incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4; - + while ((size >= ft->gsize) && (vifRegs->num > 0)) { func(dest, (u32*)cdata, ft->qsize); @@ -486,7 +486,7 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int { dest += incdest; vif->tag.addr += incdest * 4; - + vif->cl = 0; if((size & 0xf) == 0)break; } @@ -495,9 +495,9 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int dest += 4; vif->tag.addr += 16; } - + // Hurrah for the 4th occurrance of this piece of code in this function... - if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if (vif->tag.addr >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) { vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); dest = (u32*)(VU->Mem + v->addr); @@ -512,14 +512,14 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int vifRow[1] = vifRegs->r1; vifRow[2] = vifRegs->r2; vifRow[3] = vifRegs->r3; - } + } } if (size >= ft->dsize && vifRegs->num > 0 && ((size & 0xf) != 0 || vif->cl != 0)) { //VIF_LOG("warning, end with size = %d", size); /* unpack one qword */ - if(vif->tag.addr + ((size / ft->dsize) * 4) >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) + if(vif->tag.addr + ((size / ft->dsize) * 4) >= (u32)(VIFdmanum ? 0x4000 : 0x1000)) { //DevCon::Notice("Overflow"); vif->tag.addr &= (u32)(VIFdmanum ? 0x3fff : 0xfff); @@ -527,7 +527,7 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int } vif->tag.addr += (size / ft->dsize) * 4; - + func(dest, (u32*)cdata, size / ft->dsize); size = 0; @@ -538,7 +538,7 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int vifRow[1] = vifRegs->r1; vifRow[2] = vifRegs->r2; vifRow[3] = vifRegs->r3; - } + } VIFUNPACK_LOG("leftover done, size %d, vifnum %d, addr %x", size, vifRegs->num, vif->tag.addr); } } @@ -555,7 +555,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i u8 *cdata = (u8*)data; u32 tempsize = 0; const u32 memlimit = (VIFdmanum ? 0x4000 : 0x1000); - + #ifdef PCSX2_DEBUG u32 memsize = memlimit; #endif @@ -593,19 +593,19 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i unpackType = v->cmd & 0xf; _mm_prefetch((char*)data + 128, _MM_HINT_NTA); - + ft = &VIFfuncTable[ unpackType ]; func = vif->usn ? ft->funcU : ft->funcS; size <<= 2; - + #ifdef PCSX2_DEBUG memsize = size; #endif - + if (vifRegs->cycle.cl >= vifRegs->cycle.wl) // skipping write { - if (v->addr >= memlimit) + if (v->addr >= memlimit) { //DevCon::Notice("Overflown at the start"); v->addr &= (memlimit - 1); @@ -614,18 +614,18 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i size = min(size, (int)vifRegs->num * ft->gsize); //size will always be the same or smaller - tempsize = vif->tag.addr + ((((vifRegs->num-1) / vifRegs->cycle.wl) * + tempsize = vif->tag.addr + ((((vifRegs->num-1) / vifRegs->cycle.wl) * (vifRegs->cycle.cl - vifRegs->cycle.wl)) * 16) + (vifRegs->num * 16); - /*tempsize = vif->tag.addr + (((size / (ft->gsize * vifRegs->cycle.wl)) * + /*tempsize = vif->tag.addr + (((size / (ft->gsize * vifRegs->cycle.wl)) * (vifRegs->cycle.cl - vifRegs->cycle.wl)) * 16) + (vifRegs->num * 16);*/ - + //Sanity Check (memory overflow) - if (tempsize > memlimit) + if (tempsize > memlimit) { - if (((vifRegs->cycle.cl != vifRegs->cycle.wl) && - ((memlimit + (vifRegs->cycle.cl - vifRegs->cycle.wl) * 16) == tempsize) || + if (((vifRegs->cycle.cl != vifRegs->cycle.wl) && + ((memlimit + (vifRegs->cycle.cl - vifRegs->cycle.wl) * 16) == tempsize) || (tempsize == memlimit))) { //It's a red herring, so ignore it! SSE unpacks will be much quicker. @@ -637,12 +637,12 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i tempsize = size; size = 0; } - } - else + } + else { tempsize = 0; //Commenting out this then //tempsize = size; // -\_uncommenting these Two enables non-SSE unpacks - //size = 0; // -/ + //size = 0; // -/ } if (size >= ft->gsize) @@ -679,13 +679,13 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i } #endif - if ((vifRegs->cycle.cl == 0) || (vifRegs->cycle.wl == 0) || + if ((vifRegs->cycle.cl == 0) || (vifRegs->cycle.wl == 0) || ((vifRegs->cycle.cl == vifRegs->cycle.wl) && !(vifRegs->code & 0x10000000))) { oldcycle = *(u32*) & vifRegs->cycle; vifRegs->cycle.cl = vifRegs->cycle.wl = 1; } - + pfn = vif->usn ? VIFfuncTableSSE[unpackType].funcU : VIFfuncTableSSE[unpackType].funcS; writemask = VIFdmanum ? g_vif1HasMask3[min(vifRegs->cycle.wl,(u8)3)] : g_vif0HasMask3[min(vifRegs->cycle.wl,(u8)3)]; writemask = pfn[(((vifRegs->code & 0x10000000)>>28)<mode](dest, (u32*)cdata, size); @@ -700,7 +700,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i vifRegs->r2 = vifRow[2]; vifRegs->r3 = vifRow[3]; } - + // if size is left over, update the src,dst pointers if (writemask > 0) @@ -728,7 +728,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i vifRow[1] = vifRegs->r1; vifRow[2] = vifRegs->r2; vifRow[3] = vifRegs->r3; - } + } VIFUNPACK_LOG("leftover done, size %d, vifnum %d, addr %x", size, vifRegs->num, vif->tag.addr); } } @@ -739,25 +739,25 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i size = 0; } - } + } else if(tempsize) { int incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4; size = 0; int addrstart = v->addr; if((tempsize >> 2) != vif->tag.size) DevCon::Notice("split when size != tagsize"); - + VIFUNPACK_LOG("sorting tempsize :p, size %d, vifnum %d, addr %x", tempsize, vifRegs->num, vif->tag.addr); while ((tempsize >= ft->gsize) && (vifRegs->num > 0)) { - if(v->addr >= memlimit) + if(v->addr >= memlimit) { DevCon::Notice("Mem limit ovf"); v->addr &= (memlimit - 1); dest = (u32*)(VU->Mem + v->addr); } - + func(dest, (u32*)cdata, ft->qsize); cdata += ft->gsize; tempsize -= ft->gsize; @@ -773,7 +773,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i else { dest += 4; - v->addr += 16; + v->addr += 16; } } @@ -785,7 +785,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i vifRow[2] = vifRegs->r2; vifRow[3] = vifRegs->r3; } - if(v->addr >= memlimit) + if(v->addr >= memlimit) { v->addr &= (memlimit - 1); dest = (u32*)(VU->Mem + v->addr); @@ -818,9 +818,9 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i { if(vifRegs->cycle.cl > 0) // Quicker and avoids zero division :P - if((u32)(((size / ft->gsize) / vifRegs->cycle.cl) * vifRegs->cycle.wl) < vifRegs->num) + if((u32)(((size / ft->gsize) / vifRegs->cycle.cl) * vifRegs->cycle.wl) < vifRegs->num) DevCon::Notice("Filling write warning! %x < %x and CL = %x WL = %x", (size / ft->gsize), vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl); - + //DevCon::Notice("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x addr %x", vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, unpackType, vif->tag.addr); while (vifRegs->num > 0) { @@ -828,25 +828,25 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i { vif->cl = 0; } - + if (vif->cl < vifRegs->cycle.cl) /* unpack one qword */ { - if(size < ft->gsize) + if(size < ft->gsize) { VIF_LOG("Out of Filling write data"); break; } - + func(dest, (u32*)cdata, ft->qsize); cdata += ft->gsize; size -= ft->gsize; vif->cl++; vifRegs->num--; - + if (vif->cl == vifRegs->cycle.wl) { vif->cl = 0; - } + } } else { @@ -876,7 +876,7 @@ static void vuExecMicro(u32 addr, const u32 VIFdmanum) VU = &VU1; vif1FLUSH(); } - + if (VU->vifRegs->itops > (VIFdmanum ? 0x3ffu : 0xffu)) Console::WriteLn("VIF%d ITOP overrun! %x", VIFdmanum, VU->vifRegs->itops); @@ -890,7 +890,7 @@ static void vuExecMicro(u32 addr, const u32 VIFdmanum) /* is DBF flag set in VIF_STAT? */ if (VU->vifRegs->stat & VIF_STAT_DBF) { - /* it is, so set tops with base, and set the stat DBF flag */ + /* it is, so set tops with base, and set the stat DBF flag */ VU->vifRegs->tops = VU->vifRegs->base; VU->vifRegs->stat &= ~VIF_STAT_DBF; } @@ -955,7 +955,7 @@ static __forceinline void vif0UNPACK(u32 *data) vif0.tag.cmd = vif0.cmd; vif0Regs->offset = 0; - + } static __forceinline void vif0mpgTransfer(u32 addr, u32 *data, int size) @@ -1066,24 +1066,24 @@ static int __fastcall Vif0TransMPG(u32 *data) // MPG if (vif0.vifpacketsize < vif0.tag.size) { if((vif0.tag.addr + vif0.vifpacketsize) > 0x1000) DevCon::Notice("Vif0 MPG Split Overflow"); - + vif0mpgTransfer(vif0.tag.addr, data, vif0.vifpacketsize); vif0.tag.addr += vif0.vifpacketsize << 2; vif0.tag.size -= vif0.vifpacketsize; - + return vif0.vifpacketsize; } else { int ret; - + if((vif0.tag.addr + vif0.tag.size) > 0x1000) DevCon::Notice("Vif0 MPG Overflow"); - + vif0mpgTransfer(vif0.tag.addr, data, vif0.tag.size); ret = vif0.tag.size; vif0.tag.size = 0; vif0.cmd = 0; - + return ret; } } @@ -1091,28 +1091,28 @@ static int __fastcall Vif0TransMPG(u32 *data) // MPG static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK { int ret; - + FreezeXMMRegs(1); if (vif0.vifpacketsize < vif0.tag.size) { - if(vif0Regs->offset != 0 || vif0.cl != 0) + if(vif0Regs->offset != 0 || vif0.cl != 0) { ret = vif0.tag.size; vif0.tag.size -= vif0.vifpacketsize - VIFalign(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum); ret = ret - vif0.tag.size; data += ret; - + if(vif0.vifpacketsize > 0) VIFunpack(data, &vif0.tag, vif0.vifpacketsize - ret, VIF0dmanum); - + ProcessMemSkip((vif0.vifpacketsize - ret) << 2, (vif0.cmd & 0xf), VIF0dmanum); vif0.tag.size -= (vif0.vifpacketsize - ret); FreezeXMMRegs(0); - + return vif0.vifpacketsize; - } + } /* size is less that the total size, transfer is 'in pieces' */ VIFunpack(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum); - + ProcessMemSkip(vif0.vifpacketsize << 2, (vif0.cmd & 0xf), VIF0dmanum); ret = vif0.vifpacketsize; @@ -1122,9 +1122,9 @@ static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK { /* we got all the data, transfer it fully */ ret = vif0.tag.size; - + //Align data after a split transfer first - if ((vif0Regs->offset != 0) || (vif0.cl != 0)) + if ((vif0Regs->offset != 0) || (vif0.cl != 0)) { vif0.tag.size = VIFalign(data, &vif0.tag, vif0.tag.size, VIF0dmanum); data += ret - vif0.tag.size; @@ -1134,11 +1134,11 @@ static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK { VIFunpack(data, &vif0.tag, vif0.tag.size, VIF0dmanum); } - + vif0.tag.size = 0; vif0.cmd = 0; } - + FreezeXMMRegs(0); return ret; } @@ -1244,7 +1244,7 @@ int VIF0transfer(u32 *data, int size, int istag) if (vif0.cmd) { vif0Regs->stat |= VIF0_STAT_VPS_T; //Decompression has started - + ret = Vif0TransTLB[(vif0.cmd & 0x7f)](data); data += ret; vif0.vifpacketsize -= ret; @@ -1253,7 +1253,7 @@ int VIF0transfer(u32 *data, int size, int istag) } if (vif0.tag.size != 0) Console::WriteLn("no vif0 cmd but tag size is left last cmd read %x", vif0Regs->code); - + // if interrupt and new cmd is NOT MARK if (vif0.irq) break; @@ -1280,7 +1280,7 @@ int VIF0transfer(u32 *data, int size, int istag) } vif0.cmd = 0; } - else + else { Vif0CMDTLB[(vif0.cmd & 0x7f)](); } @@ -1316,11 +1316,11 @@ int VIF0transfer(u32 *data, int size, int istag) if (((vif0Regs->code >> 24) & 0x7f) != 0x7)vif0Regs->stat |= VIF0_STAT_VIS; //else Console::WriteLn("VIF0 IRQ on MARK"); - + // spiderman doesn't break on qw boundaries vif0.irqoffset = transferred % 4; // cannot lose the offset - if (!istag) + if (!istag) { transferred = transferred >> 2; vif0ch->madr += (transferred << 4); @@ -1372,24 +1372,24 @@ int _chainVIF0() int id, ret; vif0ptag = (u32*)dmaGetAddr(vif0ch->tadr); //Set memory pointer to TADR - + if (!(Tag::Transfer("Vif0 Tag", vif0ch, vif0ptag))) return -1; - + vif0ch->madr = vif0ptag[1]; // MADR = ADDR field id = Tag::Id(vif0ptag); // ID for DmaChain copied from bit 28 of the tag g_vifCycles += 1; // Increase the QW read for the tag - + VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx", vif0ptag[1], vif0ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr); // Transfer dma tag if tte is set if (vif0ch->chcr.TTE) { - if (vif0.vifstalled) + if (vif0.vifstalled) ret = VIF0transfer(vif0ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset, 1); //Transfer Tag on stall - else + else ret = VIF0transfer(vif0ptag + 2, 2, 1); //Transfer Tag - + if (ret == -1) return -1; //There has been an error if (ret == -2) return -2; //IRQ set by VIFTransfer } @@ -1427,14 +1427,14 @@ void vif0Interrupt() vif0ch->chcr.STR = 0; return; } - + if (vif0ch->qwc > 0 || vif0.irqoffset > 0) { if (vif0.stallontag) _chainVIF0(); - else + else _VIF0chain(); - + CPU_INT(0, g_vifCycles); return; } @@ -1453,16 +1453,16 @@ void vif0Interrupt() if (vif0ch->qwc > 0) _VIF0chain(); - else + else _chainVIF0(); - + CPU_INT(0, g_vifCycles); return; } if (vif0ch->qwc > 0) Console::WriteLn("VIF0 Ending with QWC left"); if (vif0.cmd != 0) Console::WriteLn("vif0.cmd still set %x", vif0.cmd); - + vif0ch->chcr.STR = 0; hwDmacIrq(DMAC_VIF0); vif0Regs->stat &= ~VIF0_STAT_FQC; // FQC=0 @@ -1523,7 +1523,7 @@ void dmaVIF0() vif0.vifstalled = true; return; } - + vif0.done = true; CPU_INT(0, g_vifCycles); return; @@ -1545,7 +1545,7 @@ void vif0Write32(u32 mem, u32 value) vif0Regs->stat &= ~VIF0_STAT_MRK; vif0Regs->mark = value; break; - + case VIF0_FBRST: VIF_LOG("VIF0_FBRST write32 0x%8.8x", value); @@ -1562,7 +1562,7 @@ void vif0Write32(u32 mem, u32 value) vif0Regs->err._u32 = 0; vif0Regs->stat &= ~(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0 } - + if (value & 0x2) { /* Force Break the VIF */ @@ -1573,7 +1573,7 @@ void vif0Write32(u32 mem, u32 value) vif0.vifstalled = true; Console::WriteLn("vif0 force break"); } - + if (value & 0x4) { /* Stop VIF */ @@ -1583,7 +1583,7 @@ void vif0Write32(u32 mem, u32 value) vif0Regs->stat &= ~VIF0_STAT_VPS; vif0.vifstalled = true; } - + if (value & 0x8) { bool cancel = false; @@ -1612,7 +1612,7 @@ void vif0Write32(u32 mem, u32 value) } } break; - + case VIF0_ERR: // ERR VIF_LOG("VIF0_ERR write32 0x%8.8x", value); @@ -1620,7 +1620,7 @@ void vif0Write32(u32 mem, u32 value) /* Set VIF0_ERR with 'value' */ vif0Regs->err._u32 = value; break; - + case VIF0_R0: case VIF0_R1: case VIF0_R2: @@ -1628,7 +1628,7 @@ void vif0Write32(u32 mem, u32 value) assert((mem&0xf) == 0); g_vifRow0[(mem>>4) & 3] = value; break; - + case VIF0_C0: case VIF0_C1: case VIF0_C2: @@ -1636,7 +1636,7 @@ void vif0Write32(u32 mem, u32 value) assert((mem&0xf) == 0); g_vifCol0[(mem>>4) & 3] = value; break; - + default: Console::WriteLn("Unknown Vif0 write to %x", mem); psHu32(mem) = value; @@ -1717,9 +1717,9 @@ static __forceinline void vif1UNPACK(u32 *data) int n = vif1Regs->cycle.cl * (vifNum / vif1Regs->cycle.wl) + _limit(vifNum % vif1Regs->cycle.wl, vif1Regs->cycle.cl); - vif1.tag.size = ((n * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2; - } - + vif1.tag.size = ((n * VIFfuncTable[ vif1.cmd & 0xf ].gsize) + 3) >> 2; + } + if ((vif1Regs->code >> 15) & 0x1) vif1.tag.addr = (vif1Regs->code + vif1Regs->tops) & 0x3ff; else @@ -1867,7 +1867,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data) { vif1Regs->stat |= VIF1_STAT_VGW; return 0; - } + } } psHu32(GIF_STAT) |= (GIF_STAT_APATH2 | GIF_STAT_OPH); @@ -1887,7 +1887,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data) FreezeRegs(1); // copy 16 bytes the fast way: const u64* src = (u64*)splittransfer[0]; - const uint count = mtgsThread->PrepDataPacket(GIF_PATH_2, nloop0_packet, 1); + mtgsThread->PrepDataPacket(GIF_PATH_2, nloop0_packet, 1); u64* dst = (u64*)mtgsThread->GetDataPacketPtr(); dst[0] = src[0]; dst[1] = src[1]; @@ -1945,7 +1945,7 @@ static int __fastcall Vif1TransUnpack(u32 *data) { int ret = vif1.tag.size; /* size is less that the total size, transfer is 'in pieces' */ - if(vif1Regs->offset != 0 || vif1.cl != 0) + if(vif1Regs->offset != 0 || vif1.cl != 0) { vif1.tag.size -= vif1.vifpacketsize - VIFalign(data, &vif1.tag, vif1.vifpacketsize, VIF1dmanum); ret = ret - vif1.tag.size; @@ -1955,7 +1955,7 @@ static int __fastcall Vif1TransUnpack(u32 *data) vif1.tag.size -= (vif1.vifpacketsize - ret); FreezeXMMRegs(0); return vif1.vifpacketsize; - } + } VIFunpack(data, &vif1.tag, vif1.vifpacketsize, VIF1dmanum); ProcessMemSkip(vif1.vifpacketsize << 2, (vif1.cmd & 0xf), VIF1dmanum); @@ -1967,7 +1967,7 @@ static int __fastcall Vif1TransUnpack(u32 *data) { int ret = vif1.tag.size; - if(vif1Regs->offset != 0 || vif1.cl != 0) + if(vif1Regs->offset != 0 || vif1.cl != 0) { vif1.tag.size = VIFalign(data, &vif1.tag, vif1.tag.size, VIF1dmanum); data += ret - vif1.tag.size; @@ -1976,7 +1976,7 @@ static int __fastcall Vif1TransUnpack(u32 *data) vif1.cmd = 0; FreezeXMMRegs(0); return ret; - } + } else { /* we got all the data, transfer it fully */ @@ -2046,11 +2046,11 @@ void Vif1MskPath3() // MSKPATH3 else { //Let the Gif know it can transfer again (making sure any vif stall isnt unset prematurely) - Path3progress = TRANSFER_MODE; + Path3progress = TRANSFER_MODE; psHu32(GIF_STAT) &= ~GIF_STAT_IMT; - CPU_INT(2, 4); + CPU_INT(2, 4); } - + schedulepath3msk = 0; } static void Vif1CMDMskPath3() // MSKPATH3 @@ -2060,7 +2060,7 @@ static void Vif1CMDMskPath3() // MSKPATH3 schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1); vif1.vifstalled = true; } - else + else { schedulepath3msk = (vif1Regs->code >> 15) & 0x1; Vif1MskPath3(); @@ -2084,8 +2084,8 @@ static void Vif1CMDFlush() // FLUSH/E/A { // Gif is already transferring so wait for it. if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && gif->chcr.STR) - { - vif1Regs->stat |= VIF1_STAT_VGW; + { + vif1Regs->stat |= VIF1_STAT_VGW; CPU_INT(2, 4); } } @@ -2208,19 +2208,19 @@ int VIF1transfer(u32 *data, int size, int istag) vif1.vifpacketsize = size; while (vif1.vifpacketsize > 0) - { + { if(vif1Regs->stat & VIF1_STAT_VGW) break; - + if (vif1.cmd) { vif1Regs->stat |= VIF1_STAT_VPS_T; //Decompression has started - + ret = Vif1TransTLB[vif1.cmd](data); data += ret; vif1.vifpacketsize -= ret; - + //We are once again waiting for a new vifcode as the command has cleared - if (vif1.cmd == 0) vif1Regs->stat &= ~VIF1_STAT_VPS_T; + if (vif1.cmd == 0) vif1Regs->stat &= ~VIF1_STAT_VPS_T; continue; } @@ -2288,7 +2288,7 @@ int VIF1transfer(u32 *data, int size, int istag) if (((vif1Regs->code >> 24) & 0x7f) != 0x7) vif1Regs->stat |= VIF1_STAT_VIS; // Note: commenting this out fixes WALL-E if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) vif1.inprogress &= ~0x1; - + // spiderman doesn't break on qw boundaries if (istag) return -2; @@ -2308,14 +2308,14 @@ int VIF1transfer(u32 *data, int size, int istag) { transferred = transferred >> 2; vif1ch->madr += (transferred << 4); - vif1ch->qwc -= transferred; + vif1ch->qwc -= transferred; } - + if(vif1Regs->stat & VIF1_STAT_VGW) { vif1.vifstalled = true; } - + if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) vif1.inprogress &= ~0x1; @@ -2345,7 +2345,7 @@ void vif1TransferFromMemory() // completely and execute the transfer there-after. FreezeXMMRegs(1); - + if (GSreadFIFO2 == NULL) { for (size = vif1ch->qwc; size > 0; --size) @@ -2369,9 +2369,9 @@ void vif1TransferFromMemory() psHu64(0x5000) = pMem[2*vif1ch->qwc-2]; psHu64(0x5008) = pMem[2*vif1ch->qwc-1]; } - + FreezeXMMRegs(0); - + g_vifCycles += vif1ch->qwc * 2; vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes vif1ch->qwc = 0; @@ -2396,7 +2396,7 @@ int _VIF1chain() } pMem = (u32*)dmaGetAddr(vif1ch->madr); - if (pMem == NULL) + if (pMem == NULL) { vif1.cmd = 0; vif1.tag.size = 0; @@ -2436,9 +2436,9 @@ __forceinline void vif1SetupTransfer() int ret; vif1ptag = (u32*)dmaGetAddr(vif1ch->tadr); //Set memory pointer to TADR - + if (!(Tag::Transfer("Vif1 Tag", vif1ch, vif1ptag))) return; - + vif1ch->madr = vif1ptag[1]; //MADR = ADDR field g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag id = Tag::Id(vif1ptag); //ID for DmaChain copied from bit 28 of the tag @@ -2469,7 +2469,7 @@ __forceinline void vif1SetupTransfer() else ret = VIF1transfer(vif1ptag + 2, 2, 1); //Transfer Tag - if (ret < 0 && vif1.irqoffset < 2) + if (ret < 0 && vif1.irqoffset < 2) { vif1.inprogress = 0; //Better clear this so it has to do it again (Jak 1) return; //There has been an error or an interrupt @@ -2480,7 +2480,7 @@ __forceinline void vif1SetupTransfer() vif1.done |= hwDmacSrcChainWithStack(vif1ch, id); //Check TIE bit of CHCR and IRQ bit of tag - if (vif1ch->chcr.TIE && (Tag::IRQ(vif1ptag))) + if (vif1ch->chcr.TIE && (Tag::IRQ(vif1ptag))) { VIF_LOG("dmaIrq Set"); @@ -2502,12 +2502,12 @@ __forceinline void vif1Interrupt() if((vif1Regs->stat & VIF1_STAT_VGW)) { if (gif->chcr.STR) - { + { CPU_INT(1, gif->qwc * BIAS); return; - } + } else vif1Regs->stat &= ~VIF1_STAT_VGW; - + } if (!(vif1ch->chcr.STR)) Console::WriteLn("Vif1 running when CHCR == %x", vif1ch->chcr._u32); @@ -2520,7 +2520,7 @@ __forceinline void vif1Interrupt() if (vif1Regs->stat & (VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) { vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0 - + // One game doesnt like vif stalling at end, cant remember what. Spiderman isnt keen on it tho vif1ch->chcr.STR = 0; return; @@ -2534,7 +2534,7 @@ __forceinline void vif1Interrupt() } } - if (vif1.inprogress & 0x1) + if (vif1.inprogress & 0x1) { _VIF1chain(); CPU_INT(1, g_vifCycles); @@ -2555,8 +2555,8 @@ __forceinline void vif1Interrupt() CPU_INT(1, g_vifCycles); return; } - - if (vif1.vifstalled && vif1.irq) + + if (vif1.vifstalled && vif1.irq) { CPU_INT(1, 0); return; //Dont want to end if vif is stalled. @@ -2571,7 +2571,7 @@ __forceinline void vif1Interrupt() g_vifCycles = 0; hwDmacIrq(DMAC_VIF1); - //Im not totally sure why Path3 Masking makes it want to see stuff in the fifo + //Im not totally sure why Path3 Masking makes it want to see stuff in the fifo //Games effected by setting, Fatal Frame, KH2, Shox, Crash N Burn, GT3/4 possibly //Im guessing due to the full gs fifo before the reverse? (Refraction) //Note also this is only the condition for reverse fifo mode, normal direction clears it as normal @@ -2587,7 +2587,7 @@ void dmaVIF1() g_vifCycles = 0; vif1.inprogress = 0; - + if (dmacRegs->ctrl.MFD == MFD_VIF1) // VIF MFIFO { //Console::WriteLn("VIFMFIFO\n"); @@ -2595,7 +2595,7 @@ void dmaVIF1() if (vif1ch->chcr.MOD == NORMAL_MODE) Console::WriteLn("MFIFO mode is normal (which isn't normal here)! %x", vif1ch->chcr); vifMFIFOInterrupt(); return; - } + } #ifdef PCSX2_DEVBUILD if (dmacRegs->ctrl.STD == STD_VIF1) @@ -2615,14 +2615,14 @@ void dmaVIF1() else vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE; } - else + else { vif1.dmamode = VIF_CHAIN_MODE; } if (vif1.dmamode != VIF_NORMAL_FROM_MEM_MODE) vif1Regs->stat |= 0x10000000; // FQC=16 - else + else vif1Regs->stat |= min((u16)16, vif1ch->qwc) << 24; // FQC=16 // Chain Mode @@ -2641,7 +2641,7 @@ void vif1Write32(u32 mem, u32 value) vif1Regs->stat &= ~VIF1_STAT_MRK; vif1Regs->mark = value; break; - + case VIF1_FBRST: // FBRST VIF_LOG("VIF1_FBRST write32 0x%8.8x", value); @@ -2654,19 +2654,19 @@ void vif1Write32(u32 mem, u32 value) psHu64(VIF1_FIFO) = 0; psHu64(VIF1_FIFO + 8) = 0; vif1.done = true; - + if(vif1Regs->mskpath3) { vif1Regs->mskpath3 = 0; gifRegs->stat.IMT = 0; - if (gif->chcr.STR) CPU_INT(2, 4); + if (gif->chcr.STR) CPU_INT(2, 4); } - + vif1Regs->err._u32 = 0; vif1.inprogress = 0; vif1Regs->stat &= ~(VIF1_STAT_FQC | VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0 } - + if (value & 0x2) { /* Force Break the VIF */ @@ -2677,7 +2677,7 @@ void vif1Write32(u32 mem, u32 value) vif1.vifstalled = true; Console::WriteLn("vif1 force break"); } - + if (value & 0x4) { /* Stop VIF */ @@ -2688,7 +2688,7 @@ void vif1Write32(u32 mem, u32 value) cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's vif1.vifstalled = true; } - + if (value & 0x8) { bool cancel = false; @@ -2701,7 +2701,7 @@ void vif1Write32(u32 mem, u32 value) vif1Regs->stat &= ~(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS | VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1); - + if (cancel) { if (vif1.vifstalled) @@ -2723,14 +2723,14 @@ void vif1Write32(u32 mem, u32 value) } } break; - + case VIF1_ERR: // ERR VIF_LOG("VIF1_ERR write32 0x%8.8x", value); /* Set VIF1_ERR with 'value' */ vif1Regs->err._u32 = value; break; - + case VIF1_STAT: // STAT VIF_LOG("VIF1_STAT write32 0x%8.8x", value); @@ -2759,11 +2759,11 @@ void vif1Write32(u32 mem, u32 value) vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0 } break; - + case VIF1_MODE: // MODE vif1Regs->mode = value; break; - + case VIF1_R0: case VIF1_R1: case VIF1_R2: @@ -2771,7 +2771,7 @@ void vif1Write32(u32 mem, u32 value) assert((mem&0xf) == 0); g_vifRow1[(mem>>4) & 3] = value; break; - + case VIF1_C0: case VIF1_C1: case VIF1_C2: @@ -2779,7 +2779,7 @@ void vif1Write32(u32 mem, u32 value) assert((mem&0xf) == 0); g_vifCol1[(mem>>4) & 3] = value; break; - + default: Console::WriteLn("Unknown Vif1 write to %x", mem); psHu32(mem) = value; diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index ca9e799702..fedcf73262 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -36,6 +36,7 @@ BEGIN_DECLARE_EVENT_TYPES() DECLARE_EVENT_TYPE( pxEVT_SemaphorePing, -1 ) DECLARE_EVENT_TYPE( pxEVT_OpenModalDialog, -1 ) DECLARE_EVENT_TYPE( pxEVT_ReloadPlugins, -1 ) + DECLARE_EVENT_TYPE( pxEVT_LoadPluginsComplete, -1 ) END_DECLARE_EVENT_TYPES() // ------------------------------------------------------------------------ @@ -365,6 +366,7 @@ protected: void HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const; void OnReloadPlugins( wxCommandEvent& evt ); + void OnLoadPluginsComplete( wxCommandEvent& evt ); void OnSemaphorePing( wxCommandEvent& evt ); void OnOpenModalDialog( wxCommandEvent& evt ); void OnMessageBox( pxMessageBoxEvent& evt ); diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index 61741ee988..04dfc0ebae 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -27,13 +27,14 @@ #include #include -#include +#include IMPLEMENT_APP(Pcsx2App) DEFINE_EVENT_TYPE( pxEVT_SemaphorePing ); DEFINE_EVENT_TYPE( pxEVT_OpenModalDialog ); DEFINE_EVENT_TYPE( pxEVT_ReloadPlugins ); +DEFINE_EVENT_TYPE( pxEVT_LoadPluginsComplete ); bool UseAdminMode = false; wxDirName SettingsFolder; @@ -427,6 +428,7 @@ bool Pcsx2App::OnInit() Connect( pxEVT_SemaphorePing, wxCommandEventHandler( Pcsx2App::OnSemaphorePing ) ); Connect( pxEVT_OpenModalDialog, wxCommandEventHandler( Pcsx2App::OnOpenModalDialog ) ); Connect( pxEVT_ReloadPlugins, wxCommandEventHandler( Pcsx2App::OnReloadPlugins ) ); + Connect( pxEVT_LoadPluginsComplete, wxCommandEventHandler( Pcsx2App::OnLoadPluginsComplete ) ); Connect( pxID_Window_GS, wxEVT_KEY_DOWN, wxKeyEventHandler( Pcsx2App::OnEmuKeyDown ) ); @@ -630,12 +632,13 @@ void Pcsx2App::OnMessageBox( pxMessageBoxEvent& evt ) Msgbox::OnEvent( evt ); } -#include - void Pcsx2App::CleanupMess() { - m_CorePlugins->Close(); - m_CorePlugins->Shutdown(); + if( m_CorePlugins ) + { + m_CorePlugins->Close(); + m_CorePlugins->Shutdown(); + } // Notice: deleting the plugin manager (unloading plugins) here causes Lilypad to crash, // likely due to some pending message in the queue that references lilypad procs. @@ -768,7 +771,7 @@ void Pcsx2App::LoadSettings() IniLoader loader( *conf ); g_Conf->LoadSave( loader ); - if( m_MainFrame != NULL ) + if( m_MainFrame != NULL && m_MainFrame->m_RecentIsoList ) m_MainFrame->m_RecentIsoList->Load( *conf ); } @@ -780,6 +783,6 @@ void Pcsx2App::SaveSettings() IniSaver saver( *conf ); g_Conf->LoadSave( saver ); - if( m_MainFrame != NULL ) + if( m_MainFrame != NULL && m_MainFrame->m_RecentIsoList ) m_MainFrame->m_RecentIsoList->Save( *conf ); } diff --git a/pcsx2/gui/ConsoleLogger.cpp b/pcsx2/gui/ConsoleLogger.cpp index 667cb2d9da..996a45532a 100644 --- a/pcsx2/gui/ConsoleLogger.cpp +++ b/pcsx2/gui/ConsoleLogger.cpp @@ -574,7 +574,7 @@ namespace Console // [TODO] make this a configurable option? Do we care? :) #ifdef __LINUX__ // puts does automatic newlines, which we don't want here - fputs( "PCSX2 > ", stdout ); + //fputs( "PCSX2 > ", stdout ); fputs( src, stdout ); #endif @@ -635,6 +635,7 @@ namespace Console bool __fastcall WriteLn( const wxString& fmt ) { const wxString fmtline( fmt + L"\n" ); + _immediate_logger( "PCSX2 > "); _immediate_logger( fmtline ); if( emuLog != NULL ) diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index dcb7654650..13691b0390 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -432,11 +432,8 @@ MainEmuFrame::~MainEmuFrame() throw() { try { - if( m_RecentIsoList != NULL ) - { + if( m_RecentIsoList ) m_RecentIsoList->Save( *wxConfigBase::Get( false ) ); - safe_delete( m_RecentIsoList ); - } } DESTRUCTOR_CATCHALL } @@ -450,10 +447,10 @@ void MainEmuFrame::ApplySettings() wxConfigBase* cfg = wxConfigBase::Get( false ); wxASSERT( cfg != NULL ); - if( m_RecentIsoList != NULL ) + if( m_RecentIsoList ) m_RecentIsoList->Save( *cfg ); - safe_delete( m_RecentIsoList ); - m_RecentIsoList = new wxFileHistory( g_Conf->RecentFileCount ); + m_RecentIsoList.reset(); + m_RecentIsoList.reset( new wxFileHistory( g_Conf->RecentFileCount ) ); m_RecentIsoList->Load( *cfg ); UpdateIsoSrcFile(); diff --git a/pcsx2/gui/MainFrame.h b/pcsx2/gui/MainFrame.h index de5e9b5874..f5b115634c 100644 --- a/pcsx2/gui/MainFrame.h +++ b/pcsx2/gui/MainFrame.h @@ -37,7 +37,7 @@ class MainEmuFrame : public wxFrame // ------------------------------------------------------------------------ protected: - wxFileHistory* m_RecentIsoList; + wxScopedPtr m_RecentIsoList; wxStatusBar& m_statusbar; wxStaticBitmap m_background; diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp index 6adfb1b205..de7e88c202 100644 --- a/pcsx2/gui/MainMenuClicks.cpp +++ b/pcsx2/gui/MainMenuClicks.cpp @@ -144,13 +144,15 @@ void MainEmuFrame::Menu_OpenELF_Click(wxCommandEvent &event) void MainEmuFrame::Menu_LoadStates_Click(wxCommandEvent &event) { int id = event.GetId() - MenuId_State_Load01 - 1; - Console::WriteLn("If this were hooked up, it would load slot %d.", id); + Console::WriteLn("Loading slot %d.", id); + States_Load(id); } void MainEmuFrame::Menu_SaveStates_Click(wxCommandEvent &event) { int id = event.GetId() - MenuId_State_Save01 - 1; - Console::WriteLn("If this were hooked up, it would save slot %d.", id); + Console::WriteLn("Saving to slot %d.", id); + States_Save(id); } void MainEmuFrame::Menu_LoadStateOther_Click(wxCommandEvent &event) diff --git a/pcsx2/gui/Panels/PluginSelectorPanel.cpp b/pcsx2/gui/Panels/PluginSelectorPanel.cpp index 53a733c4ae..9115e16dcc 100644 --- a/pcsx2/gui/Panels/PluginSelectorPanel.cpp +++ b/pcsx2/gui/Panels/PluginSelectorPanel.cpp @@ -1,6 +1,6 @@ /* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2009 PCSX2 Dev Team - * + * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -297,7 +297,7 @@ void Panels::PluginSelectorPanel::Apply() // ---------------------------------------------------------------------------- // Make sure folders are up to date, and try to load/reload plugins if needed... - + g_Conf->Folders.ApplyDefaults(); // Need to unload the current emulation state if the user changed plugins, because @@ -340,7 +340,7 @@ void Panels::PluginSelectorPanel::Apply() wxsFormat( L"The selected %s plugin failed to load.", plugname.c_str() ) + L"\n\n" + GetApplyFailedMsg() ); } - } + } } void Panels::PluginSelectorPanel::CancelRefresh() @@ -416,7 +416,7 @@ void Panels::PluginSelectorPanel::OnConfigure_Clicked( wxCommandEvent& evt ) wxDynamicLibrary dynlib( (*m_FileList)[(int)m_ComponentBoxes.Get(pid).GetClientData(sel)] ); if( PluginConfigureFnptr configfunc = (PluginConfigureFnptr)dynlib.GetSymbol( tbl_PluginInfo[pid].GetShortname() + L"configure" ) ) { - ScopedWindowDisable disabler( wxGetTopLevelParent( this ) ); + wxWindowDisabler disabler; configfunc(); } } diff --git a/pcsx2/gui/Panels/SpeedhacksPanel.cpp b/pcsx2/gui/Panels/SpeedhacksPanel.cpp index 22e8052651..3a4388a397 100644 --- a/pcsx2/gui/Panels/SpeedhacksPanel.cpp +++ b/pcsx2/gui/Panels/SpeedhacksPanel.cpp @@ -1,6 +1,6 @@ /* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2009 PCSX2 Dev Team - * + * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -47,7 +47,8 @@ const wxChar* Panels::SpeedHacksPanel::GetEEcycleSliderMsg( int val ) L"audio on many FMVs." ); - jNO_DEFAULT + default: + break; } return L"Unreachable Warning Suppressor!!"; @@ -78,8 +79,8 @@ const wxChar* Panels::SpeedHacksPanel::GetVUcycleSliderMsg( int val ) L"3 - Maximum VU Cycle Stealing. Usefulness is limited, as this will cause flickering " L"visuals or slowdown in most games." ); - - jNO_DEFAULT + default: + break; } return L"Unreachable Warning Suppressor!!"; @@ -172,7 +173,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow& parent, int idealWidth ) : L"Uses SSE's Min/Max Floating Point Operations instead of custom logical Min/Max routines. " L"Known to break Gran Tourismo 4, Tekken 5." ) ); - + m_check_vuMinMax->SetValue(opts.vuMinMax); // ------------------------------------------------------------------------ diff --git a/pcsx2/gui/Plugins.cpp b/pcsx2/gui/Plugins.cpp index db13783456..aa76a67351 100644 --- a/pcsx2/gui/Plugins.cpp +++ b/pcsx2/gui/Plugins.cpp @@ -25,6 +25,90 @@ #include "HostGui.h" #include "AppConfig.h" +using namespace Threading; + +// -------------------------------------------------------------------------------------- +// LoadPluginsTask +// -------------------------------------------------------------------------------------- +// On completion the thread sends a pxEVT_LoadPluginsComplete message, which contains a +// handle to this thread object. If the load is successful, the Result var is set to +// non-NULL. If NULL, an error occurred and the thread loads the exception into either +// Ex_PluginError or Ex_RuntimeError. +// +class LoadPluginsTask : public Threading::PersistentThread +{ +public: + Exception::PluginError* Ex_PluginError; + Exception::RuntimeError* Ex_RuntimeError; + PluginManager* Result; + +protected: + wxString m_folders[PluginId_Count]; + +public: + LoadPluginsTask( const wxString (&folders)[PluginId_Count] ) : + Ex_PluginError( NULL ) + , Ex_RuntimeError( NULL ) + , Result( NULL ) + { + for(int i=0; i _loadTask; + +LoadPluginsTask::~LoadPluginsTask() throw() +{ + _loadTask.release(); + PersistentThread::Cancel(); + _loadTask.reset(); +} + +int LoadPluginsTask::ExecuteTask() +{ + wxGetApp().Ping(); + Sleep(3); + + wxCommandEvent evt( pxEVT_LoadPluginsComplete ); + evt.SetClientData( this ); + + try + { + // This is for testing of the error handler... uncomment for fun? + //throw Exception::PluginError( PluginId_PAD, "This one is for testing the error handler!" ); + + Result = PluginManager_Create( m_folders ); + } + catch( Exception::PluginError& ex ) + { + Ex_PluginError = new Exception::PluginError( ex ); + } + catch( Exception::RuntimeError& innerEx ) + { + // Runtime errors are typically recoverable, so handle them here + // and prep them for re-throw on the main thread. + Ex_RuntimeError = new Exception::RuntimeError( + L"A runtime error occurred on the LoadPlugins thread.\n" + innerEx.FormatDiagnosticMessage(), + innerEx.FormatDisplayMessage() + ); + } + // anything else leave unhandled so that the debugger catches it! + + wxGetApp().AddPendingEvent( evt ); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + + int EnumeratePluginsInFolder( const wxDirName& searchpath, wxArrayString* dest ) { wxScopedPtr placebo; @@ -45,69 +129,29 @@ int EnumeratePluginsInFolder( const wxDirName& searchpath, wxArrayString* dest ) wxDir::GetAllFiles( searchpath.ToString(), realdest, wxsFormat( pattern, wxDynamicLibrary::GetDllExt()), wxDIR_FILES ) : 0; } -using namespace Threading; - void Pcsx2App::OnReloadPlugins( wxCommandEvent& evt ) { ReloadPlugins(); } +void Pcsx2App::OnLoadPluginsComplete( wxCommandEvent& evt ) +{ + // scoped ptr ensures the thread object is cleaned up even on exception: + wxScopedPtr killTask( (LoadPluginsTask*)evt.GetClientData() ); + m_CorePlugins.reset( killTask->Result ); + + if( !m_CorePlugins ) + { + if( killTask->Ex_PluginError != NULL ) + throw *killTask->Ex_PluginError; + if( killTask->Ex_RuntimeError != NULL ) + throw *killTask->Ex_RuntimeError; // Re-Throws generic threaded errors + } +} + void Pcsx2App::ReloadPlugins() { - class LoadPluginsTask : public Threading::BaseTaskThread - { - public: - PluginManager* Result; - Exception::PluginError* Ex_PluginError; - Exception::RuntimeError* Ex_RuntimeError; - - protected: - const wxString (&m_folders)[PluginId_Count]; - - public: - LoadPluginsTask( const wxString (&folders)[PluginId_Count] ) : - Result( NULL ) - , Ex_PluginError( NULL ) - , Ex_RuntimeError( NULL ) - , m_folders( folders ) - { - } - - virtual ~LoadPluginsTask() throw() - { - BaseTaskThread::Cancel(); - } - - protected: - void Task() - { - wxGetApp().Ping(); - Sleep(3); - - try - { - //throw Exception::PluginError( PluginId_PAD, "This one is for testing the error handler!" ); - Result = PluginManager_Create( m_folders ); - } - catch( Exception::PluginError& ex ) - { - Result = NULL; - Ex_PluginError = new Exception::PluginError( ex ); - } - catch( Exception::RuntimeError& innerEx ) - { - // Runtime errors are typically recoverable, so handle them here - // and prep them for re-throw on the main thread. - Result = NULL; - Ex_RuntimeError = new Exception::RuntimeError( - L"A runtime error occurred on the LoadPlugins thread.\n" + innerEx.FormatDiagnosticMessage(), - innerEx.FormatDisplayMessage() - ); - } - - // anything else leave unhandled so that the debugger catches it! - } - }; + if( _loadTask ) return; m_CoreThread.reset(); m_CorePlugins.reset(); @@ -123,41 +167,39 @@ void Pcsx2App::ReloadPlugins() passins[pi->id] = g_Conf->FullpathTo( pi->id ); } - LoadPluginsTask task( passins ); - task.Start(); - task.PostTask(); - task.WaitForResult(); - - if( task.Result == NULL ) - { - if( task.Ex_PluginError != NULL ) - throw *task.Ex_PluginError; - if( task.Ex_RuntimeError != NULL ) - throw *task.Ex_RuntimeError; // Re-Throws generic threaded errors - } - - m_CorePlugins.reset( task.Result ); + _loadTask.reset( new LoadPluginsTask( passins ) ); + // ... and when it finishes it posts up a OnLoadPluginsComplete(). Bye. :) } // Posts a message to the App to reload plugins. Plugins are loaded via a background thread // which is started on a pending event, so don't expect them to be ready "right now." +// If plugins are already loaded then no action is performed. void LoadPluginsPassive() { + if( g_plugins ) return; + wxCommandEvent evt( pxEVT_ReloadPlugins ); wxGetApp().AddPendingEvent( evt ); } // Blocks until plugins have been successfully loaded, or throws an exception if -// the user cancels the loading procedure after error. +// the user cancels the loading procedure after error. If plugins are already loaded +// then no action is performed. void LoadPluginsImmediate() { wxASSERT( wxThread::IsMain() ); + if( g_plugins ) return; static int _reentrant = 0; EntryGuard guard( _reentrant ); wxASSERT( !guard.IsReentrant() ); wxGetApp().ReloadPlugins(); + while( _loadTask ) + { + Sleep( 10 ); + wxGetApp().ProcessPendingEvents(); + } } void UnloadPlugins()