From 0c1c5e39af3b1682f0823975dd9357e8c026002c Mon Sep 17 00:00:00 2001
From: zilmar <zilmar@pj64-emu.com>
Date: Tue, 18 Apr 2017 21:32:43 +1000
Subject: [PATCH] [Plugins] Give access to notify class

---
 Source/Glide64/Main.cpp                       |  26 +-
 Source/Glide64/rdp.cpp                        |  53 ++--
 Source/Glitch64/OGLESglitchmain.cpp           | 186 ++++++-------
 Source/Glitch64/OGLglitchmain.cpp             | 254 ++++++++----------
 Source/Project64-core/Plugins/PluginBase.cpp  |  40 ++-
 Source/Project64-core/Plugins/PluginBase.h    |   8 +
 Source/Project64-core/Plugins/PluginClass.cpp |   1 -
 Source/Project64-core/Plugins/PluginClass.h   |   9 +
 Source/Settings/Settings.cpp                  |  59 ++++
 Source/Settings/Settings.h                    |  12 +
 10 files changed, 355 insertions(+), 293 deletions(-)

diff --git a/Source/Glide64/Main.cpp b/Source/Glide64/Main.cpp
index 18332c0d5..e692b8da8 100644
--- a/Source/Glide64/Main.cpp
+++ b/Source/Glide64/Main.cpp
@@ -47,6 +47,7 @@
 #include <png/png.h>
 #include <memory>
 #include <Common/SmartPointer.h>
+#include <Settings/Settings.h>
 
 #include "Config.h"
 #include "Util.h"
@@ -84,7 +85,6 @@ int ev_fullscreen = 0;
 extern int g_viewport_offset;
 extern int g_width, g_height;
 
-
 #ifdef _WIN32
 HINSTANCE hinstDLL = NULL;
 #endif
@@ -505,7 +505,7 @@ int InitGfx()
     voodoo.has_2mb_tex_boundary = (SST_type < GR_SSTTYPE_Banshee) && !evoodoo;
     // use UMA if available
     voodoo.tex_UMA = FALSE;
-    if (strstr(extensions, " TEXUMA ")) 
+    if (strstr(extensions, " TEXUMA "))
     {
         // we get better texture cache hits with UMA on
         grEnable(GR_TEXTURE_UMA_EXT);
@@ -520,11 +520,7 @@ int InitGfx()
     gfx_context = grSstWinOpen(GR_COLORFORMAT_RGBA, GR_ORIGIN_UPPER_LEFT, 2, 1);
     if (!gfx_context)
     {
-#ifdef _WIN32
-        MessageBox(gfx.hWnd, "Error setting display mode", "Error", MB_OK | MB_ICONEXCLAMATION);
-#else
-        fprintf(stderr, "Error setting display mode\n");
-#endif
+        g_Notify->DisplayError("Error setting display mode");
         grGlideShutdown();
         return FALSE;
     }
@@ -710,7 +706,7 @@ int InitGfx()
         voodoo.sup_mirroring = 1;
     }
     return TRUE;
-}
+    }
 
 void ReleaseGfx()
 {
@@ -1074,7 +1070,7 @@ void CALL RomClosed(void)
     if (evoodoo)
     {
         ReleaseGfx();
-    }
+}
 }
 
 static void CheckDRAMSize()
@@ -1084,14 +1080,14 @@ static void CheckDRAMSize()
     {
         test = gfx.RDRAM[0x007FFFFF] + 1;
     }
-    GLIDE64_CATCH
+        GLIDE64_CATCH
     {
         test = 0;
     }
-    if (test)
-        BMASK = 0x7FFFFF;
-    else
-        BMASK = WMASK;
+        if (test)
+            BMASK = 0x7FFFFF;
+        else
+            BMASK = WMASK;
 #ifdef LOGGING
     sprintf(out_buf, "Detected RDRAM size: %08lx", BMASK);
     LOG(out_buf);
@@ -1610,4 +1606,4 @@ void Android_JNI_SwapWindow()
 {
     gfx.SwapBuffers();
 }
-#endif
+#endif
\ No newline at end of file
diff --git a/Source/Glide64/rdp.cpp b/Source/Glide64/rdp.cpp
index b4457d2d3..d9264cdea 100644
--- a/Source/Glide64/rdp.cpp
+++ b/Source/Glide64/rdp.cpp
@@ -52,6 +52,7 @@
 #include <Common/StdString.h>
 #include "trace.h"
 #include "SettingsID.h"
+#include <Settings/Settings.h>
 
 #ifdef _WIN32
 #include <Common/CriticalSection.h>
@@ -305,12 +306,12 @@ void microcheck()
 
 #ifdef LOG_UCODE
     std::ofstream ucf;
-    ucf.open ("ucode.txt", std::ios::out | std::ios::binary);
+    ucf.open("ucode.txt", std::ios::out | std::ios::binary);
     char d;
-    for (i=0; i<0x400000; i++)
+    for (i = 0; i < 0x400000; i++)
     {
-        d = ((char*)gfx.RDRAM)[i^3];
-        ucf.write (&d, 1);
+        d = ((char*)gfx.RDRAM)[i ^ 3];
+        ucf.write(&d, 1);
     }
     ucf.close();
 #endif
@@ -324,9 +325,7 @@ void microcheck()
         {
             ReleaseGfx();
             WriteTrace(TraceGlide64, TraceError, "uCode crc not found in INI, using currently selected uCode %08lx", (unsigned long)uc_crc);
-#ifdef _WIN32
-            MessageBox(gfx.hWnd, stdstr_f("Error: uCode crc not found in INI, using currently selected uCode\n\n%08lx", uc_crc).c_str(), "Error", MB_OK | MB_ICONEXCLAMATION);
-#endif
+            g_Notify->DisplayError(stdstr_f("Error: uCode crc not found in INI, using currently selected uCode\n\n%08lx", uc_crc).c_str());
             g_ucode_error_report = false; // don't report any more ucode errors from this game
         }
     }
@@ -336,9 +335,7 @@ void microcheck()
         {
             ReleaseGfx();
             WriteTrace(TraceGlide64, TraceError, "Unsupported uCode! crc: %08lx", (unsigned long)uc_crc);
-#ifdef _WIN32
-            MessageBox(gfx.hWnd, stdstr_f("Error: Unsupported uCode!\n\ncrc: %08lx", uc_crc).c_str(), "Error", MB_OK | MB_ICONEXCLAMATION);
-#endif
+            g_Notify->DisplayError(stdstr_f("Error: Unsupported uCode!\n\ncrc: %08lx", uc_crc).c_str());
             g_ucode_error_report = FALSE; // don't report any more ucode errors from this game
         }
     }
