From 2c4aaec387ffe0eb60f92a027539195993b6408f Mon Sep 17 00:00:00 2001 From: Aki Date: Wed, 23 Mar 2022 21:45:22 +0100 Subject: Moved Video methods to GameWinDX9 --- Stars45/GameWinDX9.cpp | 264 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) (limited to 'Stars45/GameWinDX9.cpp') diff --git a/Stars45/GameWinDX9.cpp b/Stars45/GameWinDX9.cpp index d670351..cc86769 100644 --- a/Stars45/GameWinDX9.cpp +++ b/Stars45/GameWinDX9.cpp @@ -9,13 +9,18 @@ #include #include +#include "Bitmap.h" #include "Color.h" #include "DataLoader.h" #include "Game.h" #include "MachineInfo.h" +#include "MemDebug.h" #include "Panic.h" +#include "Screen.h" #include "Types.h" #include "Utils.h" +#include "VideoFactory.h" +#include "Video.h" GameWinDX9* GameWinDX9::instance = nullptr; @@ -223,11 +228,270 @@ GameWinDX9::InitGame() return false; } Print(" Palette laoded\n"); + if (!InitVideo() || !video || video->Status() != Video::VIDEO_OK) { + Panic::Panic("Could not create the Video Interface"); + return false; + } + Print(" Created video object.\n"); + Color::UseVideo(video); + screen = new(__FILE__, __LINE__) Screen(video); + if (!screen) { + Panic::Panic("Could not create the Screen object."); + return false; + } + Print(" Created screen object.\n"); + if (!screen->SetBackgroundColor(Color::Black)) + Print(" WARNING: Could not set video background color to Black.\n"); + screen->ClearAllFrames(true); + Print("Established requested video parameters.\n\n"); return Game::InitGame(); } bool +GameWinDX9::InitVideo() +{ + if (server) return true; + + // create a video factory, and video object: + video_factory = new(__FILE__,__LINE__) VideoFactory(hwnd); + + if (video_factory) { + Print(" Init Video...\n"); + Print(" Request %s mode\n", video_settings->GetModeDescription()); + + video = video_factory->CreateVideo(video_settings); + + if (video) { + if (!video->IsHardware()) { + video_factory->DestroyVideo(video); + video = 0; + + Panic::Panic("3D Hardware Not Found"); + } + + // save a copy of the device-specific video settings: + else if (video->GetVideoSettings()) { + *video_settings = *video->GetVideoSettings(); + is_windowed = video_settings->IsWindowed(); + } + } + + soundcard = video_factory->CreateSoundCard(); + } + + return (video && video->Status() == Video::VIDEO_OK); +} + + +bool +GameWinDX9::ResetVideo() +{ + if (server) return true; + if (!video_factory) return InitVideo(); + + Print(" Reset Video...\n"); + Print(" Request %s mode\n", video_settings->GetModeDescription()); + + delete screen; + + if (video && !video->Reset(video_settings)) { + video_factory->DestroyVideo(video); + video = video_factory->CreateVideo(video_settings); + } + + if (!video || video->Status() != Video::VIDEO_OK) { + Panic::Panic("Could not re-create Video Interface."); + return false; + } + + Print(" Re-created video object.\n"); + + // save a copy of the device-specific video settings: + if (video->GetVideoSettings()) { + *video_settings = *video->GetVideoSettings(); + is_windowed = video_settings->IsWindowed(); + } + + Color::UseVideo(video); + + screen = new(__FILE__,__LINE__) Screen(video); + if (!screen) { + Panic::Panic("Could not re-create Screen object."); + return false; + } + + Print(" Re-created screen object.\n"); + + if (!screen->SetBackgroundColor(Color::Black)) + Print(" WARNING: could not set video background color to Black\n"); + + screen->ClearAllFrames(true); + + Print(" Re-established requested video parameters.\n"); + + Bitmap::CacheUpdate(); + Print(" Refreshed texture bitmaps.\n\n"); + return true; +} + + +bool +GameWinDX9::ResizeVideo() +{ + if (!video || !video_settings) return false; + if (!is_windowed) return false; + if (ignore_size_change) return true; + + HRESULT hr = S_OK; + RECT client_old; + + client_old = client_rect; + + // Update window properties + GetWindowRect(hwnd, &bounds_rect); + GetClientRect(hwnd, &client_rect); + + if (client_old.right - client_old.left != + client_rect.right - client_rect.left || + client_old.bottom - client_old.top != + client_rect.bottom - client_rect.top) { + + // A new window size will require a new backbuffer + // size, so the 3D structures must be changed accordingly. + Pause(true); + + video_settings->is_windowed = true; + video_settings->window_width = client_rect.right - client_rect.left; + video_settings->window_height = client_rect.bottom - client_rect.top; + + ::Print("ResizeVideo() %d x %d\n", video_settings->window_width, video_settings->window_height); + + if (video) { + video->Reset(video_settings); + } + + Pause(false); + } + + // save a copy of the device-specific video settings: + if (video->GetVideoSettings()) { + *video_settings = *video->GetVideoSettings(); + is_windowed = video_settings->IsWindowed(); + } + + screen->Resize(video_settings->window_width, video_settings->window_height); + + return hr == S_OK; +} + + +bool +GameWinDX9::ToggleFullscreen() +{ + bool result = false; + + if (video && video_settings) { + Pause(true); + ignore_size_change = true; + + // Toggle the windowed state + is_windowed = !is_windowed; + video_settings->is_windowed = is_windowed; + + // Prepare window for windowed/fullscreen change + AdjustWindowForChange(); + + // Reset the 3D device + if (!video->Reset(video_settings)) { + // reset failed, try to restore... + ignore_size_change = false; + + if (!is_windowed) { + // Restore window type to windowed mode + is_windowed = !is_windowed; + video_settings->is_windowed = is_windowed; + + AdjustWindowForChange(); + + SetWindowPos(hwnd, + HWND_NOTOPMOST, + bounds_rect.left, + bounds_rect.top, + bounds_rect.right - bounds_rect.left, + bounds_rect.bottom - bounds_rect.top, + SWP_SHOWWINDOW); + } + + ::Print("Unable to toggle %s fullscreen mode.\n", is_windowed ? "into" : "out of"); + } + + else { + ignore_size_change = false; + + // When moving from fullscreen to windowed mode, it is important to + // adjust the window size after resetting the device rather than + // beforehand to ensure that you get the window size you want. For + // example, when switching from 640x480 fullscreen to windowed with + // a 1000x600 window on a 1024x768 desktop, it is impossible to set + // the window size to 1000x600 until after the display mode has + // changed to 1024x768, because windows cannot be larger than the + // desktop. + + if (is_windowed) { + SetWindowPos(hwnd, + HWND_NOTOPMOST, + bounds_rect.left, + bounds_rect.top, + bounds_rect.right - bounds_rect.left, + bounds_rect.bottom - bounds_rect.top, + SWP_SHOWWINDOW); + } + + GetClientRect(hwnd, &client_rect); // Update our copy + Pause(false); + + if (is_windowed) + screen->Resize(video_settings->window_width, + video_settings->window_height); + + else + screen->Resize(video_settings->fullscreen_mode.width, + video_settings->fullscreen_mode.height); + + result = true; + } + } + + return result; +} + + +bool +GameWinDX9::AdjustWindowForChange() +{ + if (is_windowed) { + // Set windowed-mode style + SetWindowLong(hwnd, GWL_STYLE, window_style); + if (hmenu != NULL) { + SetMenu(hwnd, hmenu); + hmenu = NULL; + } + } + else { + // Set fullscreen-mode style + SetWindowLong(hwnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE); + if (hmenu == NULL) { + hmenu = GetMenu(hwnd); + SetMenu(hwnd, NULL); + } + } + + return true; +} + + +bool GameWinDX9::SetupPalette() { if (LoadPalette(standard_palette, inverse_palette)) { -- cgit v1.1