Implement full screen (#290)

This commit is contained in:
Anders Jenbo 2025-06-12 22:51:52 +02:00 committed by GitHub
parent d3378026ba
commit bbb0de6e9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 70 additions and 11 deletions

View File

@ -88,7 +88,7 @@ IsleApp::IsleApp()
m_cdPath = NULL;
m_deviceId = NULL;
m_savePath = NULL;
m_fullScreen = FALSE;
m_fullScreen = TRUE;
m_flipSurfaces = FALSE;
m_backBuffersInVram = TRUE;
m_using8bit = FALSE;
@ -355,9 +355,19 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
// [library:window]
// Remaining functionality to be implemented:
// Full screen - crashes when minimizing/maximizing, but this will probably be fixed once DirectDraw is replaced
// WM_TIMER - use SDL_Timer functionality instead
switch (event->type) {
case SDL_EVENT_MOUSE_MOTION:
case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_EVENT_MOUSE_BUTTON_UP:
IDirect3DRMMiniwinDevice* device = GetD3DRMMiniwinDevice();
if (device && !device->ConvertEventToRenderCoordinates(event)) {
SDL_Log("Failed to convert event coordinates: %s", SDL_GetError());
}
break;
}
switch (event->type) {
case SDL_EVENT_WINDOW_FOCUS_GAINED:
if (!IsleDebug_Enabled()) {

View File

@ -3,6 +3,7 @@
DEFINE_GUID(IID_IDirect3DRMMiniwinDevice, 0x6eb09673, 0x8d30, 0x4d8a, 0x8d, 0x81, 0x34, 0xea, 0x69, 0x30, 0x12, 0x01);
struct IDirect3DRMMiniwinDevice : virtual public IUnknown {
virtual bool ConvertEventToRenderCoordinates(SDL_Event* event) = 0;
virtual float GetShininessFactor() = 0;
virtual HRESULT SetShininessFactor(float factor) = 0;
};

View File

@ -144,6 +144,11 @@ float Direct3DRMDevice2Impl::GetShininessFactor()
return m_renderer->GetShininessFactor();
}
bool Direct3DRMDevice2Impl::ConvertEventToRenderCoordinates(SDL_Event* event)
{
return m_renderer->ConvertEventToRenderCoordinates(event);
}
HRESULT Direct3DRMDevice2Impl::SetShininessFactor(float factor)
{
return m_renderer->SetShininessFactor(factor);

View File

@ -17,6 +17,9 @@
SDL_Window* DDWindow;
SDL_Surface* DDBackBuffer;
SDL_Texture* HWBackBuffer;
SDL_PixelFormat HWBackBufferFormat;
SDL_Renderer* DDRenderer;
HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject)
{
@ -296,6 +299,8 @@ HRESULT DirectDrawImpl::SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags)
return DDERR_GENERIC;
}
DDWindow = sdlWindow;
DDRenderer = SDL_CreateRenderer(DDWindow, NULL);
SDL_SetRenderLogicalPresentation(DDRenderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX);
}
return DD_OK;
}

View File

@ -55,6 +55,31 @@ static SDL_Rect ConvertRect(const RECT* r)
return {r->left, r->top, r->right - r->left, r->bottom - r->top};
}
bool SetupHWBackBuffer()
{
HWBackBuffer = SDL_CreateTextureFromSurface(DDRenderer, DDBackBuffer);
if (!HWBackBuffer) {
return false;
}
SDL_PropertiesID props = SDL_GetTextureProperties(HWBackBuffer);
if (!props) {
SDL_DestroyTexture(HWBackBuffer);
HWBackBuffer = nullptr;
return false;
}
HWBackBufferFormat =
(SDL_PixelFormat) SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_FORMAT_NUMBER, SDL_PIXELFORMAT_UNKNOWN);
if (HWBackBufferFormat == SDL_PIXELFORMAT_UNKNOWN) {
SDL_DestroyTexture(HWBackBuffer);
HWBackBuffer = nullptr;
return false;
}
return true;
}
HRESULT DirectDrawSurfaceImpl::Blt(
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
@ -69,6 +94,9 @@ HRESULT DirectDrawSurfaceImpl::Blt(
}
if (m_autoFlip) {
DDBackBuffer = srcSurface->m_surface;
if (!HWBackBuffer && !SetupHWBackBuffer()) {
return DDERR_GENERIC;
}
return Flip(nullptr, DDFLIP_WAIT);
}
@ -126,18 +154,15 @@ HRESULT DirectDrawSurfaceImpl::BltFast(
HRESULT DirectDrawSurfaceImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags)
{
if (!DDBackBuffer) {
if (!DDBackBuffer || !DDRenderer) {
return DDERR_GENERIC;
}
SDL_Surface* windowSurface = SDL_GetWindowSurface(DDWindow);
if (!windowSurface) {
return DDERR_GENERIC;
}
SDL_Rect srcRect{0, 0, DDBackBuffer->w, DDBackBuffer->h};
SDL_Surface* copy = SDL_ConvertSurface(DDBackBuffer, windowSurface->format);
SDL_BlitSurface(copy, &srcRect, windowSurface, &srcRect);
SDL_Surface* copy = SDL_ConvertSurface(DDBackBuffer, HWBackBufferFormat);
SDL_UpdateTexture(HWBackBuffer, nullptr, copy->pixels, copy->pitch);
SDL_DestroySurface(copy);
SDL_UpdateWindowSurface(DDWindow);
SDL_RenderTexture(DDRenderer, HWBackBuffer, nullptr, nullptr);
SDL_RenderPresent(DDRenderer);
return DD_OK;
}
@ -147,6 +172,9 @@ HRESULT DirectDrawSurfaceImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTD
return DDERR_INVALIDPARAMS;
}
DDBackBuffer = m_surface;
if (!SetupHWBackBuffer()) {
return DDERR_GENERIC;
}
*lplpDDAttachedSurface = static_cast<IDirectDrawSurface*>(this);
return DD_OK;
}

View File

@ -33,6 +33,7 @@ struct Direct3DRMDevice2Impl : public Direct3DRMObjectBaseImpl<IDirect3DRMDevice
HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) override;
// IDirect3DRMMiniwinDevice interface
bool ConvertEventToRenderCoordinates(SDL_Event* event) override;
float GetShininessFactor() override;
HRESULT SetShininessFactor(float factor) override;

View File

@ -31,6 +31,8 @@ struct SceneLight {
};
static_assert(sizeof(SceneLight) == 48);
extern SDL_Renderer* DDRenderer;
class Direct3DRMRenderer : public IDirect3DDevice2 {
public:
virtual void PushLights(const SceneLight* vertices, size_t count) = 0;
@ -51,6 +53,10 @@ class Direct3DRMRenderer : public IDirect3DDevice2 {
) = 0;
virtual HRESULT FinalizeFrame() = 0;
bool ConvertEventToRenderCoordinates(SDL_Event* event)
{
return SDL_ConvertEventToRenderCoordinates(DDRenderer, event);
}
float GetShininessFactor() { return m_shininessFactor; }
HRESULT SetShininessFactor(float factor)
{

View File

@ -8,6 +8,9 @@
extern SDL_Window* DDWindow;
extern SDL_Surface* DDBackBuffer;
extern SDL_Texture* HWBackBuffer;
extern SDL_PixelFormat HWBackBufferFormat;
extern SDL_Renderer* DDRenderer;
struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
// IUnknown interface