@@ -688,7 +685,7 @@ EXPORT void CALL ProcessDList(void)
         else
         {
             // MAIN PROCESSING LOOP
-            do 
+            do
             {
                 // Get the address of the next command
                 a = rdp.pc[rdp.pc_i] & BMASK;
@@ -735,7 +732,7 @@ EXPORT void CALL ProcessDList(void)
     catch (...) {
         if (g_fullscreen)
         {
-            ReleaseGfx ();
+            ReleaseGfx();
             rdp_reset();
             if (g_ghq_use)
             {
@@ -743,14 +740,8 @@ EXPORT void CALL ProcessDList(void)
                 g_ghq_use = false;
             }
         }
-        if (MessageBox(gfx.hWnd, "The GFX plugin caused an exception and has been disabled.\nWould you like to turn it back on and attempt to continue?","Glide64 Exception", MB_YESNO|MB_ICONEXCLAMATION) == MB_NO)
-        {
-            exception = TRUE;
-        }
-        else
-        {
-            to_fullscreen = TRUE;
-        }
+        DisplayError("The GFX plugin caused an exception and has been disabled");
+        to_fullscreen = TRUE;
         return;
     }
 #endif
@@ -759,7 +750,7 @@ EXPORT void CALL ProcessDList(void)
     {
         rdp.scale_x = rdp.scale_x_bak;
         rdp.scale_y = rdp.scale_y_bak;
-    }
+}
 
     if (g_settings->hacks(CSettings::hack_OoT))
     {
@@ -781,7 +772,7 @@ EXPORT void CALL ProcessDList(void)
         CI_SET = FALSE;
     }
     WriteTrace(TraceRDP, TraceDebug, "ProcessDList end");
-}
+    }
 
 // undef - undefined instruction, always ignore
 static void undef()
@@ -909,11 +900,11 @@ static void rdp_texrect()
         else
         {
             //gDPTextureRectangle
-			if (g_settings->hacks(CSettings::hack_Winback))
+            if (g_settings->hacks(CSettings::hack_Winback))
             {
-				rdp.pc[rdp.pc_i] += 8;
-				return;
-			}
+                rdp.pc[rdp.pc_i] += 8;
+                return;
+            }
 
             if (g_settings->hacks(CSettings::hack_ASB))
             {
@@ -924,7 +915,7 @@ static void rdp_texrect()
                 rdp.cmd2 = ((uint32_t*)gfx.RDRAM)[a + 0];
             }
 
-			rdp.cmd3 = ((uint32_t*)gfx.RDRAM)[a + 1];
+            rdp.cmd3 = ((uint32_t*)gfx.RDRAM)[a + 1];
             rdp.pc[rdp.pc_i] += 8;
         }
     }
@@ -934,7 +925,7 @@ static void rdp_texrect()
         return;
     }
 
-	if (rdp.skip_drawing || (!g_settings->fb_emulation_enabled() && (rdp.cimg == rdp.zimg)))
+    if (rdp.skip_drawing || (!g_settings->fb_emulation_enabled() && (rdp.cimg == rdp.zimg)))
     {
         if (g_settings->hacks(CSettings::hack_PMario) && rdp.ci_status == ci_useless)
         {
@@ -1988,7 +1979,7 @@ static inline void loadTile(uint32_t *src, uint32_t *dst, int width, int height,
             do
             {
                 v16 = __ROL__(v16, 8);
-                *(uint8_t *)v7 = (v16  & 0xFF);
+                *(uint8_t *)v7 = (v16 & 0xFF);
                 v7 = (uint32_t *)((char *)v7 + 1);
                 --v15;
             } while (v15);
@@ -2969,7 +2960,7 @@ void SetWireframeCol()
 {
     switch (g_settings->wfmode())
     {
-    //case CSettings::wfmode_NormalColors: // normal colors, don't do anything
+        //case CSettings::wfmode_NormalColors: // normal colors, don't do anything
     case CSettings::wfmode_VertexColors:
         grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
             GR_COMBINE_FACTOR_NONE,
@@ -4134,7 +4125,7 @@ void CALL ProcessRDPList(void)
         rdp_cmd_cur = (rdp_cmd_cur + rdp_command_length[cmd] / 4) & maxCMDMask;
     }
 
-    if (setZero) 
+    if (setZero)
     {
         rdp_cmd_ptr = 0;
         rdp_cmd_cur = 0;
diff --git a/Source/Glitch64/OGLESglitchmain.cpp b/Source/Glitch64/OGLESglitchmain.cpp
index 15c1e7a3f..103b209a6 100644
--- a/Source/Glitch64/OGLESglitchmain.cpp
+++ b/Source/Glitch64/OGLESglitchmain.cpp
@@ -216,34 +216,6 @@ void display_warning(const char *text, ...)
     }
 }
 
-#ifdef _WIN32
-void display_error()
-{
-    LPVOID lpMsgBuf;
-    if (!FormatMessage(
-        FORMAT_MESSAGE_ALLOCATE_BUFFER |
-        FORMAT_MESSAGE_FROM_SYSTEM |
-        FORMAT_MESSAGE_IGNORE_INSERTS,
-        NULL,
-        GetLastError(),
-        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-        (LPTSTR)&lpMsgBuf,
-        0,
-        NULL))
-    {
-        // Handle the error.
-        return;
-    }
-    // Process any inserts in lpMsgBuf.
-    // ...
-    // Display the string.
-    MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
-
-    // Free the buffer.
-    LocalFree(lpMsgBuf);
-}
-#endif // _WIN32
-
 FX_ENTRY void FX_CALL
 grSstOrigin(GrOriginLocation_t  origin)
 {
@@ -380,7 +352,7 @@ FX_ENTRY GrContext_t FX_CALL grSstWinOpenExt(GrColorFormat_t color_format, GrOri
 # endif
 #endif
 
-FX_ENTRY GrContext_t FX_CALL grSstWinOpen( GrColorFormat_t color_format, GrOriginLocation_t origin_location, int nColBuffers, int nAuxBuffers)
+FX_ENTRY GrContext_t FX_CALL grSstWinOpen(GrColorFormat_t color_format, GrOriginLocation_t origin_location, int nColBuffers, int nAuxBuffers)
 {
     static int show_warning = 1;
 
@@ -988,12 +960,12 @@ int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info
 
 FX_ENTRY void FX_CALL
 grTextureAuxBufferExt(GrChipID_t tmu,
-FxU32      startAddress,
-GrLOD_t    thisLOD,
-GrLOD_t    largeLOD,
-GrAspectRatio_t aspectRatio,
-GrTextureFormat_t format,
-FxU32      odd_even_mask)
+    FxU32      startAddress,
+    GrLOD_t    thisLOD,
+    GrLOD_t    largeLOD,
+    GrAspectRatio_t aspectRatio,
+    GrTextureFormat_t format,
+    FxU32      odd_even_mask)
 {
     WriteTrace(TraceGlitch, TraceDebug, "tmu: %d startAddress: %d thisLOD: %d largeLOD: %d aspectRatio: %d format: %d odd_even_mask: %d", tmu, startAddress, thisLOD, largeLOD, aspectRatio, format, odd_even_mask);
     //WriteTrace(TraceGlitch, TraceWarning, "grTextureAuxBufferExt");
@@ -1477,32 +1449,32 @@ grRenderBuffer(GrBuffer_t buffer)
             savedHeighto = heighto;
         }
 
-    {
-        if (!use_fbo) {
-            //glMatrixMode(GL_MODELVIEW);
-            //glLoadIdentity();
-            //glTranslatef(0, 0, 1-zscale);
-            //glScalef(1, 1, zscale);
-            inverted_culling = 0;
+        {
+            if (!use_fbo) {
+                //glMatrixMode(GL_MODELVIEW);
+                //glLoadIdentity();
+                //glTranslatef(0, 0, 1-zscale);
+                //glScalef(1, 1, zscale);
+                inverted_culling = 0;
+            }
+            else {
+                /*
+                        float m[4*4] = {1.0f, 0.0f, 0.0f, 0.0f,
+                        0.0f,-1.0f, 0.0f, 0.0f,
+                        0.0f, 0.0f, 1.0f, 0.0f,
+                        0.0f, 0.0f, 0.0f, 1.0f};
+                        glMatrixMode(GL_MODELVIEW);
+                        glLoadMatrixf(m);
+                        // VP z fix
+                        glTranslatef(0, 0, 1-zscale);
+                        glScalef(1, 1*1, zscale);
+                        */
+                inverted_culling = 1;
+                grCullMode(culling_mode);
+            }
         }
-        else {
-            /*
-                    float m[4*4] = {1.0f, 0.0f, 0.0f, 0.0f,
-                    0.0f,-1.0f, 0.0f, 0.0f,
-                    0.0f, 0.0f, 1.0f, 0.0f,
-                    0.0f, 0.0f, 0.0f, 1.0f};
-                    glMatrixMode(GL_MODELVIEW);
-                    glLoadMatrixf(m);
-                    // VP z fix
-                    glTranslatef(0, 0, 1-zscale);
-                    glScalef(1, 1*1, zscale);
-                    */
-            inverted_culling = 1;
-            grCullMode(culling_mode);
-        }
-    }
-    render_to_texture = 1;
-    break;
+        render_to_texture = 1;
+        break;
     default:
         WriteTrace(TraceGlitch, TraceWarning, "grRenderBuffer : unknown buffer : %x", buffer);
     }
@@ -1623,14 +1595,14 @@ grBufferSwap(FxU32 swap_interval)
         }
     }
 #endif
-}
+        }
 
 // frame buffer
 
 FX_ENTRY FxBool FX_CALL
 grLfbLock(GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode,
-GrOriginLocation_t origin, FxBool pixelPipeline,
-GrLfbInfo_t *info)
+    GrOriginLocation_t origin, FxBool pixelPipeline,
+    GrLfbInfo_t *info)
 {
     WriteTrace(TraceGlitch, TraceDebug, "type: %d buffer: %d writeMode: %d origin: %d pixelPipeline: %d", type, buffer, writeMode, origin, pixelPipeline);
     if (type == GR_LFB_WRITE_ONLY)
@@ -1652,7 +1624,7 @@ GrLfbInfo_t *info)
             break;
         default:
             WriteTrace(TraceGlitch, TraceWarning, "grLfbLock : unknown buffer : %x", buffer);
