diff --git a/MissionEditor/IsoView.cpp b/MissionEditor/IsoView.cpp index 5aacc66..01899a6 100644 --- a/MissionEditor/IsoView.cpp +++ b/MissionEditor/IsoView.cpp @@ -201,6 +201,218 @@ CIsoView::~CIsoView() bNoThreadDraw = TRUE; } +BOOL CIsoView::RecreateSurfaces() +{ + last_succeeded_operation = 7; + + errstream << "\n\nDirectDrawCreate() will be called now\n"; + errstream.flush(); + + CIsoView& isoView = *this; + if (DirectDrawCreate(NULL, &isoView.dd_1, NULL) != DD_OK) { + errstream << "DirectDrawCreate() failed\n"; + errstream.flush(); + ShowWindow(SW_HIDE); + MessageBox("DirectDraw could not be initialized! Quitting..."); + exit(-1); + + return FALSE; + } + + errstream << "DirectDrawCreate() successful\n\n"; + errstream.flush(); + + errstream << "Now querying the DirectX 7 or 6 interface\n"; + errstream.flush(); + + if (isoView.dd_1->QueryInterface(IID_IDirectDraw7, (void**)&isoView.dd) != DD_OK) { + errstream << "QueryInterface() failed -> Using DirectX 6.0\n"; + errstream.flush(); + //ShowWindow(SW_HIDE); + //MessageBox("You don´t have DirectX 6.0 but an older version. Quitting..."); + //exit(-1); + + //return FALSE; + + if (isoView.dd_1->QueryInterface(IID_IDirectDraw4, (void**)&isoView.dd) != DD_OK) { + MessageBox("You need at least DirectX 6.0 to run this program", "Error"); + exit(-1); + return FALSE; + } + } + + errstream << "QueryInterface() successful\n\nNow setting cooperative level\n"; + errstream.flush(); + + if (isoView.dd->SetCooperativeLevel(isoView.m_hWnd, DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES) != DD_OK) { + errstream << "SetCooperativeLevel() failed\n"; + errstream.flush(); + ShowWindow(SW_HIDE); + MessageBox("Cooperative Level could not be set! Quitting..."); + isoView.dd->Release(); + isoView.dd = NULL; + exit(-2); + + return FALSE; + } + + errstream << "SetCooperativeLevel() successful\n\nCreating primary surface\n"; + errstream.flush(); + + DDSURFACEDESC2 ddsd; + + + memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + ddsd.dwFlags = DDSD_CAPS; + + + + int res = 0; + int trycount = 0; + do { + res = isoView.dd->CreateSurface(&ddsd, &isoView.lpds, NULL); + errstream << "Return code: " << res << endl; + errstream.flush(); + + //if(res!=DD_OK && (res!=DDERR_PRIMARYSURFACEALREADYEXISTS || trycount>100)) + if (res != DD_OK && trycount >= 300) { + + errstream << "CreateSurface() failed\n"; + + errstream.flush(); + ShowWindow(SW_HIDE); + MessageBox("Primary surface could not be initialized! Quitting..."); + isoView.dd->Release(); + isoView.dd = NULL; + exit(-3); + + return FALSE; + } + trycount++; + if (res != DD_OK) { + Sleep(50); + } + + + } while (res != DD_OK); + +#ifdef NOSURFACES + DDPIXELFORMAT pf; + memset(&pf, 0, sizeof(DDPIXELFORMAT)); + pf.dwSize = sizeof(DDPIXELFORMAT); + + isoView.lpds->GetPixelFormat(&pf); + + if (!pf.dwBBitMask || !pf.dwRBitMask || !pf.dwGBitMask) { + ShowWindow(SW_HIDE); + MessageBox("You must not use a palette color mode like 8 bit in order to run FinalSun/FinalAlert 2. Please check readme.txt", "Error", MB_OK); + + isoView.lpds->Release(); + isoView.lpds = NULL; + isoView.dd->Release(); + isoView.dd = NULL; + exit(-3); + return FALSE; + } + bpp = (pf.dwRGBBitCount + 7) / 8; +#endif + + + errstream << "CreateSurface() successful\n\nCreating backbuffer surface\n"; + errstream.flush(); + + memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); + ddsd.dwSize = sizeof(DDSURFACEDESC2); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; + isoView.lpds->GetSurfaceDesc(&ddsd); + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + + + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + + + if (isoView.dd->CreateSurface(&ddsd, &isoView.lpdsBack, NULL) != DD_OK) { + errstream << "CreateSurface() failed\n"; + errstream.flush(); + ShowWindow(SW_HIDE); + MessageBox("Backbuffer surface could not be initialized! Quitting..."); + isoView.lpds->Release(); + isoView.lpds = NULL; + isoView.dd->Release(); + isoView.dd = NULL; + exit(-4); + + return FALSE; + } + if (theApp.m_Options.bHighResUI && isoView.dd->CreateSurface(&ddsd, &isoView.lpdsBackHighRes, NULL) != DD_OK) { + errstream << "CreateSurface() failed\n"; + errstream.flush(); + ShowWindow(SW_HIDE); + MessageBox("Highres Backbuffer surface could not be initialized! Quitting..."); + isoView.lpdsBack->Release(); + isoView.lpdsBack = NULL; + isoView.lpds->Release(); + isoView.lpds = NULL; + isoView.dd->Release(); + isoView.dd = NULL; + exit(-4); + + return FALSE; + } + if (isoView.dd->CreateSurface(&ddsd, &isoView.lpdsTemp, NULL) != DD_OK) { + errstream << "CreateSurface() failed\n"; + errstream.flush(); + ShowWindow(SW_HIDE); + MessageBox("Tempbuffer surface could not be initialized! Quitting..."); + isoView.lpdsBack->Release(); + isoView.lpdsBack = NULL; + if (isoView.lpdsBackHighRes) + isoView.lpdsBackHighRes->Release(); + isoView.lpdsBackHighRes = nullptr; + isoView.lpds->Release(); + isoView.lpds = NULL; + isoView.dd->Release(); + isoView.dd = NULL; + exit(-4); + + return FALSE; + } + + errstream << "CreateSurface() successful\n\nNow creating clipper\n"; + errstream.flush(); + + LPDIRECTDRAWCLIPPER ddc; + if (isoView.dd->CreateClipper(0, &ddc, NULL) != DD_OK) { + errstream << "CreateClipper() failed\n"; + errstream.flush(); + ShowWindow(SW_HIDE); + MessageBox("Clipper could not be created! Quitting..."); + isoView.lpdsTemp->Release(); + isoView.lpdsTemp = NULL; + isoView.lpdsBack->Release(); + isoView.lpdsBack = NULL; + if (isoView.lpdsBackHighRes) + isoView.lpdsBackHighRes->Release(); + isoView.lpdsBackHighRes = nullptr; + isoView.lpds->Release(); + isoView.lpds = NULL; + isoView.dd->Release(); + isoView.dd = NULL; + exit(-6); + } + + errstream << "CreateClipper() successful\n\n"; + errstream.flush(); + + isoView.lpds->SetClipper(ddc); + + ddc->SetHWnd(0, isoView.m_hWnd); + + return TRUE; +} + BEGIN_MESSAGE_MAP(CIsoView, CView) //{{AFX_MSG_MAP(CIsoView) @@ -6044,11 +6256,8 @@ void CIsoView::DrawMap() } -void CIsoView::RenderUIOverlay() +std::tuple CIsoView::getDDDesc(bool recreated) { - if (!m_textDefault) - updateFontScaled(); - LPDIRECTDRAWSURFACE4 dds = lpdsBack; bool useHighRes = false; if (m_viewScale != Vec2(1.0f, 1.0f) && lpdsBackHighRes) { @@ -6063,7 +6272,27 @@ void CIsoView::RenderUIOverlay() dds->GetSurfaceDesc(&ddsd); - dds->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL); + auto const lockRet = dds->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL); + + if (lockRet == DDERR_SURFACELOST && !recreated) { + ReInitializeDDraw(); + return getDDDesc(true); + } + + ASSERT(lockRet == S_OK); + ASSERT(ddsd.lpSurface != nullptr); + + return { ddsd, dds, useHighRes }; +} + +void CIsoView::RenderUIOverlay() +{ + if (!m_textDefault) { + updateFontScaled(); + } + + auto const [ddsd, dds, useHighRes] = getDDDesc(false); + LineDrawer d(ddsd.lpSurface, bpp, ddsd.dwWidth, ddsd.dwHeight, ddsd.lPitch); int lr, lt, ll, lb; diff --git a/MissionEditor/IsoView.h b/MissionEditor/IsoView.h index b250cf0..80e051b 100644 --- a/MissionEditor/IsoView.h +++ b/MissionEditor/IsoView.h @@ -101,6 +101,8 @@ public: CIsoView(); virtual ~CIsoView(); + BOOL RecreateSurfaces(); + // overwriteables //{{AFX_VIRTUAL(CIsoView) public: @@ -119,7 +121,7 @@ protected: virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif - + std::tuple getDDDesc(bool recreated); // generated message maps //{{AFX_MSG(CIsoView) diff --git a/MissionEditor/Loading.cpp b/MissionEditor/Loading.cpp index 8c94902..6c13504 100644 --- a/MissionEditor/Loading.cpp +++ b/MissionEditor/Loading.cpp @@ -3539,214 +3539,7 @@ void CLoading::CalcPicCount() BOOL CLoading::InitDirectDraw() { - last_succeeded_operation = 7; - - errstream << "\n\nDirectDrawCreate() will be called now\n"; - errstream.flush(); - - CIsoView& v = *((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview; - if (DirectDrawCreate(NULL, &v.dd_1, NULL) != DD_OK) { - errstream << "DirectDrawCreate() failed\n"; - errstream.flush(); - ShowWindow(SW_HIDE); - MessageBox("DirectDraw could not be initialized! Quitting..."); - exit(-1); - - return FALSE; - } - - errstream << "DirectDrawCreate() successful\n\n"; - errstream.flush(); - - errstream << "Now querying the DirectX 7 or 6 interface\n"; - errstream.flush(); - - if (v.dd_1->QueryInterface(IID_IDirectDraw7, (void**)&v.dd) != DD_OK) { - errstream << "QueryInterface() failed -> Using DirectX 6.0\n"; - errstream.flush(); - //ShowWindow(SW_HIDE); - //MessageBox("You don´t have DirectX 6.0 but an older version. Quitting..."); - //exit(-1); - - //return FALSE; - - if (v.dd_1->QueryInterface(IID_IDirectDraw4, (void**)&v.dd) != DD_OK) { - MessageBox("You need at least DirectX 6.0 to run this program", "Error"); - exit(-1); - return FALSE; - } - } - - errstream << "QueryInterface() successful\n\nNow setting cooperative level\n"; - errstream.flush(); - - if (v.dd->SetCooperativeLevel(v.m_hWnd, DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES) != DD_OK) { - errstream << "SetCooperativeLevel() failed\n"; - errstream.flush(); - ShowWindow(SW_HIDE); - MessageBox("Cooperative Level could not be set! Quitting..."); - v.dd->Release(); - v.dd = NULL; - exit(-2); - - return FALSE; - } - - errstream << "SetCooperativeLevel() successful\n\nCreating primary surface\n"; - errstream.flush(); - - DDSURFACEDESC2 ddsd; - - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(DDSURFACEDESC2); - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - ddsd.dwFlags = DDSD_CAPS; - - - - int res = 0; - int trycount = 0; - do { - res = v.dd->CreateSurface(&ddsd, &v.lpds, NULL); - errstream << "Return code: " << res << endl; - errstream.flush(); - - //if(res!=DD_OK && (res!=DDERR_PRIMARYSURFACEALREADYEXISTS || trycount>100)) - if (res != DD_OK && trycount >= 300) { - - errstream << "CreateSurface() failed\n"; - - errstream.flush(); - ShowWindow(SW_HIDE); - MessageBox("Primary surface could not be initialized! Quitting..."); - v.dd->Release(); - v.dd = NULL; - exit(-3); - - return FALSE; - } - trycount++; - if (res != DD_OK) { - Sleep(50); - } - - - } while (res != DD_OK); - -#ifdef NOSURFACES - DDPIXELFORMAT pf; - memset(&pf, 0, sizeof(DDPIXELFORMAT)); - pf.dwSize = sizeof(DDPIXELFORMAT); - - v.lpds->GetPixelFormat(&pf); - - if (!pf.dwBBitMask || !pf.dwRBitMask || !pf.dwGBitMask) { - ShowWindow(SW_HIDE); - MessageBox("You must not use a palette color mode like 8 bit in order to run FinalSun/FinalAlert 2. Please check readme.txt", "Error", MB_OK); - - v.lpds->Release(); - v.lpds = NULL; - v.dd->Release(); - v.dd = NULL; - exit(-3); - return FALSE; - } - bpp = (pf.dwRGBBitCount + 7) / 8; -#endif - - - errstream << "CreateSurface() successful\n\nCreating backbuffer surface\n"; - errstream.flush(); - - memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(DDSURFACEDESC2); - ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; - v.lpds->GetSurfaceDesc(&ddsd); - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - - - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - - - if (v.dd->CreateSurface(&ddsd, &v.lpdsBack, NULL) != DD_OK) { - errstream << "CreateSurface() failed\n"; - errstream.flush(); - ShowWindow(SW_HIDE); - MessageBox("Backbuffer surface could not be initialized! Quitting..."); - v.lpds->Release(); - v.lpds = NULL; - v.dd->Release(); - v.dd = NULL; - exit(-4); - - return FALSE; - } - if (theApp.m_Options.bHighResUI && v.dd->CreateSurface(&ddsd, &v.lpdsBackHighRes, NULL) != DD_OK) { - errstream << "CreateSurface() failed\n"; - errstream.flush(); - ShowWindow(SW_HIDE); - MessageBox("Highres Backbuffer surface could not be initialized! Quitting..."); - v.lpdsBack->Release(); - v.lpdsBack = NULL; - v.lpds->Release(); - v.lpds = NULL; - v.dd->Release(); - v.dd = NULL; - exit(-4); - - return FALSE; - } - if (v.dd->CreateSurface(&ddsd, &v.lpdsTemp, NULL) != DD_OK) { - errstream << "CreateSurface() failed\n"; - errstream.flush(); - ShowWindow(SW_HIDE); - MessageBox("Tempbuffer surface could not be initialized! Quitting..."); - v.lpdsBack->Release(); - v.lpdsBack = NULL; - if (v.lpdsBackHighRes) - v.lpdsBackHighRes->Release(); - v.lpdsBackHighRes = nullptr; - v.lpds->Release(); - v.lpds = NULL; - v.dd->Release(); - v.dd = NULL; - exit(-4); - - return FALSE; - } - - errstream << "CreateSurface() successful\n\nNow creating clipper\n"; - errstream.flush(); - - LPDIRECTDRAWCLIPPER ddc; - if (v.dd->CreateClipper(0, &ddc, NULL) != DD_OK) { - errstream << "CreateClipper() failed\n"; - errstream.flush(); - ShowWindow(SW_HIDE); - MessageBox("Clipper could not be created! Quitting..."); - v.lpdsTemp->Release(); - v.lpdsTemp = NULL; - v.lpdsBack->Release(); - v.lpdsBack = NULL; - if (v.lpdsBackHighRes) - v.lpdsBackHighRes->Release(); - v.lpdsBackHighRes = nullptr; - v.lpds->Release(); - v.lpds = NULL; - v.dd->Release(); - v.dd = NULL; - exit(-6); - } - - errstream << "CreateClipper() successful\n\n"; - errstream.flush(); - - v.lpds->SetClipper(ddc); - - ddc->SetHWnd(0, v.m_hWnd); - - return TRUE; + return ((CFinalSunDlg*)theApp.m_pMainWnd)->m_view.m_isoview->RecreateSurfaces(); } void CLoading::OnPaint() @@ -3919,18 +3712,30 @@ void CLoading::FreeAll() try { CFinalSunDlg* dlg = ((CFinalSunDlg*)theApp.m_pMainWnd); - if (dlg->m_view.m_isoview->lpds != NULL) dlg->m_view.m_isoview->lpds->Release(); - dlg->m_view.m_isoview->lpds = NULL; - if (dlg->m_view.m_isoview->lpdsBack != NULL) dlg->m_view.m_isoview->lpdsBack->Release(); - dlg->m_view.m_isoview->lpdsBack = NULL; - if (dlg->m_view.m_isoview->lpdsBackHighRes != NULL) dlg->m_view.m_isoview->lpdsBackHighRes->Release(); - dlg->m_view.m_isoview->lpdsBackHighRes = NULL; - if (dlg->m_view.m_isoview->lpdsTemp != NULL) dlg->m_view.m_isoview->lpdsTemp->Release(); - dlg->m_view.m_isoview->lpdsTemp = NULL; - if (dlg->m_view.m_isoview->dd != NULL) dlg->m_view.m_isoview->dd->Release(); - dlg->m_view.m_isoview->dd = NULL; - if (dlg->m_view.m_isoview->dd_1 != NULL) dlg->m_view.m_isoview->dd_1->Release(); - dlg->m_view.m_isoview->dd_1 = NULL; + if (dlg->m_view.m_isoview->lpds != NULL) { + dlg->m_view.m_isoview->lpds->Release(); + dlg->m_view.m_isoview->lpds = NULL; + } + if (dlg->m_view.m_isoview->lpdsBack != NULL) { + dlg->m_view.m_isoview->lpdsBack->Release(); + dlg->m_view.m_isoview->lpdsBack = NULL; + } + if (dlg->m_view.m_isoview->lpdsBackHighRes != NULL) { + dlg->m_view.m_isoview->lpdsBackHighRes->Release(); + dlg->m_view.m_isoview->lpdsBackHighRes = NULL; + } + if (dlg->m_view.m_isoview->lpdsTemp != NULL) { + dlg->m_view.m_isoview->lpdsTemp->Release(); + dlg->m_view.m_isoview->lpdsTemp = NULL; + } + if (dlg->m_view.m_isoview->dd != NULL) { + dlg->m_view.m_isoview->dd->Release(); + dlg->m_view.m_isoview->dd = NULL; + } + if (dlg->m_view.m_isoview->dd_1 != NULL) { + dlg->m_view.m_isoview->dd_1->Release(); + dlg->m_view.m_isoview->dd_1 = NULL; + } } catch (...) { errstream << "Exception while freeing DirectDraw" << endl; } diff --git a/MissionEditorPackLib/MissionEditorPackLib.cpp b/MissionEditorPackLib/MissionEditorPackLib.cpp index 7065ea8..bb46786 100644 --- a/MissionEditorPackLib/MissionEditorPackLib.cpp +++ b/MissionEditorPackLib/MissionEditorPackLib.cpp @@ -1635,6 +1635,7 @@ namespace FSunPackLib VoxelNormalTable emptyNormalTable; +#if defined(XCC_VXL_DRAW) BOOL LoadVXLImageInSurface(const VoxelNormalTables& normalTables, Vec3f lightDirection, IDirectDraw4* pdd, int iStart, int iCount, const Vec3f rotation, const Vec3f postHVAOffset, LPDIRECTDRAWSURFACE4* pdds, HTSPALETTE hPalette, int* lpXCenter, int* lpYCenter, int ZAdjust, int* lpXCenterZMax, int* lpYCenterZMax, int i3dCenterX, int i3dCenterY) { if (hPalette == NULL || hPalette > dwPalCount) return NULL; @@ -1850,6 +1851,7 @@ namespace FSunPackLib //pal.close(); return TRUE; } +#endif BOOL LoadVXLImage( const VoxelNormalTables& normalTables, diff --git a/MissionEditorPackLib/MissionEditorPackLib.h b/MissionEditorPackLib/MissionEditorPackLib.h index c80b533..3a1b2be 100644 --- a/MissionEditorPackLib/MissionEditorPackLib.h +++ b/MissionEditorPackLib/MissionEditorPackLib.h @@ -228,7 +228,9 @@ namespace FSunPackLib BOOL GetVXLSectionInfo(int section, VoxelNormalClass& normalClass); +#if defined(XCC_VXL_DRAW) BOOL LoadVXLImageInSurface(const VoxelNormalTables& normalTables, Vec3f lightDirection, IDirectDraw4* pdd, int iStart, int iCount, Vec3f rotation, Vec3f modelOffset, LPDIRECTDRAWSURFACE4* pdds, HTSPALETTE hPalette, int* lpXCenter = NULL, int* lpYCenter = NULL, int ZAdjust = 0, int* lpXCenterZMax = NULL, int* lpYCenterZMax = NULL, int i3dCenterX = -1, int i3dCenterY = -1); +#endif // modelOffset is applied before VXL/HVA translates and scales and before model-to-world rotation BOOL LoadVXLImage(const VoxelNormalTables& normalTables,