From 658b2f697280d00a329033165508dd875fc4cbf1 Mon Sep 17 00:00:00 2001 From: Mathieu Schroeter Date: Mon, 23 Jan 2017 00:20:27 +0100 Subject: [PATCH] WIP: add experimental SDL support for video output --- blupi.cpp | 2 + blupi.h | 5 ++ pixmap.cpp | 142 +++++++++++++++++++++++++++++++++++- pixmap.h | 8 +- planetblupi.vcxproj | 1 + planetblupi.vcxproj.filters | 3 + 6 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 blupi.h diff --git a/blupi.cpp b/blupi.cpp index 914cf5b..7ae13d4 100644 --- a/blupi.cpp +++ b/blupi.cpp @@ -1,6 +1,8 @@ // blupi.cpp // +#include "blupi.h" + #define WIN32_LEAN_AND_MEAN #define SDL_MAIN_HANDLED diff --git a/blupi.h b/blupi.h new file mode 100644 index 0000000..44abe3b --- /dev/null +++ b/blupi.h @@ -0,0 +1,5 @@ +#pragma once + +struct SDL_Window; + +extern SDL_Window *g_window; diff --git a/pixmap.cpp b/pixmap.cpp index 8a3ce6d..52f2740 100644 --- a/pixmap.cpp +++ b/pixmap.cpp @@ -3,11 +3,17 @@ #include #include +#include +#include #include +#include +#include +#include #include "def.h" #include "pixmap.h" #include "misc.h" #include "ddutil.h" +#include "blupi.h" @@ -188,6 +194,33 @@ bool CPixmap::Create(HWND hwnd, POINT dim, OutputDebug("Fatal error: CreateSurface\n"); return false; } + + /* Create a 32-bit surface with the bytes of each pixel in R,G,B,A order, + as expected by OpenGL for textures */ + Uint32 rmask, gmask, bmask, amask; + + /* SDL interprets each pixel as a 32-bit number, so our masks must depend + on the endianness (byte order) of the machine */ +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + + /*m_lpSDLPrimary = SDL_CreateRGBSurface (0, dim.x, dim.y, 32, + rmask, gmask, bmask, amask); + if (m_lpSDLPrimary == NULL) + { + SDL_Log ("SDL_CreateRGBSurfaceWithFormat() failed: %s", SDL_GetError ()); + return false; + }*/ + m_lpSDLPrimary = SDL_GetWindowSurface (g_window); // Create the back buffer. ZeroMemory(&ddsd, sizeof(ddsd)); @@ -206,6 +239,14 @@ bool CPixmap::Create(HWND hwnd, POINT dim, return false; } + m_lpSDLBack = SDL_CreateRGBSurface (0, dim.x, dim.y, 32, + rmask, gmask, bmask, amask); + if (m_lpSDLBack == NULL) + { + SDL_Log ("SDL_CreateRGBSurfaceWithFormat() failed: %s", SDL_GetError ()); + return false; + } + // Create the mouse buffer. ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -223,6 +264,14 @@ bool CPixmap::Create(HWND hwnd, POINT dim, return false; } + m_lpSDLMouse = SDL_CreateRGBSurface (0, DIMBLUPIX, DIMBLUPIY, 32, + rmask, gmask, bmask, amask); + if (m_lpSDLMouse == NULL) + { + SDL_Log ("SDL_CreateRGBSurfaceWithFormat() failed: %s", SDL_GetError ()); + return false; + } + // Create a DirectDrawClipper object. The object enables clipping to the // window boundaries in the IDirectDrawSurface::Blt function for the // primary surface. @@ -391,15 +440,34 @@ HRESULT CPixmap::BltFast(int chDst, int channel, { if ( chDst < 0 ) { + SDL_Rect srcRect, dstRect; + srcRect.x = rcRect.left; + srcRect.y = rcRect.top; + srcRect.w = rcRect.right - rcRect.left; + srcRect.h = rcRect.bottom - rcRect.top; + dstRect = srcRect; + dstRect.x = dst.x; + dstRect.y = dst.y; + SDL_BlitSurface (m_lpSDLSurface[channel], &srcRect, m_lpSDLBack, &dstRect); ddrval = m_lpDDSBack->BltFast(dst.x, dst.y, m_lpDDSurface[channel], &rcRect, dwTrans); + } else { ddrval = m_lpDDSurface[chDst]->BltFast(dst.x, dst.y, m_lpDDSurface[channel], &rcRect, dwTrans); + SDL_Rect srcRect, dstRect; + srcRect.x = rcRect.left; + srcRect.y = rcRect.top; + srcRect.w = rcRect.right - rcRect.left; + srcRect.h = rcRect.bottom - rcRect.top; + dstRect = srcRect; + dstRect.x = dst.x; + dstRect.y = dst.y; + SDL_BlitSurface (m_lpSDLSurface[channel], &srcRect, m_lpSDLSurface[chDst], &dstRect); } if ( ddrval == DD_OK ) break; @@ -418,7 +486,7 @@ HRESULT CPixmap::BltFast(int chDst, int channel, // Effectue un appel BltFast. // Les modes sont 0=transparent, 1=opaque. -HRESULT CPixmap::BltFast(LPDIRECTDRAWSURFACE lpDD, +HRESULT CPixmap::BltFast(LPDIRECTDRAWSURFACE lpDD, SDL_Surface *lpSDL, int channel, POINT dst, RECT rcRect, int mode) { DWORD dwTrans; @@ -432,6 +500,15 @@ HRESULT CPixmap::BltFast(LPDIRECTDRAWSURFACE lpDD, ddrval = lpDD->BltFast(dst.x, dst.y, m_lpDDSurface[channel], &rcRect, dwTrans); + SDL_Rect srcRect, dstRect; + srcRect.x = rcRect.left; + srcRect.y = rcRect.top; + srcRect.w = rcRect.right - rcRect.left; + srcRect.h = rcRect.bottom - rcRect.top; + dstRect = srcRect; + dstRect.x = dst.x; + dstRect.y = dst.y; + SDL_BlitSurface (m_lpSDLSurface[channel], &srcRect, lpSDL, &dstRect); if ( ddrval == DD_OK ) break; if ( ddrval == DDERR_SURFACELOST ) @@ -590,6 +667,11 @@ bool CPixmap::Cache(int channel, char *pFilename, POINT totalDim, POINT iconDim, // Create the offscreen surface, by loading our bitmap. m_lpDDSurface[channel] = DDLoadBitmap(m_lpDD, pFilename, 0, 0); + std::string file = pFilename; + if (_access ((file + ".bmp").c_str (), 0 /* F_OK */) != -1) + file += ".bmp"; + m_lpSDLSurface[channel] = SDL_LoadBMP (file.c_str ()); + if ( m_lpDDSurface[channel] == NULL ) { @@ -938,7 +1020,7 @@ bool CPixmap::BuildIconMask(int channelMask, int rankMask, rect.bottom = rect.top + m_iconDim[channel].y; posDst.x = (rankDst%nbx)*m_iconDim[channel].x; posDst.y = (rankDst/nbx)*m_iconDim[channel].y; - ddrval = BltFast(m_lpDDSurface[channel], channel, posDst, rect, 1); + ddrval = BltFast(m_lpDDSurface[channel], m_lpSDLSurface[channel], channel, posDst, rect, 1); if ( ddrval != DD_OK ) return false; if ( m_iconDim[channelMask].x == 0 || @@ -953,7 +1035,7 @@ bool CPixmap::BuildIconMask(int channelMask, int rankMask, rect.top = (rankMask/nbx)*m_iconDim[channelMask].y; rect.right = rect.left + m_iconDim[channelMask].x; rect.bottom = rect.top + m_iconDim[channelMask].y; - ddrval = BltFast(m_lpDDSurface[channel], channelMask, posDst, rect, 0); + ddrval = BltFast(m_lpDDSurface[channel], m_lpSDLSurface[channel], channelMask, posDst, rect, 0); if ( ddrval != DD_OK ) return false; return true; @@ -989,6 +1071,30 @@ bool CPixmap::Display() DDBLT_WAIT, &m_DDbltfx ); + /*SDL_Rect srcRect, dstRect; + srcRect.x = MapRect.left; + srcRect.y = MapRect.top; + srcRect.w = MapRect.right - MapRect.left; + srcRect.h = MapRect.bottom - MapRect.top; + dstRect.x = DestRect.left; + dstRect.y = DestRect.top; + dstRect.w = DestRect.right - DestRect.left; + dstRect.h = DestRect.bottom - DestRect.top; + SDL_BlitSurface (m_lpSDLPrimary, &srcRect, m_lpSDLBack, &dstRect);*/ + + /* + * Copies the bmp surface to the window surface + */ + SDL_BlitSurface (m_lpSDLBack, + NULL, + m_lpSDLPrimary, + NULL); + + /* + * Now updating the window + */ + SDL_UpdateWindowSurface (g_window); + if ( ddrval == DDERR_SURFACELOST ) { ddrval = RestoreAll(); @@ -1120,6 +1226,16 @@ bool CPixmap::MouseQuickDraw(RECT rect) DDBLT_WAIT, &m_DDbltfx ); + SDL_Rect srcRect, dstRect; + srcRect.x =rect.left; + srcRect.y =rect.top; + srcRect.w =rect.right - rect.left; + srcRect.h =rect.bottom - rect.top; + dstRect.x = DestRect.left; + dstRect.y = DestRect.top; + dstRect.w = DestRect.right - DestRect.left; + dstRect.h = DestRect.bottom - DestRect.top; + SDL_BlitSurface (m_lpSDLPrimary, &srcRect, m_lpSDLBack, &dstRect); if ( ddrval == DDERR_SURFACELOST ) { ddrval = RestoreAll(); @@ -1181,7 +1297,7 @@ void CPixmap::MouseBackDraw() } // Dessine le lutin dans m_lpDDSBack. - BltFast(m_lpDDSBack, CHBLUPI, dst, rcRect, 0); + BltFast(m_lpDDSBack, m_lpSDLBack, CHBLUPI, dst, rcRect, 0); } // Sauve le fond sous la souris. @@ -1234,6 +1350,15 @@ void CPixmap::MouseBackSave() ddrval = m_lpDDSMouse->BltFast(dst.x, dst.y, m_lpDDSBack, &rcRect, DDBLTFAST_NOCOLORKEY); + SDL_Rect srcRect, dstRect; + srcRect.x = rcRect.left; + srcRect.y = rcRect.top; + srcRect.w = rcRect.right - rcRect.left; + srcRect.h = rcRect.bottom - rcRect.top; + dstRect = srcRect; + dstRect.x = dst.x; + dstRect.y = dst.y; + SDL_BlitSurface (m_lpSDLBack, &srcRect, m_lpSDLMouse, &dstRect); if ( ddrval == DD_OK ) break; if ( ddrval == DDERR_SURFACELOST ) @@ -1290,6 +1415,15 @@ void CPixmap::MouseBackRestore() ddrval = m_lpDDSBack->BltFast(dst.x, dst.y, m_lpDDSMouse, &rcRect, DDBLTFAST_NOCOLORKEY); + SDL_Rect srcRect, dstRect; + srcRect.x = rcRect.left; + srcRect.y = rcRect.top; + srcRect.w = rcRect.right - rcRect.left; + srcRect.h = rcRect.bottom - rcRect.top; + dstRect = srcRect; + dstRect.x = dst.x; + dstRect.y = dst.y; + SDL_BlitSurface (m_lpSDLMouse, &srcRect, m_lpSDLBack, &dstRect); if ( ddrval == DD_OK ) break; if ( ddrval == DDERR_SURFACELOST ) diff --git a/pixmap.h b/pixmap.h index b93152d..d4d40aa 100644 --- a/pixmap.h +++ b/pixmap.h @@ -3,12 +3,12 @@ #pragma once #include +#include ///////////////////////////////////////////////////////////////////////////// #define MAXIMAGE 100 - class CPixmap { public: @@ -60,7 +60,7 @@ public: protected: HRESULT RestoreAll(); HRESULT BltFast(int chDst, int channel, POINT dst, RECT rcRect, int mode); - HRESULT BltFast(LPDIRECTDRAWSURFACE lpDD, + HRESULT BltFast(LPDIRECTDRAWSURFACE lpDD, SDL_Surface *lpSDL, int channel, POINT dst, RECT rcRect, int mode); void MouseUpdate(); @@ -90,10 +90,14 @@ protected: LPDIRECTDRAW m_lpDD; // DirectDraw object LPDIRECTDRAWSURFACE m_lpDDSPrimary; // DirectDraw primary surface + SDL_Surface * m_lpSDLPrimary; LPDIRECTDRAWSURFACE m_lpDDSBack; // DirectDraw back surface + SDL_Surface * m_lpSDLBack; LPDIRECTDRAWSURFACE m_lpDDSMouse; // DirectDraw back surface + SDL_Surface * m_lpSDLMouse; LPDIRECTDRAWPALETTE m_lpDDPal; // the primary surface palette LPDIRECTDRAWSURFACE m_lpDDSurface[MAXIMAGE]; // offscreen surfaces + SDL_Surface * m_lpSDLSurface[MAXIMAGE]; LPDIRECTDRAWCLIPPER m_lpClipper; PALETTEENTRY m_pal[256]; // sauvegarde palette PALETTEENTRY m_sysPal[256]; // sauvegarde palette diff --git a/planetblupi.vcxproj b/planetblupi.vcxproj index 733ae83..7e9e567 100644 --- a/planetblupi.vcxproj +++ b/planetblupi.vcxproj @@ -186,6 +186,7 @@ + diff --git a/planetblupi.vcxproj.filters b/planetblupi.vcxproj.filters index 1496f0f..f6a2d37 100644 --- a/planetblupi.vcxproj.filters +++ b/planetblupi.vcxproj.filters @@ -151,6 +151,9 @@ Sources + + Sources +