-        }
+    }
 
         if (buffer != GR_BUFFER_AUXBUFFER)
         {
@@ -1694,7 +1666,7 @@ GrLfbInfo_t *info)
             info->origin = origin;
             glReadPixels(0, g_viewport_offset, g_width, g_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
         }
-    }
+}
 
     return FXTRUE;
 }
@@ -1712,9 +1684,9 @@ grLfbUnlock(GrLock_t type, GrBuffer_t buffer)
 
 FX_ENTRY FxBool FX_CALL
 grLfbReadRegion(GrBuffer_t src_buffer,
-FxU32 src_x, FxU32 src_y,
-FxU32 src_width, FxU32 src_height,
-FxU32 dst_stride, void *dst_data)
+    FxU32 src_x, FxU32 src_y,
+    FxU32 src_width, FxU32 src_height,
+    FxU32 dst_stride, void *dst_data)
 {
     unsigned char *buf;
     unsigned int i, j;
@@ -1777,11 +1749,11 @@ FxU32 dst_stride, void *dst_data)
 
 FX_ENTRY FxBool FX_CALL
 grLfbWriteRegion(GrBuffer_t dst_buffer,
-FxU32 dst_x, FxU32 dst_y,
-GrLfbSrcFmt_t src_format,
-FxU32 src_width, FxU32 src_height,
-FxBool pixelPipeline,
-FxI32 src_stride, void *src_data)
+    FxU32 dst_x, FxU32 dst_y,
+    GrLfbSrcFmt_t src_format,
+    FxU32 src_width, FxU32 src_height,
+    FxBool pixelPipeline,
+    FxI32 src_stride, void *src_data)
 {
     unsigned char *buf;
     unsigned int i, j;
@@ -1886,7 +1858,7 @@ FxI32 src_stride, void *src_data)
     }
     else
     {
-        float *buf = (float*)malloc(src_width*(src_height + (g_viewport_offset))*sizeof(float));
+        float *buf = (float*)malloc(src_width*(src_height + (g_viewport_offset)) * sizeof(float));
 
         if (src_format != GR_LFBWRITEMODE_ZA16)
             WriteTrace(TraceGlitch, TraceWarning, "unknown depth buffer write format:%x", src_format);
@@ -1901,7 +1873,7 @@ FxI32 src_stride, void *src_data)
                 buf[(j + (g_viewport_offset))*src_width + i] =
                     (frameBuffer[(src_height - j - 1)*(src_stride / 2) + i] / (65536.0f*(2.0f / zscale))) + 1 - zscale / 2.0f;
             }
-        }
+    }
 
 #ifdef VPDEBUG
         if (dumping) {
@@ -1927,7 +1899,7 @@ FxI32 src_stride, void *src_data)
         //glDrawPixels(src_width, src_height+(g_viewport_offset), GL_DEPTH_COMPONENT, GL_FLOAT, buf);
 
         free(buf);
-    }
+}
     //glDrawBuffer(current_buffer);
     //glPopAttrib();
     return FXTRUE;
@@ -2035,46 +2007,46 @@ grFlush(void)
 
 FX_ENTRY void FX_CALL
 grTexMultibase(GrChipID_t tmu,
-FxBool     enable)
+    FxBool     enable)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexMultibase");
 }
 
 FX_ENTRY void FX_CALL
 grTexMipMapMode(GrChipID_t     tmu,
-GrMipMapMode_t mode,
-FxBool         lodBlend)
+    GrMipMapMode_t mode,
+    FxBool         lodBlend)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexMipMapMode");
 }
 
 FX_ENTRY void FX_CALL
 grTexDownloadTablePartial(GrTexTable_t type,
-void         *data,
-int          start,
-int          end)
+    void         *data,
+    int          start,
+    int          end)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexDownloadTablePartial");
 }
 
 FX_ENTRY void FX_CALL
 grTexDownloadTable(GrTexTable_t type,
-void         *data)
+    void         *data)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexDownloadTable");
 }
 
 FX_ENTRY FxBool FX_CALL
 grTexDownloadMipMapLevelPartial(GrChipID_t        tmu,
-FxU32             startAddress,
-GrLOD_t           thisLod,
-GrLOD_t           largeLod,
-GrAspectRatio_t   aspectRatio,
-GrTextureFormat_t format,
-FxU32             evenOdd,
-void              *data,
-int               start,
-int               end)
+    FxU32             startAddress,
+    GrLOD_t           thisLod,
+    GrLOD_t           largeLod,
+    GrAspectRatio_t   aspectRatio,
+    GrTextureFormat_t format,
+    FxU32             evenOdd,
+    void              *data,
+    int               start,
+    int               end)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexDownloadMipMapLevelPartial");
     return 1;
@@ -2082,13 +2054,13 @@ int               end)
 
 FX_ENTRY void FX_CALL
 grTexDownloadMipMapLevel(GrChipID_t        tmu,
-FxU32             startAddress,
-GrLOD_t           thisLod,
-GrLOD_t           largeLod,
-GrAspectRatio_t   aspectRatio,
-GrTextureFormat_t format,
-FxU32             evenOdd,
-void              *data)
+    FxU32             startAddress,
+    GrLOD_t           thisLod,
+    GrLOD_t           largeLod,
+    GrAspectRatio_t   aspectRatio,
+    GrTextureFormat_t format,
+    FxU32             evenOdd,
+    void              *data)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexDownloadMipMapLevel");
 }
@@ -2126,8 +2098,8 @@ grSelectContext(GrContext_t context)
 
 FX_ENTRY void FX_CALL
 grAADrawTriangle(
-const void *a, const void *b, const void *c,
-FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias
+    const void *a, const void *b, const void *c,
+    FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias
 )
 {
     WriteTrace(TraceGlitch, TraceWarning, "grAADrawTriangle");
@@ -2189,10 +2161,10 @@ grLfbConstantAlpha(GrAlpha_t alpha)
 
 FX_ENTRY void FX_CALL
 grTexMultibaseAddress(GrChipID_t       tmu,
-GrTexBaseRange_t range,
-FxU32            startAddress,
-FxU32            evenOdd,
-GrTexInfo        *info)
+    GrTexBaseRange_t range,
+    FxU32            startAddress,
+    FxU32            evenOdd,
+    GrTexInfo        *info)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexMultibaseAddress");
 }
@@ -2384,7 +2356,7 @@ void CHECK_FRAMEBUFFER_STATUS(void)
     GLenum status;
     status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
     WriteTrace(TraceGlitch, TraceDebug, "status: %X", status);
-    switch(status) {
+    switch (status) {
     case GL_FRAMEBUFFER_COMPLETE:
         /*WriteTrace(TraceGlitch, TraceWarning, "framebuffer complete!\n");*/
         break;
@@ -2406,5 +2378,5 @@ void CHECK_FRAMEBUFFER_STATUS(void)
         break;
         /* programming error; will fail on all hardware */
         /*assert(0);*/
-    }
 }
+}
\ No newline at end of file
diff --git a/Source/Glitch64/OGLglitchmain.cpp b/Source/Glitch64/OGLglitchmain.cpp
index 283de0c84..cf972f4f7 100644
--- a/Source/Glitch64/OGLglitchmain.cpp
+++ b/Source/Glitch64/OGLglitchmain.cpp
@@ -24,7 +24,7 @@
 
 /*
  * `GetSystemSetting` and `FindSystemSettingId` from Project64 debugger
- * used only in DisplayError when OpenGL extension loading fails on WGL
+ * used only in g_Notify->DisplayError when OpenGL extension loading fails on WGL
  */
 #include <Settings/Settings.h>
 
@@ -78,39 +78,31 @@ static inline void opt_glCopyTexImage2D(GLenum target,
  * displaying error information showing the missing OpenGL support.
  */
 
-void DisplayError(const char * message)
-{
-    if (GetSystemSetting(FindSystemSettingId("Debugger")) == 0)
-        return;
-    MessageBoxA(NULL, message, NULL, MB_ICONERROR);
-    return;
-}
-
 PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
 PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
 PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
 PFNGLFOGCOORDFPROC glFogCoordfEXT;
 void APIENTRY dummy_glActiveTexture(GLenum/*texture*/)
 { /* GLX render opcode 197, req. OpenGL 1.3 (1.2 w/ ARB_multitexture) */
-    DisplayError("glActiveTexture");
+    g_Notify->DisplayError("glActiveTexture");
 }
 void APIENTRY dummy_glMultiTexCoord2f(GLenum/*target*/, GLfloat/*s*/, GLfloat/*t*/)
 { /* GLX render opcode 203, req. OpenGL 1.3 (1.2 w/ ARB_multitexture) */
-    DisplayError("glMultiTexCoord2f");
+    g_Notify->DisplayError("glMultiTexCoord2f");
 }
 void APIENTRY dummy_glFogCoordf(GLfloat/*coord*/)
 { /* GLX render opcode 4124, req. OpenGL 1.4 (1.1 w/ EXT_fog_coord) */
-    DisplayError("glFogCoordf");
+    g_Notify->DisplayError("glFogCoordf");
 }
 void APIENTRY dummy_glBlendFuncSeparate(GLenum, GLenum, GLenum, GLenum)
 { /* GLX render opcode 4134, req. OpenGL 1.0 w/ EXT_blend_func_separate */
-    DisplayError("glBlendFuncSeparate");
+    g_Notify->DisplayError("glBlendFuncSeparate");
 }
 
 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
 const char * APIENTRY dummy_wglGetExtensionsString(HDC)
 {
-    DisplayError("wglGetExtensionsString");
+    g_Notify->DisplayError("wglGetExtensionsString");
     return NULL;
 }
 
@@ -126,44 +118,44 @@ PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
 PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
 void APIENTRY dummy_glGenRenderbuffers(GLsizei/*n*/, GLuint* /*renderbuffers*/)
 { /* GLX vendor opcode 1423, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glGenRenderbuffers");
+    g_Notify->DisplayError("glGenRenderbuffers");
 }
 void APIENTRY dummy_glGenFramebuffers(GLsizei/*n*/, GLuint* /*framebuffers*/)
 { /* GLX vendor opcode 1426, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glGenFramebuffers");
+    g_Notify->DisplayError("glGenFramebuffers");
 }
 GLenum APIENTRY dummy_glCheckFramebufferStatus(GLenum/*target*/)
 { /* GLX vendor opcode 1427, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glCheckFramebufferStatus");
+    g_Notify->DisplayError("glCheckFramebufferStatus");
     return 0x00008CDD; /* GL_FRAMEBUFFER_UNSUPPORTED */
 }
 void APIENTRY dummy_glBindRenderbuffer(GLenum/*target*/, GLuint/*renderbuffer*/)
 { /* GLX render opcode 4316, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glBindRenderbuffer");
+    g_Notify->DisplayError("glBindRenderbuffer");
 }
 void APIENTRY dummy_glDeleteRenderbuffers(GLsizei/*n*/, const GLuint* /*renderbuffers*/)
 { /* GLX render opcode 4317, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glDeleteRenderbuffers");
+    g_Notify->DisplayError("glDeleteRenderbuffers");
 }
 void APIENTRY dummy_glRenderbufferStorage(GLenum, GLenum, GLsizei, GLsizei)
 { /* GLX render opcode 4318, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glRenderbufferStorage");
+    g_Notify->DisplayError("glRenderbufferStorage");
 }
 void APIENTRY dummy_glBindFramebuffer(GLenum/*target*/, GLuint/*framebuffer*/)
 { /* GLX render opcode 4319, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glBindFramebuffer");
+    g_Notify->DisplayError("glBindFramebuffer");
 }
 void APIENTRY dummy_glDeleteFramebuffers(GLsizei/*n*/, const GLuint* /*framebuffers*/)
 { /* GLX render opcode 4320, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glDeleteFramebuffers");
+    g_Notify->DisplayError("glDeleteFramebuffers");
 }
 void APIENTRY dummy_glFramebufferTexture2D(GLenum, GLenum, GLenum, GLuint, GLint)
 { /* GLX render opcode 4322, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glFramebufferTexture2D");
+    g_Notify->DisplayError("glFramebufferTexture2D");
 }
 void APIENTRY dummy_glFramebufferRenderbuffer(GLenum, GLenum, GLenum, GLuint)
 { /* GLX render opcode 4324, req. OpenGL 1.2 w/ EXT_framebuffer_object */
-    DisplayError("glFramebufferRenderbuffer");
+    g_Notify->DisplayError("glFramebufferRenderbuffer");
 }
 
 PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
@@ -184,70 +176,70 @@ PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
 PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f;
 void APIENTRY dummy_glSecondaryColor3f(GLfloat/*red*/, GLfloat/*green*/, GLfloat/*blue*/)
 { /* GLX render opcode 4129, req. OpenGL 1.4 (1.1 w/ EXT_secondary_color) */
-    DisplayError("glSecondaryColor3f");
+    g_Notify->DisplayError("glSecondaryColor3f");
 }
 GLuint APIENTRY dummy_glCreateShader(GLenum/*type*/)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glCreateShader");
+    g_Notify->DisplayError("glCreateShader");
     return ((GLuint)(NULL));
 }
 void APIENTRY dummy_glShaderSource(GLuint, GLsizei, const GLchar **, GLint *)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glShaderSource");
+    g_Notify->DisplayError("glShaderSource");
 }
 void APIENTRY dummy_glCompileShader(GLuint/*shader*/)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glCompileShader");
+    g_Notify->DisplayError("glCompileShader");
 }
 GLuint APIENTRY dummy_glCreateProgram(void)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glCreateProgram");
+    g_Notify->DisplayError("glCreateProgram");
     return ((GLuint)(NULL));
 }
 void APIENTRY dummy_glAttachObject(GLhandleARB, GLhandleARB)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glAttachObject");
+    g_Notify->DisplayError("glAttachObject");
 }
 void APIENTRY dummy_glLinkProgram(GLuint/*program*/)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glLinkProgram");
+    g_Notify->DisplayError("glLinkProgram");
 }
 void APIENTRY dummy_glUseProgram(GLuint/*program*/)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glUseProgram");
+    g_Notify->DisplayError("glUseProgram");
 }
 GLint APIENTRY dummy_glGetUniformLocation(GLuint/*program*/, GLchar* /*name*/)
 { /* GLX single opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glGetUniformLocation");
+    g_Notify->DisplayError("glGetUniformLocation");
     return -1;
 }
 void APIENTRY dummy_glUniform1i(GLint/*location*/, GLint/*v0*/)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glUniform1i");
+    g_Notify->DisplayError("glUniform1i");
 }
 void APIENTRY dummy_glUniform4i(GLint/*location*/, GLint, GLint, GLint, GLint)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glUniform4i");
+    g_Notify->DisplayError("glUniform4i");
 }
 void APIENTRY dummy_glUniform1f(GLint/*location*/, GLfloat/*v0*/)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glUniform1f");
+    g_Notify->DisplayError("glUniform1f");
 }
 void APIENTRY dummy_glUniform4f(GLint/*location*/, GLfloat, GLfloat, GLfloat, GLfloat)
 { /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
-    DisplayError("glUniform4f");
+    g_Notify->DisplayError("glUniform4f");
 }
 void APIENTRY dummy_glDeleteObject(GLhandleARB/*obj*/)
 { /* GLX render opcode ?, req. OpenGL 1.2 w/ ARB_shader_objects */
-    DisplayError("glDeleteObject");
+    g_Notify->DisplayError("glDeleteObject");
 }
 void APIENTRY dummy_glGetInfoLog(GLhandleARB, GLsizei, GLsizei *, GLcharARB *)
 { /* GLX single opcode ?, req. OpenGL 1.2 w/ ARB_shader_objects */
-    DisplayError("glGetInfoLog");
+    g_Notify->DisplayError("glGetInfoLog");
 }
 void APIENTRY dummy_glGetObjectParameteriv(GLhandleARB, GLenum, GLint *)
 { /* GLX single opcode ?, req. OpenGL 1.2 w/ ARB_shader_objects */
-    DisplayError("glGetObjectParameteriv");
+    g_Notify->DisplayError("glGetObjectParameteriv");
 }
 
 // FXT1,DXT1,DXT5 support - Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
@@ -259,7 +251,7 @@ void APIENTRY dummy_glGetObjectParameteriv(GLhandleARB, GLenum, GLint *)
 PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2DARB;
 void APIENTRY dummy_glCompressedTexImage2D(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)
 { /* GLX render opcode 215, req. OpenGL 1.3 (1.2 w/ ARB_texture_compression) */
-    DisplayError("glCompressedTexImage2D");
+    g_Notify->DisplayError("glCompressedTexImage2D");
 }
 #endif // _WIN32
 
@@ -332,19 +324,6 @@ unsigned short depthBuffer[2048 * 2048];
 
 //#define VOODOO1
 
-#ifdef _WIN32
-void display_error()
-{
-    LPVOID lpMsgBuf;
-    if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL))
-    {
-        return;
-    }
-    MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
-    LocalFree(lpMsgBuf);
-}
-#endif // _WIN32
-
 FX_ENTRY void FX_CALL
 grSstOrigin(GrOriginLocation_t  origin)
 {
@@ -472,11 +451,11 @@ int isWglExtensionSupported(const char *extension)
 
 FX_ENTRY GrContext_t FX_CALL
 grSstWinOpenExt(
-GrColorFormat_t      color_format,
-GrOriginLocation_t   origin_location,
-GrPixelFormat_t    /*pixelformat*/,
-int                  nColBuffers,
-int                  nAuxBuffers)
+    GrColorFormat_t      color_format,
+    GrOriginLocation_t   origin_location,
+    GrPixelFormat_t    /*pixelformat*/,
+    int                  nColBuffers,
+    int                  nAuxBuffers)
 {
     WriteTrace(TraceGlitch, TraceDebug, "color_format: %d, origin_location: %d, nColBuffers: %d, nAuxBuffers: %d", color_format, origin_location, nColBuffers, nAuxBuffers);
     return grSstWinOpen(color_format, origin_location, nColBuffers, nAuxBuffers);
@@ -492,10 +471,10 @@ extern HWND g_hwnd_win;
 
 FX_ENTRY GrContext_t FX_CALL
 grSstWinOpen(
-GrColorFormat_t      color_format,
-GrOriginLocation_t   origin_location,
-int                  nColBuffers,
-int                  nAuxBuffers)
+    GrColorFormat_t      color_format,
+    GrOriginLocation_t   origin_location,
+    int                  nColBuffers,
+    int                  nAuxBuffers)
 {
     static int show_warning = 1;
 
@@ -1236,12 +1215,12 @@ int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info
 
 FX_ENTRY void FX_CALL
 grTextureAuxBufferExt(GrChipID_t tmu,
-FxU32      startAddress,
-GrLOD_t    thisLOD,
-GrLOD_t    largeLOD,
-GrAspectRatio_t aspectRatio,
-GrTextureFormat_t format,
-FxU32      odd_even_mask)
+    FxU32      startAddress,
+    GrLOD_t    thisLOD,
+    GrLOD_t    largeLOD,
+    GrAspectRatio_t aspectRatio,
+    GrTextureFormat_t format,
+    FxU32      odd_even_mask)
 {
     WriteTrace(TraceGlitch, TraceDebug, "tmu: %d startAddress: %d thisLOD: %d largeLOD: %d aspectRatio: %d format: %d odd_even_mask: %d", tmu, startAddress, thisLOD, largeLOD, aspectRatio, format, odd_even_mask);
 }
@@ -1703,30 +1682,30 @@ grRenderBuffer(GrBuffer_t buffer)
             savedHeighto = heighto;
         }
 
-    {
-        if (!use_fbo) {
-            glMatrixMode(GL_MODELVIEW);
-            glLoadIdentity();
-            glTranslatef(0, 0, 1 - zscale);
-            glScalef(1, 1, zscale);
-            inverted_culling = 0;
+        {
+            if (!use_fbo) {
+                glMatrixMode(GL_MODELVIEW);
+                glLoadIdentity();
+                glTranslatef(0, 0, 1 - zscale);
+                glScalef(1, 1, zscale);
+                inverted_culling = 0;
+            }
+            else {
+                float m[4 * 4] = { 1.0f, 0.0f, 0.0f, 0.0f,
+                    0.0f, -1.0f, 0.0f, 0.0f,
+                    0.0f, 0.0f, 1.0f, 0.0f,
+                    0.0f, 0.0f, 0.0f, 1.0f };
+                glMatrixMode(GL_MODELVIEW);
+                glLoadMatrixf(m);
+                // VP z fix
+                glTranslatef(0, 0, 1 - zscale);
+                glScalef(1, 1 * 1, zscale);
+                inverted_culling = 1;
+                grCullMode(culling_mode);
+            }
         }
-        else {
-            float m[4 * 4] = { 1.0f, 0.0f, 0.0f, 0.0f,
-                0.0f, -1.0f, 0.0f, 0.0f,
-                0.0f, 0.0f, 1.0f, 0.0f,
-                0.0f, 0.0f, 0.0f, 1.0f };
-            glMatrixMode(GL_MODELVIEW);
-            glLoadMatrixf(m);
-            // VP z fix
-            glTranslatef(0, 0, 1 - zscale);
-            glScalef(1, 1 * 1, zscale);
-            inverted_culling = 1;
-            grCullMode(culling_mode);
-        }
-    }
-    render_to_texture = 1;
-    break;
+        render_to_texture = 1;
+        break;
     default:
         WriteTrace(TraceGlitch, TraceWarning, "grRenderBuffer : unknown buffer : %x", buffer);
     }
@@ -1738,7 +1717,7 @@ grAuxBufferExt(GrBuffer_t buffer)
 {
     WriteTrace(TraceGlitch, TraceDebug, "buffer: %d", buffer);
 
-    if (buffer == GR_BUFFER_AUXBUFFER) 
+    if (buffer == GR_BUFFER_AUXBUFFER)
     {
         invtex[0] = 0;
         invtex[1] = 0;
@@ -1823,8 +1802,8 @@ grBufferSwap(FxU32 swap_interval)
 
 FX_ENTRY FxBool FX_CALL
 grLfbLock(GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode,
-GrOriginLocation_t origin, FxBool pixelPipeline,
-GrLfbInfo_t *info)
+    GrOriginLocation_t origin, FxBool pixelPipeline,
+    GrLfbInfo_t *info)
 {
     WriteTrace(TraceGlitch, TraceDebug, "type: %d buffer: %d writeMode: %d origin: %d pixelPipeline: %d", type, buffer, writeMode, origin, pixelPipeline);
     if (type == GR_LFB_WRITE_ONLY)
@@ -1907,9 +1886,9 @@ grLfbUnlock(GrLock_t type, GrBuffer_t buffer)
 
 FX_ENTRY FxBool FX_CALL
 grLfbReadRegion(GrBuffer_t src_buffer,
-FxU32 src_x, FxU32 src_y,
-FxU32 src_width, FxU32 src_height,
-FxU32 dst_stride, void *dst_data)
+    FxU32 src_x, FxU32 src_y,
+    FxU32 src_width, FxU32 src_height,
+    FxU32 dst_stride, void *dst_data)
 {
     unsigned char *buf;
     unsigned int i, j;
@@ -1973,11 +1952,11 @@ FxU32 dst_stride, void *dst_data)
 
 FX_ENTRY FxBool FX_CALL
 grLfbWriteRegion(GrBuffer_t dst_buffer,
-FxU32 dst_x, FxU32 dst_y,
-GrLfbSrcFmt_t src_format,
-FxU32 src_width, FxU32 src_height,
-FxBool pixelPipeline,
-FxI32 src_stride, void *src_data)
+    FxU32 dst_x, FxU32 dst_y,
+    GrLfbSrcFmt_t src_format,
+    FxU32 src_width, FxU32 src_height,
+    FxBool pixelPipeline,
+    FxI32 src_stride, void *src_data)
 {
     unsigned char *buf;
     unsigned int i, j;
@@ -2082,7 +2061,7 @@ FxI32 src_stride, void *src_data)
     }
     else
     {
-        float *buf = (float*)malloc(src_width*(src_height + (g_viewport_offset))*sizeof(float));
+        float *buf = (float*)malloc(src_width*(src_height + (g_viewport_offset)) * sizeof(float));
 
         if (src_format != GR_LFBWRITEMODE_ZA16)
             WriteTrace(TraceGlitch, TraceWarning, "unknown depth buffer write format:%x", src_format);
@@ -2131,7 +2110,6 @@ FxI32 src_stride, void *src_data)
     return FXTRUE;
 }
 
-
 /* wrapper-specific glide extensions */
 
 FX_ENTRY FxBool FX_CALL grKeyPressedExt(FxU32 key)
@@ -2233,46 +2211,46 @@ grFlush(void)
 
 FX_ENTRY void FX_CALL
 grTexMultibase(GrChipID_t /*tmu*/,
-FxBool     /*enable*/)
+    FxBool     /*enable*/)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexMultibase");
 }
 
 FX_ENTRY void FX_CALL
 grTexMipMapMode(GrChipID_t    /*tmu*/,
-GrMipMapMode_t /*mode*/,
-FxBool         /*lodBlend*/)
+    GrMipMapMode_t /*mode*/,
+    FxBool         /*lodBlend*/)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexMipMapMode");
 }
 
 FX_ENTRY void FX_CALL
 grTexDownloadTablePartial(GrTexTable_t /*type*/,
-void      * /*data*/,
-int         /*start*/,
-int         /*end*/)
+    void      * /*data*/,
+    int         /*start*/,
+    int         /*end*/)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexDownloadTablePartial");
 }
 
 FX_ENTRY void FX_CALL
 grTexDownloadTable(GrTexTable_t /*type*/,
-void        * /*data*/)
+    void        * /*data*/)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexDownloadTable");
 }
 
 FX_ENTRY FxBool FX_CALL
 grTexDownloadMipMapLevelPartial(GrChipID_t        /*tmu*/,
-FxU32             /*startAddress*/,
-GrLOD_t           /*thisLod*/,
-GrLOD_t           /*largeLod*/,
-GrAspectRatio_t   /*aspectRatio*/,
-GrTextureFormat_t /*format*/,
-FxU32             /*evenOdd*/,
-void *            /*data*/,
-int               /*start*/,
-int               /*end*/)
+    FxU32             /*startAddress*/,
+    GrLOD_t           /*thisLod*/,
+    GrLOD_t           /*largeLod*/,
+    GrAspectRatio_t   /*aspectRatio*/,
+    GrTextureFormat_t /*format*/,
+    FxU32             /*evenOdd*/,
+    void *            /*data*/,
+    int               /*start*/,
+    int               /*end*/)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexDownloadMipMapLevelPartial");
     return 1;
@@ -2280,13 +2258,13 @@ int               /*end*/)
 
 FX_ENTRY void FX_CALL
 grTexDownloadMipMapLevel(GrChipID_t       /*tmu*/,
-FxU32             /*startAddress*/,
-GrLOD_t           /*thisLod*/,
-GrLOD_t           /*largeLod*/,
-GrAspectRatio_t   /*aspectRatio*/,
-GrTextureFormat_t /*format*/,
-FxU32             /*evenOdd*/,
-void            * /*data*/)
+    FxU32             /*startAddress*/,
+    GrLOD_t           /*thisLod*/,
+    GrLOD_t           /*largeLod*/,
+    GrAspectRatio_t   /*aspectRatio*/,
+    GrTextureFormat_t /*format*/,
+    FxU32             /*evenOdd*/,
+    void            * /*data*/)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexDownloadMipMapLevel");
 }
@@ -2324,8 +2302,8 @@ grSelectContext(GrContext_t /*context*/)
 
 FX_ENTRY void FX_CALL
 grAADrawTriangle(
-const void * /*a*/, const void * /*b*/, const void * /*c*/,
-FxBool /*ab_antialias*/, FxBool /*bc_antialias*/, FxBool /*ca_antialias*/
+    const void * /*a*/, const void * /*b*/, const void * /*c*/,
+    FxBool /*ab_antialias*/, FxBool /*bc_antialias*/, FxBool /*ca_antialias*/
 )
 {
     WriteTrace(TraceGlitch, TraceWarning, "grAADrawTriangle");
@@ -2387,10 +2365,10 @@ grLfbConstantAlpha(GrAlpha_t /*alpha*/)
 
 FX_ENTRY void FX_CALL
 grTexMultibaseAddress(GrChipID_t      /*tmu*/,
-GrTexBaseRange_t /*range*/,
-FxU32            /*startAddress*/,
-FxU32            /*evenOdd*/,
-GrTexInfo *      /*info*/)
+    GrTexBaseRange_t /*range*/,
+    FxU32            /*startAddress*/,
+    FxU32            /*evenOdd*/,
+    GrTexInfo *      /*info*/)
 {
     WriteTrace(TraceGlitch, TraceWarning, "grTexMultibaseAddress");
 }
@@ -2410,7 +2388,7 @@ static void CorrectGamma(const FxU16 aGammaRamp[3][256])
 {
     int res;
 
- /* res = SDL_SetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]); */
+    /* res = SDL_SetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]); */
     res = -1;
     fputs("ERROR:  Replacement for SDL_SetGammaRamp unimplemented.\n", stderr);
     WriteTrace(TraceGlitch, TraceDebug, "SDL_SetGammaRamp returned %d\r\n", res);
@@ -2445,7 +2423,7 @@ grGetGammaTableExt(FxU32 /*nentries*/, FxU32 *red, FxU32 *green, FxU32 *blue)
         ReleaseDC(NULL, hdc);
 #else
     fputs("ERROR:  Replacement for SDL_GetGammaRamp unimplemented.\n", stderr);
- /* if (SDL_GetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]) != -1) */
+    /* if (SDL_GetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]) != -1) */
     {
 #endif
         for (int i = 0; i < 256; i++)
@@ -2648,7 +2626,7 @@ void dump_tex(int id)
 
     int n;
     // yes, it's inefficient
-    for (n=0; n<tl_i; n++)
+    for (n = 0; n < tl_i; n++)
         if (tl[n] == id)
             return;
 
@@ -2702,4 +2680,4 @@ void CHECK_FRAMEBUFFER_STATUS()
         /* programming error; will fail on all hardware */
         /*assert(0);*/
     }
-}
+}
\ No newline at end of file
diff --git a/Source/Project64-core/Plugins/PluginBase.cpp b/Source/Project64-core/Plugins/PluginBase.cpp
index 6201635de..99555b925 100644
--- a/Source/Project64-core/Plugins/PluginBase.cpp
+++ b/Source/Project64-core/Plugins/PluginBase.cpp
@@ -72,6 +72,19 @@ bool CPlugin::Load(const char * FileName)
     LoadFunction(DllConfig);
     LoadFunction(DllAbout);
 
+    LoadFunction(SetPluginNotification);
+    if (SetPluginNotification)
+    {
+        WriteTrace(PluginTraceType(), TraceDebug, "Found SetPluginNotification");
+        PLUGIN_NOTIFICATION info;
+        info.DisplayError = DisplayError;
+        info.FatalError = FatalError;
+        info.DisplayMessage = DisplayMessage;
+        info.DisplayMessage2 = DisplayMessage2;
+        info.BreakPoint = BreakPoint;
+        SetPluginNotification(&info);
+    }
+
     LoadFunction(SetSettingNotificationInfo);
     if (SetSettingNotificationInfo)
     {
@@ -305,4 +318,29 @@ bool CPlugin::ValidPluginVersion(PLUGIN_INFO & PluginInfo)
         break;
     }
     return false;
-}
\ No newline at end of file
+}
+
+void CPlugin::DisplayError(const char * Message)
+{
+    g_Notify->DisplayError(Message);
+}
+
+void CPlugin::FatalError(const char * Message)
+{
+    g_Notify->FatalError(Message);
+}
+
+void CPlugin::DisplayMessage(int DisplayTime, const char * Message)
+{
+    g_Notify->DisplayMessage(DisplayTime, Message);
+}
+
+void CPlugin::DisplayMessage2(const char * Message)
+{
+    g_Notify->DisplayMessage2(Message);
+}
+
+void CPlugin::BreakPoint(const char * FileName, int32_t LineNumber)
+{
+    g_Notify->BreakPoint(FileName, LineNumber);
+}
diff --git a/Source/Project64-core/Plugins/PluginBase.h b/Source/Project64-core/Plugins/PluginBase.h
index 57bb17903..fb1a04e36 100644
--- a/Source/Project64-core/Plugins/PluginBase.h
+++ b/Source/Project64-core/Plugins/PluginBase.h
@@ -61,6 +61,7 @@ protected:
     void(CALL *SetSettingInfo2)(PLUGIN_SETTINGS2 *);
     void(CALL *SetSettingInfo3)(PLUGIN_SETTINGS3 *);
     void(CALL *SetSettingNotificationInfo)(PLUGIN_SETTINGS_NOTIFICATION *);
+    void(CALL *SetPluginNotification)(PLUGIN_NOTIFICATION *);
 
     pjutil::DynLibHandle m_LibHandle;
     bool m_Initialized, m_RomOpen;
@@ -76,4 +77,11 @@ protected:
     // i.e. _LoadFunction("CloseDLL", CloseDLL);
 #define LoadFunction(functionName) _LoadFunctionVoid(#functionName, (void **)&functionName)
 #define _LoadFunction(functionName,function) _LoadFunctionVoid(functionName, (void **)&function)
+
+private:
+    static void DisplayError(const char * Message);
+    static void FatalError(const char * Message);
+    static void DisplayMessage(int DisplayTime, const char * Message);
+    static void DisplayMessage2(const char * Message);
+    static void BreakPoint(const char * FileName, int32_t LineNumber);
 };
diff --git a/Source/Project64-core/Plugins/PluginClass.cpp b/Source/Project64-core/Plugins/PluginClass.cpp
index 06bdd1f06..88e832cf6 100644
--- a/Source/Project64-core/Plugins/PluginClass.cpp
+++ b/Source/Project64-core/Plugins/PluginClass.cpp
@@ -326,7 +326,6 @@ bool CPlugins::Reset(CN64System * System)
     bool bRspChange = _stricmp(m_RSPFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()) != 0;
     bool bContChange = _stricmp(m_ControlFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()) != 0;
 
-
     if (g_Settings->LoadBool(Plugin_ForceGfxReset))
     {
         //this is a hack and should not be here, glide64 is not correctly freeing something on restart, this needs to be fixed but this is a short term workaround
diff --git a/Source/Project64-core/Plugins/PluginClass.h b/Source/Project64-core/Plugins/PluginClass.h
index 372170a36..34d3b2775 100644
--- a/Source/Project64-core/Plugins/PluginClass.h
+++ b/Source/Project64-core/Plugins/PluginClass.h
@@ -80,6 +80,15 @@ typedef struct
     void(*UnregisterChangeCB)(void * handle, int ID, void * Data, SettingChangedFunc Func);
 } PLUGIN_SETTINGS_NOTIFICATION;
 
+typedef struct
+{
+    void(*DisplayError)(const char * Message);
+    void(*FatalError)(const char * Message);
+    void(*DisplayMessage)(int DisplayTime, const char * Message);
+    void(*DisplayMessage2)(const char * Message);
+    void(*BreakPoint)(const char * FileName, int32_t LineNumber);
+} PLUGIN_NOTIFICATION;
+
 enum PLUGIN_TYPE
 {
     PLUGIN_TYPE_NONE = 0,
diff --git a/Source/Settings/Settings.cpp b/Source/Settings/Settings.cpp
index 7b35b9b4c..56b1d5a32 100644
--- a/Source/Settings/Settings.cpp
+++ b/Source/Settings/Settings.cpp
@@ -12,6 +12,9 @@
 #define CALL
 #endif
 
+CNotification g_NotifyLocal;
+CNotification * g_Notify = &g_NotifyLocal;
+
 enum SettingLocation
 {
     SettingType_ConstString = 0,
@@ -72,16 +75,27 @@ typedef struct
     void(*UnregisterChangeCB)(void * handle, int ID, void * Data, SettingChangedFunc Func);
 } PLUGIN_SETTINGS_NOTIFICATION;
 
+typedef struct
+{
+    void (*DisplayError)(const char * Message);
+    void (*FatalError)(const char * Message);
+    void (*DisplayMessage)(int DisplayTime, const char * Message);
+    void (*DisplayMessage2)(const char * Message);
+    void (*BreakPoint)(const char * FileName, int32_t LineNumber);
+} PLUGIN_NOTIFICATION;
+
 static PLUGIN_SETTINGS  g_PluginSettings;
 static PLUGIN_SETTINGS2 g_PluginSettings2;
 static PLUGIN_SETTINGS3 g_PluginSettings3;
 static PLUGIN_SETTINGS_NOTIFICATION g_PluginSettingsNotification;
+static PLUGIN_NOTIFICATION g_PluginNotification;
 static bool g_PluginInitilized = false;
 static char g_PluginSettingName[300];
 
 EXPORT void SetSettingInfo(PLUGIN_SETTINGS * info);
 EXPORT void SetSettingInfo2(PLUGIN_SETTINGS2 * info);
 EXPORT void SetSettingInfo3(PLUGIN_SETTINGS3 * info);
+EXPORT void SetPluginNotification(PLUGIN_NOTIFICATION * info);
 
 EXPORT void SetSettingInfo(PLUGIN_SETTINGS * info)
 {
@@ -105,6 +119,11 @@ EXPORT void SetSettingNotificationInfo(PLUGIN_SETTINGS_NOTIFICATION * info)
     g_PluginSettingsNotification = *info;
 }
 
+EXPORT void SetPluginNotification(PLUGIN_NOTIFICATION * info)
+{
+    g_PluginNotification = *info;
+}
+
 int32_t SettingsInitilized(void)
 {
     return g_PluginInitilized;
@@ -316,3 +335,43 @@ void SettingsUnregisterChange(bool SystemSetting, int SettingID, void * Data, Se
         g_PluginSettingsNotification.UnregisterChangeCB(g_PluginSettings.handle, SettingID + (SystemSetting ? 0 : g_PluginSettings.SettingStartRange), Data, Func);
     }
 }
+
+void CNotification::DisplayError(const char * Message)
+{
+    if (g_PluginNotification.BreakPoint != NULL)
+    {
+        g_PluginNotification.DisplayError(Message);
+    }
+}
+
+void CNotification::FatalError(const char * Message)
+{
+    if (g_PluginNotification.BreakPoint != NULL)
+    {
+        g_PluginNotification.FatalError(Message);
+    }
+}
+
+void CNotification::DisplayMessage(int DisplayTime, const char * Message)
+{
+    if (g_PluginNotification.BreakPoint != NULL)
+    {
+        g_PluginNotification.DisplayMessage(DisplayTime, Message);
+    }
+}
+
+void CNotification::DisplayMessage2(const char * Message)
+{
+    if (g_PluginNotification.BreakPoint != NULL)
+    {
+        g_PluginNotification.DisplayMessage2(Message);
+    }
+}
+
+void CNotification::BreakPoint(const char * FileName, int LineNumber)
+{
+    if (g_PluginNotification.BreakPoint != NULL)
+    {
+        g_PluginNotification.BreakPoint(FileName, LineNumber);
+    }
+}
diff --git a/Source/Settings/Settings.h b/Source/Settings/Settings.h
index 13f0af1ae..5b1b4999a 100644
--- a/Source/Settings/Settings.h
+++ b/Source/Settings/Settings.h
@@ -48,3 +48,15 @@ extern "C" {
 #if defined(__cplusplus)
 }
 #endif
+
+class CNotification
+{
+public:
+    static void DisplayError(const char * Message);
+    static void FatalError(const char * Message);
+    static void DisplayMessage(int DisplayTime, const char * Message);
+    static void DisplayMessage2(const char * Message);
+    static void BreakPoint(const char * FileName, int LineNumber);
+};
+
+extern CNotification * g_Notify;