mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2026-05-12 18:29:37 -06:00
Hardware rendering
- Use SDL_Texture and SDL_Render to for DibBitmap and Display operations - SubBitmap class was created to handle suballocating dibs since the old method required direct pixel access - Font buffer is no longer used. Back buffer is forced valid and drawn to the screen.
This commit is contained in:
parent
8619337473
commit
24eba15f59
172
game/SimUI.cpp
172
game/SimUI.cpp
@ -2413,7 +2413,7 @@ bool MiniMapControl::Init(Form *pfrm, IniReader *pini, FindProp *pfind)
|
||||
dword *pbtd = (dword *)(pmtseth + 1);
|
||||
m_pbTileData = new dword[pmtseth->cTiles];
|
||||
for (int i = 0; i < pmtseth->cTiles; i++, pbtd++) {
|
||||
m_pbTileData[i] = BigDword(*pbtd);
|
||||
m_pbTileData[i] = *pbtd;
|
||||
}
|
||||
|
||||
// Calc powered radar flag
|
||||
@ -2706,9 +2706,9 @@ void MiniMapControl::RedrawTRect(TRect *ptrc)
|
||||
|
||||
// Redraw this rect
|
||||
|
||||
dword *pbDst = m_pbm->GetBits() + (long)ptrc->top * m_cbRowBytes * m_nScale +
|
||||
ptrc->left * m_nScale + (long)m_yOff * m_cbRowBytes + m_xOff;
|
||||
int cbDstReturn = m_cbRowBytes - ptrc->Width() * m_nScale;
|
||||
Rect rc;
|
||||
rc.Set(m_xOff, m_yOff, ptrc->Width(), ptrc->Height());
|
||||
DibBitmap *pbmDst = m_pbm->Suballoc(rc);
|
||||
long offset = (long)ptrc->top * m_ctx + ptrc->left;
|
||||
byte *pbFogMap = m_pbFogMap + offset;
|
||||
word *pwTileMap = m_pwTileMap + offset;
|
||||
@ -2716,138 +2716,62 @@ void MiniMapControl::RedrawTRect(TRect *ptrc)
|
||||
int ctReturn = m_ctx - ptrc->Width();
|
||||
|
||||
#define HasWall(btt) ((btt) == kttWall)
|
||||
for (TCoord ty = ptrc->top; ty < ptrc->bottom; ty++) {
|
||||
for (TCoord tx = ptrc->left; tx < ptrc->right; tx++, pbFogMap++, pwTileMap++, pbTrMap++) {
|
||||
// Fogged?
|
||||
|
||||
if (m_nScale == 1) {
|
||||
for (TCoord ty = ptrc->top; ty < ptrc->bottom; ty++) {
|
||||
for (TCoord tx = ptrc->left; tx < ptrc->right; tx++, pbFogMap++, pwTileMap++, pbTrMap++) {
|
||||
// Fogged?
|
||||
if (IsFogOpaque(*pbFogMap)) {
|
||||
pbmDst->Fill(tx * m_nScale, ty * m_nScale, m_nScale, m_nScale, m_clrBlack);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsFogOpaque(*pbFogMap)) {
|
||||
*pbDst++ = m_clrBlack;
|
||||
continue;
|
||||
}
|
||||
// Not fogged; remember to redraw the minimap to the screen next timer
|
||||
|
||||
// Not fogged; remember to redraw the minimap to the screen next timer
|
||||
m_wfMm |= kfMmRedraw;
|
||||
|
||||
m_wfMm |= kfMmRedraw;
|
||||
// Unit gob?
|
||||
|
||||
// Unit gob?
|
||||
UnitGob *punt = ggobm.GetUnitGob(tx, ty);
|
||||
if (punt != NULL) {
|
||||
dword wf = punt->GetFlags();
|
||||
if ((wf & (kfGobMobileUnit | kfGobActive)) != (kfGobMobileUnit)) {
|
||||
Color clr;
|
||||
if (wf & kfGobSelected) {
|
||||
clr = m_clrWhite;
|
||||
} else {
|
||||
clr = m_aclrSide[punt->GetSide()];
|
||||
}
|
||||
|
||||
UnitGob *punt = ggobm.GetUnitGob(tx, ty);
|
||||
pbmDst->Fill(tx * m_nScale, ty * m_nScale, m_nScale, m_nScale, clr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// don't show inactive munts
|
||||
// Wall?
|
||||
|
||||
if (punt != NULL) {
|
||||
dword wf = punt->GetFlags();
|
||||
if ((wf & (kfGobMobileUnit | kfGobActive)) != (kfGobMobileUnit)) {
|
||||
if (wf & kfGobSelected) {
|
||||
*pbDst++ = m_clrWhite;
|
||||
} else {
|
||||
*pbDst++ = m_aclrSide[punt->GetSide()];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (HasWall(*pbTrMap)) {
|
||||
pbmDst->Fill(tx * m_nScale, ty * m_nScale, m_nScale, m_nScale, m_clrWall);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Wall?
|
||||
// Galaxite?
|
||||
|
||||
if (HasWall(*pbTrMap)) {
|
||||
*pbDst++ = m_clrWall;
|
||||
continue;
|
||||
}
|
||||
if (HasGalaxite(*pbFogMap)) {
|
||||
pbmDst->Fill(tx * m_nScale, ty * m_nScale, m_nScale, m_nScale, m_clrGalaxite);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Galaxite?
|
||||
// Tile
|
||||
|
||||
if (HasGalaxite(*pbFogMap)) {
|
||||
*pbDst++ = m_clrGalaxite;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Tile
|
||||
|
||||
int nTile = (BigWord(*pwTileMap) & 0x7fc);
|
||||
*pbDst++ = m_pbTileData[nTile >> 2];
|
||||
continue;
|
||||
}
|
||||
pwTileMap += ctReturn;
|
||||
pbFogMap += ctReturn;
|
||||
pbTrMap += ctReturn;
|
||||
pbDst += cbDstReturn;
|
||||
}
|
||||
} else if (m_nScale == 2) {
|
||||
for (TCoord ty = ptrc->top; ty < ptrc->bottom; ty++) {
|
||||
for (TCoord tx = ptrc->left; tx < ptrc->right; tx++, pbFogMap++, pwTileMap++, pbTrMap++) {
|
||||
// Fogged?
|
||||
|
||||
if (IsFogOpaque(*pbFogMap)) {
|
||||
*pbDst++ = m_clrBlack;
|
||||
*pbDst++ = m_clrBlack;
|
||||
*(pbDst + m_cbRowBytes - 2) = m_clrBlack;
|
||||
*(pbDst + m_cbRowBytes - 1) = m_clrBlack;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not fogged; remember to redraw the minimap to the screen next timer
|
||||
|
||||
m_wfMm |= kfMmRedraw;
|
||||
|
||||
// Unit gob?
|
||||
|
||||
UnitGob *punt = ggobm.GetUnitGob(tx, ty);
|
||||
if (punt != NULL) {
|
||||
dword wf = punt->GetFlags();
|
||||
if ((wf & (kfGobMobileUnit | kfGobActive)) != (kfGobMobileUnit)) {
|
||||
dword clr;
|
||||
if (wf & kfGobSelected) {
|
||||
clr = m_clrWhite;
|
||||
} else {
|
||||
clr = m_aclrSide[punt->GetSide()];
|
||||
}
|
||||
|
||||
*pbDst++ = clr;
|
||||
*pbDst++ = clr;
|
||||
*(pbDst + m_cbRowBytes - 2) = clr;
|
||||
*(pbDst + m_cbRowBytes - 1) = clr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Wall?
|
||||
|
||||
if (HasWall(*pbTrMap)) {
|
||||
*pbDst++ = m_clrWall;
|
||||
*pbDst++ = m_clrWall;
|
||||
*(pbDst + m_cbRowBytes - 2) = m_clrWall;
|
||||
*(pbDst + m_cbRowBytes - 1) = m_clrWall;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Galaxite?
|
||||
|
||||
if (HasGalaxite(*pbFogMap)) {
|
||||
*pbDst++ = m_clrGalaxite;
|
||||
*pbDst++ = m_clrGalaxite;
|
||||
*(pbDst + m_cbRowBytes - 2) = m_clrGalaxite;
|
||||
*(pbDst + m_cbRowBytes - 1) = m_clrGalaxite;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Tile
|
||||
|
||||
int nTile = (BigWord(*pwTileMap) & 0x7fc);
|
||||
dword pbSrc = m_pbTileData[nTile];
|
||||
*pbDst++ = pbSrc;
|
||||
*pbDst++ = pbSrc;
|
||||
*(pbDst + m_cbRowBytes - 2) = pbSrc;
|
||||
*(pbDst + m_cbRowBytes - 1) = pbSrc;
|
||||
continue;
|
||||
}
|
||||
pwTileMap += ctReturn;
|
||||
pbFogMap += ctReturn;
|
||||
pbTrMap += ctReturn;
|
||||
pbDst += cbDstReturn + m_cbRowBytes;
|
||||
}
|
||||
}
|
||||
int nTile = (BigWord(*pwTileMap) & 0x7fc);
|
||||
dword pbSrc = m_pbTileData[m_nScale == 1 ? nTile >> 2 : nTile];
|
||||
pbmDst->Fill(tx * m_nScale, ty * m_nScale, m_nScale, m_nScale, pbSrc);
|
||||
continue;
|
||||
}
|
||||
pwTileMap += ctReturn;
|
||||
pbFogMap += ctReturn;
|
||||
pbTrMap += ctReturn;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wi
|
||||
|
||||
300
game/bitmap.cpp
300
game/bitmap.cpp
@ -3,12 +3,7 @@
|
||||
#if defined(SDL)
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
|
||||
#define SURFACE_FLAGS 0
|
||||
#define SURFACE_DEPTH 32
|
||||
#define SURFACE_PITCH(x) x*4 // row length in bytes: x*sizeof(byte)*sizeof(dword)
|
||||
#define SHADOW_ALPHA_MOD 100
|
||||
#endif // defined(SDL)
|
||||
#endif
|
||||
|
||||
namespace wi {
|
||||
|
||||
@ -16,21 +11,23 @@ namespace wi {
|
||||
|
||||
DibBitmap::DibBitmap()
|
||||
{
|
||||
m_surface = NULL;
|
||||
m_texture = NULL;
|
||||
m_ppfmt = NULL;
|
||||
m_wf = 0;
|
||||
m_pszFn = NULL;
|
||||
m_renderer = NULL;
|
||||
m_cx = 0;
|
||||
m_cy = 0;
|
||||
}
|
||||
|
||||
DibBitmap::~DibBitmap()
|
||||
{
|
||||
SDL_DestroyRenderer(m_renderer);
|
||||
SDL_FreeSurface(m_surface);
|
||||
if (m_wf & kfDibFreeMem)
|
||||
free(m_surface->pixels);
|
||||
m_surface = NULL;
|
||||
if (m_pszFn != NULL)
|
||||
delete[] m_pszFn;
|
||||
if (m_texture) {
|
||||
SDL_DestroyTexture(m_texture);
|
||||
m_texture = NULL;
|
||||
}
|
||||
if (m_ppfmt && m_ppfmt->next) {
|
||||
SDL_FreeFormat(m_ppfmt);
|
||||
m_ppfmt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DibBitmap *LoadDibBitmap(char *pszFn)
|
||||
@ -46,26 +43,13 @@ DibBitmap *LoadDibBitmap(char *pszFn)
|
||||
return pbm;
|
||||
}
|
||||
|
||||
DibBitmap *CreateDibBitmap(dword *pb, int cx, int cy, bool alpha)
|
||||
DibBitmap *CreateDibBitmap(dword *pb, int cx, int cy)
|
||||
{
|
||||
DibBitmap *pbm = new DibBitmap();
|
||||
Assert(pbm != NULL, "out of memory!");
|
||||
if (pbm == NULL)
|
||||
return NULL;
|
||||
if (!pbm->Init(pb, cx, cy, alpha, false)) {
|
||||
delete pbm;
|
||||
return NULL;
|
||||
}
|
||||
return pbm;
|
||||
}
|
||||
|
||||
DibBitmap *CreateBigDibBitmap(dword *pb, int cx, int cy, bool alpha)
|
||||
{
|
||||
DibBitmap *pbm = new DibBitmap();
|
||||
Assert(pbm != NULL, "out of memory!");
|
||||
if (pbm == NULL)
|
||||
return NULL;
|
||||
if (!pbm->Init(pb, cx, cy, alpha, true)) {
|
||||
if (!pbm->Init(pb, cx, cy)) {
|
||||
delete pbm;
|
||||
return NULL;
|
||||
}
|
||||
@ -74,94 +58,107 @@ DibBitmap *CreateBigDibBitmap(dword *pb, int cx, int cy, bool alpha)
|
||||
|
||||
bool DibBitmap::Init(char *pszFn)
|
||||
{
|
||||
// Read the file
|
||||
// Open the file
|
||||
|
||||
File *pfil = gpakr.fopen(pszFn, "rb");
|
||||
if (pfil == NULL)
|
||||
if (!pfil)
|
||||
return false;
|
||||
byte *pb = new byte[pfil->cbTotal];
|
||||
|
||||
if (gpakr.fread(pb, pfil->cbTotal, 1, pfil) != 1)
|
||||
if (!pb)
|
||||
return false;
|
||||
|
||||
// Feed the bytes into an SDL surface
|
||||
// Read the file
|
||||
|
||||
SDL_RWops *prwio = SDL_RWFromMem(pb, pfil->cbTotal);
|
||||
m_surface = IMG_Load_RW(prwio, 0);
|
||||
|
||||
// Cleanup
|
||||
|
||||
SDL_FreeRW(prwio);
|
||||
delete[] pb;
|
||||
if (gpakr.fread(pb, pfil->cbTotal, 1, pfil) != 1) {
|
||||
gpakr.fclose(pfil);
|
||||
return false;
|
||||
}
|
||||
gpakr.fclose(pfil);
|
||||
|
||||
// Keep the name around
|
||||
// Copy bytes into an SDL texture
|
||||
|
||||
m_pszFn = AllocString(pszFn);
|
||||
SDL_RWops *prwio = SDL_RWFromMem(pb, pfil->cbTotal);
|
||||
m_texture = IMG_LoadTexture_RW(gpdisp->Renderer(), prwio, 1);
|
||||
if (!m_texture)
|
||||
return false;
|
||||
|
||||
return m_surface != NULL;
|
||||
// Bytes have been copied into the texture and can be deleted
|
||||
|
||||
delete[] pb;
|
||||
|
||||
// Query the texture and save prevalent information
|
||||
|
||||
dword fmt;
|
||||
SDL_QueryTexture(m_texture, &fmt, NULL, &m_cx, &m_cy);
|
||||
m_ppfmt = SDL_AllocFormat(fmt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DibBitmap::Init(dword *pb, int cx, int cy, bool alpha, bool bigendian)
|
||||
bool DibBitmap::Init(dword *pb, int cx, int cy)
|
||||
{
|
||||
Uint32 rmask, gmask, bmask, amask;
|
||||
if (bigendian) {
|
||||
rmask = 0x000000ff;
|
||||
gmask = 0x0000ff00;
|
||||
bmask = 0x00ff0000;
|
||||
amask = 0xff000000;
|
||||
} else {
|
||||
rmask = 0xff000000;
|
||||
gmask = 0x00ff0000;
|
||||
bmask = 0x0000ff00;
|
||||
amask = 0x000000ff;
|
||||
}
|
||||
if (!alpha)
|
||||
amask = 0;
|
||||
// Assume RGBA mask
|
||||
|
||||
Uint32 rmask = 0, gmask = 0, bmask = 0, amask = 0;
|
||||
rmask = 0xff000000;
|
||||
gmask = 0x00ff0000;
|
||||
bmask = 0x0000ff00;
|
||||
amask = 0x000000ff;
|
||||
|
||||
// Create the texture
|
||||
|
||||
SDL_Renderer *renderer = gpdisp->Renderer();
|
||||
if (pb == NULL) {
|
||||
m_surface = SDL_CreateRGBSurface(SURFACE_FLAGS, cx, cy, SURFACE_DEPTH,
|
||||
rmask, gmask, bmask, amask);
|
||||
m_texture = SDL_CreateTexture(renderer,
|
||||
SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, cx, cy);
|
||||
} else {
|
||||
m_surface = SDL_CreateRGBSurfaceFrom(pb, cx, cy, SURFACE_DEPTH, SURFACE_PITCH(cx),
|
||||
rmask, gmask, bmask, amask);
|
||||
|
||||
// When using SDL_CreateRGBSurfaceFrom(), SDL does not manage the pixel data
|
||||
// so it will need to be freed manually
|
||||
// If creating with pb, copy bytes into SDL_Surface then create SDL_Texture from surface
|
||||
|
||||
m_wf |= kfDibFreeMem;
|
||||
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(
|
||||
pb, cx, cy, 32, cx * sizeof(dword), rmask, gmask, bmask, amask);
|
||||
m_texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
SDL_FreeSurface(surface);
|
||||
surface = NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This can be used to set the alpha color (only works if amask is 0)
|
||||
// SDL_SetColorKey(m_surface, 1, SDL_MapRGB(m_surface->format, 255, 0, 255));
|
||||
#endif
|
||||
if (!m_texture)
|
||||
return false;
|
||||
|
||||
return m_surface != NULL;
|
||||
// Query the texture and save prevalent information
|
||||
|
||||
dword fmt;
|
||||
SDL_QueryTexture(m_texture, &fmt, NULL, &m_cx, &m_cy);
|
||||
m_ppfmt = SDL_AllocFormat(fmt);
|
||||
if (!m_ppfmt)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_Rect rcSrc;
|
||||
SDL_Rect rcDst;
|
||||
void DibBitmap::Blt(DibBitmap *pbmSrc, Rect *prcSrc, int xDst, int yDst)
|
||||
{
|
||||
if (prcSrc == NULL) {
|
||||
SDL_Rect rcDst = { xDst, yDst, pbmSrc->GetSurface()->w, pbmSrc->GetSurface()->h };
|
||||
SDL_BlitSurface(pbmSrc->GetSurface(), NULL, m_surface, &rcDst);
|
||||
} else {
|
||||
SDL_Rect rcSrc = { prcSrc->left, prcSrc->top, prcSrc->Width(), prcSrc->Height() };
|
||||
SDL_Rect rcDst = { xDst, yDst, prcSrc->Width(), prcSrc->Height() };
|
||||
SDL_BlitSurface(pbmSrc->GetSurface(), &rcSrc, m_surface, &rcDst);
|
||||
SDL_Renderer *renderer = gpdisp->Renderer();
|
||||
if (SDL_SetRenderTarget(renderer, m_texture) != 0) {
|
||||
LOG() << "SDL Error: " << SDL_GetError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DibBitmap::BltTo(class DibBitmap *pbmDst, int xDst, int yDst, Rect *prcSrc)
|
||||
{
|
||||
if (prcSrc == NULL) {
|
||||
SDL_Rect rcDst = { xDst, yDst, m_surface->w, m_surface->h };
|
||||
SDL_BlitSurface(m_surface, NULL, pbmDst->GetSurface(), &rcDst);
|
||||
} else {
|
||||
SDL_Rect rcSrc = { prcSrc->left, prcSrc->top, prcSrc->Width(), prcSrc->Height() };
|
||||
SDL_Rect rcDst = { xDst, yDst, prcSrc->Width(), prcSrc->Height() };
|
||||
SDL_BlitSurface(m_surface, &rcSrc, pbmDst->GetSurface(), &rcDst);
|
||||
if (prcSrc != NULL) {
|
||||
rcSrc.x = prcSrc->left;
|
||||
rcSrc.y = prcSrc->top;
|
||||
rcSrc.w = prcSrc->Width();
|
||||
rcSrc.h = prcSrc->Height();
|
||||
}
|
||||
|
||||
rcDst.x = xDst;
|
||||
rcDst.y = yDst;
|
||||
rcDst.w = prcSrc ? prcSrc->Width() : pbmSrc->Width();
|
||||
rcDst.h = prcSrc ? prcSrc->Height() : pbmSrc->Height();
|
||||
|
||||
SDL_RenderCopy(renderer, pbmSrc->Texture(), prcSrc != NULL ? &rcSrc : NULL, &rcDst);
|
||||
}
|
||||
|
||||
void DibBitmap::BltTiles(DibBitmap *pbmSrc, UpdateMap *pupd, int yTopDst)
|
||||
@ -176,24 +173,34 @@ void DibBitmap::BltTiles(DibBitmap *pbmSrc, UpdateMap *pupd, int yTopDst)
|
||||
|
||||
void DibBitmap::GetSize(Size *psiz)
|
||||
{
|
||||
psiz->cx = m_surface->w;
|
||||
psiz->cy = m_surface->h;
|
||||
}
|
||||
|
||||
dword *DibBitmap::GetBits()
|
||||
{
|
||||
return (dword *)m_surface->pixels;
|
||||
}
|
||||
|
||||
int DibBitmap::GetPitch()
|
||||
{
|
||||
return m_surface->pitch;
|
||||
psiz->cx = m_cx;
|
||||
psiz->cy = m_cy;
|
||||
}
|
||||
|
||||
void DibBitmap::Fill(int x, int y, int cx, int cy, Color clr)
|
||||
{
|
||||
SDL_Rect rc = { x, y, cx, cy };
|
||||
SDL_FillRect(m_surface, &rc, SDL_MapRGB(m_surface->format, clr.r, clr.g, clr.b));
|
||||
SDL_Renderer *renderer = gpdisp->Renderer();
|
||||
SDL_SetRenderTarget(renderer, m_texture);
|
||||
|
||||
SDL_Rect rc;
|
||||
rc.x = x;
|
||||
rc.y = y;
|
||||
rc.w = cx;
|
||||
rc.h = cy;
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, clr.r, clr.g, clr.b, 255);
|
||||
SDL_RenderFillRect(renderer, &rc);
|
||||
}
|
||||
|
||||
void DibBitmap::Fill(int x, int y, int cx, int cy, dword clr)
|
||||
{
|
||||
SDL_PixelFormat *pfmt = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888);
|
||||
if (pfmt) {
|
||||
byte r, g, b;
|
||||
SDL_GetRGB(clr, pfmt, &r, &g, &b);
|
||||
Color c = { r, g, b };
|
||||
Fill(x, y, cx, cy, c);
|
||||
}
|
||||
}
|
||||
|
||||
void DibBitmap::FillTo(class DibBitmap *pbmDst, int xDst, int yDst,
|
||||
@ -201,20 +208,20 @@ void DibBitmap::FillTo(class DibBitmap *pbmDst, int xDst, int yDst,
|
||||
{
|
||||
Rect rcclp;
|
||||
|
||||
// For every y point that is disivible by m_surface->h
|
||||
// For every y point that is disivible by cx
|
||||
|
||||
for (int y = 0; y < cyDst; y++) {
|
||||
if (!(y % m_surface->h)) {
|
||||
if (!(y % m_cy)) {
|
||||
|
||||
// For every x point that is disivible by m_surface->w
|
||||
// For every x point that is disivible by cy
|
||||
|
||||
for (int x = 0; x < cxDst; x++) {
|
||||
if (!(x % m_surface->w)) {
|
||||
if (!(x % m_cx)) {
|
||||
|
||||
// Blt and clip appropriately
|
||||
|
||||
rcclp.Set(xDst + x, yDst + y, cxDst, cyDst);
|
||||
pbmDst->Blt(this, NULL, xDst + x, yDst + y);
|
||||
pbmDst->Blt(this, &rcclp, xDst + x, yDst + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -223,7 +230,7 @@ void DibBitmap::FillTo(class DibBitmap *pbmDst, int xDst, int yDst,
|
||||
|
||||
void DibBitmap::Clear(Color clr)
|
||||
{
|
||||
Fill(0, 0, m_surface->w, m_surface->h, clr);
|
||||
Fill(0, 0, m_cx, m_cy, clr);
|
||||
}
|
||||
|
||||
void DibBitmap::Shadow(int x, int y, int cx, int cy)
|
||||
@ -231,20 +238,21 @@ void DibBitmap::Shadow(int x, int y, int cx, int cy)
|
||||
DibBitmap *pbm = CreateDibBitmap(NULL, cx, cy);
|
||||
pbm->Clear(GetColor(kiclrBlack));
|
||||
|
||||
SDL_SetSurfaceBlendMode(pbm->GetSurface(), SDL_BLENDMODE_BLEND);
|
||||
SDL_SetSurfaceAlphaMod(pbm->GetSurface(), SHADOW_ALPHA_MOD);
|
||||
SDL_SetTextureBlendMode(pbm->Texture(), SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureAlphaMod(pbm->Texture(), 100);
|
||||
|
||||
pbm->BltTo(this, x, y);
|
||||
Blt(pbm, NULL, x, y);
|
||||
|
||||
SDL_SetTextureBlendMode(pbm->Texture(), SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
void DibBitmap::DrawLine(short x1, short y1, short x2, short y2, Color clr)
|
||||
{
|
||||
if (m_renderer == NULL)
|
||||
if ((m_renderer = SDL_CreateSoftwareRenderer(m_surface)) == NULL)
|
||||
return;
|
||||
SDL_Renderer *renderer = gpdisp->Renderer();
|
||||
SDL_SetRenderTarget(renderer, m_texture);
|
||||
|
||||
SDL_SetRenderDrawColor(m_renderer, clr.r, clr.g, clr.b, 255);
|
||||
SDL_RenderDrawLine(m_renderer, x1, y1, x2, y2);
|
||||
SDL_SetRenderDrawColor(renderer, clr.r, clr.g, clr.b, 255);
|
||||
SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void DibBitmap::Scroll(Rect *prcSrc, int xDst, int yDst)
|
||||
@ -255,26 +263,54 @@ void DibBitmap::Scroll(Rect *prcSrc, int xDst, int yDst)
|
||||
Blt(this, prcSrc, xDst, yDst);
|
||||
}
|
||||
|
||||
|
||||
DibBitmap *DibBitmap::Suballoc(int yTop, int cy)
|
||||
SubBitmap *DibBitmap::Suballoc(int yTop, int cy)
|
||||
{
|
||||
Assert(yTop < m_surface->h && yTop + cy <= m_surface->h);
|
||||
dword *pb = (dword *)m_surface->pixels + (long)m_surface->w * yTop;
|
||||
DibBitmap *pbm = CreateDibBitmap(pb, m_surface->w, cy);
|
||||
Assert(yTop < m_cy && yTop + cy <= m_cy);
|
||||
Rect rc;
|
||||
rc.Set(0, yTop, m_cx, yTop + cy);
|
||||
return Suballoc(rc);
|
||||
}
|
||||
|
||||
// We don't want it to free memory since that will be taken care
|
||||
// of by 'this'
|
||||
if (pbm != NULL)
|
||||
pbm->SetFlags(pbm->GetFlags() & ~kfDibFreeMem);
|
||||
SubBitmap *DibBitmap::Suballoc(Rect rc)
|
||||
{
|
||||
Assert(rc.right <= m_cx && rc.top <= m_cy);
|
||||
|
||||
SubBitmap *pbm = new SubBitmap(rc);
|
||||
if (!pbm) {
|
||||
delete pbm;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pbm->m_texture = m_texture;
|
||||
pbm->m_ppfmt = m_ppfmt;
|
||||
pbm->m_cx = rc.Width();
|
||||
pbm->m_cy = rc.Height();
|
||||
|
||||
return pbm;
|
||||
}
|
||||
|
||||
dword DibBitmap::MapRGB(byte r, byte g, byte b)
|
||||
{
|
||||
return SDL_MapRGB(m_surface->format, r, g, b);
|
||||
}
|
||||
|
||||
#endif // defined(SDL)
|
||||
|
||||
// SubBitmap
|
||||
|
||||
void SubBitmap::Blt(DibBitmap *pbmSrc, Rect *prcSrc, int xDst, int yDst)
|
||||
{
|
||||
DibBitmap::Blt(pbmSrc, prcSrc, xDst + m_rc.left, yDst + m_rc.top);
|
||||
}
|
||||
|
||||
void SubBitmap::Fill(int x, int y, int cx, int cy, Color clr)
|
||||
{
|
||||
DibBitmap::Fill(x + m_rc.left, y + m_rc.top, cx, cy, clr);
|
||||
}
|
||||
|
||||
void SubBitmap::Clear(Color clr)
|
||||
{
|
||||
DibBitmap::Fill(m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), clr);
|
||||
}
|
||||
|
||||
void SubBitmap::DrawLine(short x1, short y1, short x2, short y2, Color clr)
|
||||
{
|
||||
DibBitmap::DrawLine(x1 + m_rc.left, y1 + m_rc.top, x2 + m_rc.left, y2 + m_rc.top, clr);
|
||||
}
|
||||
|
||||
} // namespace wi
|
||||
|
||||
@ -937,10 +937,6 @@ void MultiFormMgr::DrawFrame(bool fForceBackBufferValid, bool fPaint)
|
||||
|
||||
bool fAnyScroll = fPaint ? Paint(fForceBackBufferValid) : false;
|
||||
|
||||
// Copy to front buffer
|
||||
|
||||
BltTo(gpdisp->GetFrontDib(), 0, fAnyScroll);
|
||||
|
||||
// Notify the display we've completed a frame. Pass in update maps
|
||||
// so selective invalidation can occur
|
||||
|
||||
|
||||
@ -2165,7 +2165,7 @@ bool Game::FilterEvent(Event *pevt)
|
||||
|
||||
// Draw
|
||||
|
||||
gpmfrmm->DrawFrame(false);
|
||||
gpmfrmm->DrawFrame(true);
|
||||
return true;
|
||||
|
||||
case gameSuspendEvent:
|
||||
|
||||
75
game/ht.h
75
game/ht.h
@ -1059,32 +1059,30 @@ struct TBitmapHeader // tbh
|
||||
#define kfDibBackWindow 0x0002
|
||||
#define kfDibWantScrolls 0x0004
|
||||
|
||||
class SubBitmap;
|
||||
class DibBitmap
|
||||
{
|
||||
public:
|
||||
DibBitmap() secDibBitmap;
|
||||
~DibBitmap() secDibBitmap;
|
||||
virtual ~DibBitmap() secDibBitmap;
|
||||
|
||||
bool Init(char *pszFn) secDibBitmap;
|
||||
bool Init(dword *pb, int cx, int cy, bool alpha, bool bigendian) secDibBitmap;
|
||||
virtual bool Init(char *pszFn) secDibBitmap;
|
||||
virtual bool Init(dword *pb, int cx, int cy) secDibBitmap;
|
||||
|
||||
void Blt(DibBitmap *pbmSrc, Rect *prcSrc, int xDst, int yDst) secDibBitmap;
|
||||
void BltTo(class DibBitmap *pbmDst, int xDst, int yDst, Rect *prcSrc = NULL) secDibBitmap;
|
||||
void BltTiles(DibBitmap *pbmSrc, UpdateMap *pupd, int yTopDst) secDibBitmap;
|
||||
|
||||
void GetSize(Size *psiz) secDibBitmap;
|
||||
dword *GetBits() secDibBitmap;
|
||||
int GetPitch() secDibBitmap;
|
||||
|
||||
void Fill(int x, int y, int cx, int cy, Color clr) secDibBitmap;
|
||||
void FillTo(class DibBitmap *pbmDst, int xDst, int yDst,
|
||||
virtual void Blt(DibBitmap *pbmSrc, Rect *prcSrc, int xDst, int yDst) secDibBitmap;
|
||||
virtual void BltTiles(DibBitmap *pbmSrc, UpdateMap *pupd, int yTopDst) secDibBitmap;
|
||||
virtual void GetSize(Size *psiz) secDibBitmap;
|
||||
virtual void Fill(int x, int y, int cx, int cy, Color clr) secDibBitmap;
|
||||
virtual void Fill(int x, int y, int cx, int cy, dword clr) secDibBitmap;
|
||||
virtual void FillTo(class DibBitmap *pbmDst, int xDst, int yDst,
|
||||
int cxDst, int cyDst, int xOrigin = 0, int yOrigin = 0) secDibBitmap;
|
||||
void Clear(Color clr) secDibBitmap;
|
||||
void Shadow(int x, int y, int cx, int cy) secDibBitmap;
|
||||
void DrawLine(short x1, short y1, short x2, short y2, Color clr) secDibBitmap;
|
||||
void Scroll(Rect *prcSrc, int xDst, int yDst) secDibBitmap;
|
||||
virtual void Clear(Color clr) secDibBitmap;
|
||||
virtual void Shadow(int x, int y, int cx, int cy) secDibBitmap;
|
||||
virtual void DrawLine(short x1, short y1, short x2, short y2, Color clr) secDibBitmap;
|
||||
virtual void Scroll(Rect *prcSrc, int xDst, int yDst) secDibBitmap;
|
||||
|
||||
DibBitmap *Suballoc(int yTop, int cy) secDibBitmap;
|
||||
virtual SubBitmap *Suballoc(int yTop, int cy) secDibBitmap;
|
||||
virtual SubBitmap *Suballoc(Rect rc) secDibBitmap;
|
||||
|
||||
word GetFlags() {
|
||||
return m_wf;
|
||||
@ -1092,31 +1090,40 @@ public:
|
||||
void SetFlags(word wf) {
|
||||
m_wf = wf;
|
||||
}
|
||||
int GetBaseline() {
|
||||
return 0;
|
||||
}
|
||||
char *GetFileName() {
|
||||
return m_pszFn;
|
||||
}
|
||||
|
||||
#if defined(SDL)
|
||||
int GetWidth() { return m_surface->w; }
|
||||
int GetHeight() { return m_surface->h; }
|
||||
dword MapRGB(byte r, byte g, byte b);
|
||||
SDL_Surface *GetSurface() { return m_surface; }
|
||||
SDL_Texture *Texture() { return m_texture; }
|
||||
int Width() { return m_cx; }
|
||||
int Height() { return m_cy; }
|
||||
#endif
|
||||
char *m_pszFn;
|
||||
|
||||
private:
|
||||
#if defined(SDL)
|
||||
SDL_Surface *m_surface;
|
||||
SDL_Renderer *m_renderer;
|
||||
SDL_Texture *m_texture;
|
||||
SDL_PixelFormat *m_ppfmt;
|
||||
#endif
|
||||
word m_wf;
|
||||
int m_cx;
|
||||
int m_cy;
|
||||
|
||||
friend class TBitmap;
|
||||
};
|
||||
DibBitmap *LoadDibBitmap(char *pszFn) secDibBitmap;
|
||||
DibBitmap *CreateDibBitmap(dword *pb, int cx, int cy, bool alpha = false) secDibBitmap;
|
||||
DibBitmap *CreateBigDibBitmap(dword *pb, int cx, int cy, bool alpha = false) secDibBitmap;
|
||||
DibBitmap *CreateDibBitmap(dword *pb, int cx, int cy) secDibBitmap;
|
||||
|
||||
class SubBitmap : public DibBitmap
|
||||
{
|
||||
public:
|
||||
SubBitmap(Rect rc) : m_rc(rc) { }
|
||||
~SubBitmap() {}
|
||||
|
||||
void Blt(DibBitmap *pbmSrc, Rect *prcSrc, int xDst, int yDst);
|
||||
void Fill(int x, int y, int cx, int cy, Color clr);
|
||||
void Clear(Color clr);
|
||||
void DrawLine(short x1, short y1, short x2, short y2, Color clr);
|
||||
private:
|
||||
Rect m_rc;
|
||||
};
|
||||
|
||||
// Texture bitmap
|
||||
// Stores information about a bitmap in a texture atlas
|
||||
@ -1150,7 +1157,7 @@ public:
|
||||
int Height() { return m_cyOrig; }
|
||||
|
||||
private:
|
||||
DibBitmap *SetLum(word lum, Side side = 1) secTBitmap;
|
||||
DibBitmap *Flash() secTBitmap;
|
||||
|
||||
int m_x, m_y, m_cx, m_cy;
|
||||
int m_cxOrig, m_cyOrig;
|
||||
|
||||
@ -32,10 +32,8 @@ Display::Display()
|
||||
|
||||
m_window = NULL;
|
||||
m_renderer = NULL;
|
||||
m_texture = NULL;
|
||||
m_display = NULL;
|
||||
m_pbm = NULL;
|
||||
|
||||
m_density = 0;
|
||||
m_fShouldRender = false;
|
||||
}
|
||||
|
||||
@ -44,15 +42,13 @@ Display::~Display()
|
||||
delete m_pbmClip;
|
||||
m_pbmClip = NULL;
|
||||
|
||||
delete m_display;
|
||||
m_display = NULL;
|
||||
delete m_pbm;
|
||||
m_pbm = NULL;
|
||||
|
||||
SDL_DestroyWindow(m_window);
|
||||
m_window = NULL;
|
||||
SDL_DestroyRenderer(m_renderer);
|
||||
m_renderer = NULL;
|
||||
SDL_DestroyTexture(m_texture);
|
||||
m_texture = NULL;
|
||||
}
|
||||
|
||||
bool Display::Init()
|
||||
@ -68,6 +64,7 @@ bool Display::Init()
|
||||
// Absolutely do not mess with SDL_FULLSCREEN if there is any chance the app
|
||||
// will crash or stop at a breakpoint. If it does you will be lost in full
|
||||
// screen mode! (ssh from another machine and kill the Xcode process)
|
||||
|
||||
videoflags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_SHOWN;
|
||||
#if defined(__IPHONEOS__) || defined(__ANDROID__)
|
||||
videoflags = videoflags | SDL_WINDOW_BORDERLESS;
|
||||
@ -75,13 +72,14 @@ bool Display::Init()
|
||||
#endif
|
||||
|
||||
// Get surface properties
|
||||
|
||||
SurfaceProperties props;
|
||||
HostHelpers::GetSurfaceProperties(&props);
|
||||
m_cx = props.cxWidth;
|
||||
m_cy = props.cyHeight;
|
||||
m_density = props.density;
|
||||
|
||||
// Set appropriate GL attributes
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
@ -94,19 +92,11 @@ bool Display::Init()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create renderer
|
||||
m_renderer = SDL_CreateRenderer(m_window, 0, SDL_RENDERER_TARGETTEXTURE);
|
||||
m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED);
|
||||
this->SetShouldRender(true);
|
||||
|
||||
// Keep the screen size around
|
||||
s_siz.cx = m_cx;
|
||||
s_siz.cy = m_cy;
|
||||
|
||||
// Create texture and display
|
||||
m_display = CreateDibBitmap(NULL, m_cx, m_cy);
|
||||
m_texture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, m_cx, m_cy);
|
||||
|
||||
// Keep the screen size around
|
||||
s_siz.cx = m_cx;
|
||||
s_siz.cy = m_cy;
|
||||
|
||||
@ -193,12 +183,12 @@ bool Display::SetMode(int imode)
|
||||
|
||||
ModeInfo *pmode = &m_amodeInfo[imode];
|
||||
|
||||
DibBitmap *pbmFront = CreateDibBitmap(NULL, m_cx, m_cy);
|
||||
if (pbmFront == NULL) {
|
||||
DibBitmap *pbm = CreateDibBitmap(NULL, m_cx, m_cy);
|
||||
if (pbm == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
delete m_display;
|
||||
m_display = pbmFront;
|
||||
delete m_pbm;
|
||||
m_pbm = pbm;
|
||||
m_imode = imode;
|
||||
|
||||
return true;
|
||||
@ -214,12 +204,12 @@ void Display::DrawFrameInclusive(Rect *prc)
|
||||
|
||||
DibBitmap *Display::GetBackDib()
|
||||
{
|
||||
return m_display;
|
||||
return m_pbm;
|
||||
}
|
||||
|
||||
DibBitmap *Display::GetFrontDib()
|
||||
{
|
||||
return m_display;
|
||||
return m_pbm;
|
||||
}
|
||||
|
||||
DibBitmap *Display::GetClippingDib()
|
||||
@ -243,25 +233,18 @@ void Display::FrameStart()
|
||||
void Display::FrameComplete(int cfrmm, UpdateMap **apupd, Rect *arc,
|
||||
bool fScrolled)
|
||||
{
|
||||
RenderGameSurface();
|
||||
}
|
||||
|
||||
void Display::RenderGameSurface() {
|
||||
if (!m_fShouldRender)
|
||||
return;
|
||||
|
||||
// Update the texture
|
||||
|
||||
SDL_UpdateTexture(m_texture, NULL, m_display->GetBits(), m_display->GetPitch());
|
||||
|
||||
// Draw any sprites onto the texture
|
||||
SDL_SetRenderTarget(m_renderer, m_texture);
|
||||
|
||||
SDL_SetRenderTarget(m_renderer, m_pbm->Texture());
|
||||
s_psprm->DrawSprites(m_renderer, s_siz);
|
||||
SDL_SetRenderTarget(m_renderer, NULL);
|
||||
|
||||
// Present the renderer to the screen
|
||||
SDL_RenderClear(m_renderer);
|
||||
SDL_RenderCopy(m_renderer, m_texture, NULL, NULL);
|
||||
|
||||
SDL_SetRenderTarget(m_renderer, NULL);
|
||||
SDL_RenderCopy(m_renderer, m_pbm->Texture(), NULL, NULL);
|
||||
SDL_RenderPresent(m_renderer);
|
||||
}
|
||||
|
||||
@ -286,12 +269,12 @@ void Display::SetFormMgrs(FormMgr *pfrmmSimUI, FormMgr *pfrmmInput)
|
||||
#endif
|
||||
}
|
||||
|
||||
float Display::Density() {
|
||||
return m_density;
|
||||
}
|
||||
|
||||
void Display::SetShouldRender(bool fsr) {
|
||||
m_fShouldRender = fsr;
|
||||
}
|
||||
|
||||
SDL_Renderer *Display::Renderer() {
|
||||
return m_renderer;
|
||||
}
|
||||
|
||||
} // namespace wi
|
||||
|
||||
@ -425,9 +425,8 @@ bool ProcessSdlEvent(base::Message *pmsg, Event *pevt)
|
||||
|
||||
// SDL may have released its graphics context if the app was previously
|
||||
// backgrounded. This leaves the screen black when the user returns.
|
||||
// Hack: Draw dib and render
|
||||
// Hack: Redraw
|
||||
gpmfrmm->DrawFrame(true);
|
||||
gpdisp->RenderGameSurface();
|
||||
break;
|
||||
|
||||
case SDL_APP_DIDENTERBACKGROUND:
|
||||
@ -465,7 +464,6 @@ bool ProcessSdlEvent(base::Message *pmsg, Event *pevt)
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
gpmfrmm->DrawFrame(true);
|
||||
gpdisp->RenderGameSurface();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@ -121,25 +121,19 @@ public:
|
||||
void ResetScrollOffset();
|
||||
SpriteManager *GetSpriteManager();
|
||||
void SetFormMgrs(FormMgr *pfrmmSim, FormMgr *pfrmmInput);
|
||||
void RenderGameSurface();
|
||||
float Density();
|
||||
void SetShouldRender(bool fsr);
|
||||
SDL_Renderer *Renderer();
|
||||
|
||||
private:
|
||||
int m_imode;
|
||||
ModeInfo m_amodeInfo[kcmodesMax];
|
||||
int m_cmodes;
|
||||
|
||||
int m_cx;
|
||||
int m_cy;
|
||||
DibBitmap *m_pbm;
|
||||
DibBitmap *m_pbmClip;
|
||||
|
||||
SDL_Window *m_window;
|
||||
SDL_Renderer *m_renderer;
|
||||
SDL_Texture *m_texture;
|
||||
DibBitmap *m_display;
|
||||
|
||||
float m_density;
|
||||
bool m_fShouldRender;
|
||||
};
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ SdlAnimSprite::SdlAnimSprite(SpriteManager *psprm) {
|
||||
cy_ = 0;
|
||||
xOrigin_ = 0;
|
||||
yOrigin_ = 0;
|
||||
surface_ = NULL;
|
||||
pbm_ = NULL;
|
||||
nScale_ = 1.0f;
|
||||
x_ = 0;
|
||||
y_ = 0;
|
||||
@ -23,7 +23,9 @@ SdlAnimSprite::~SdlAnimSprite() {
|
||||
psprm_->Remove(this);
|
||||
|
||||
crit_.Enter();
|
||||
surface_ = NULL;
|
||||
if (pbm_)
|
||||
delete pbm_;
|
||||
pbm_ = NULL;
|
||||
crit_.Leave();
|
||||
}
|
||||
|
||||
@ -74,10 +76,11 @@ bool SdlAnimSprite::CreateSurface(UnitGob *pgob) {
|
||||
yOrigin_ = rcAni.top;
|
||||
|
||||
// Create the surface
|
||||
surface_ = CreateDibBitmap(NULL, cx_, cy_, true);
|
||||
if (surface_ == NULL)
|
||||
pbm_ = CreateDibBitmap(NULL, cx_, cy_);
|
||||
if (pbm_ == NULL)
|
||||
return false;
|
||||
pgob->DrawAnimation(surface_, -xOrigin_, -yOrigin_);
|
||||
SDL_SetTextureBlendMode(pbm_->Texture(), SDL_BLENDMODE_BLEND);
|
||||
pgob->DrawAnimation(pbm_, -xOrigin_, -yOrigin_);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -104,15 +107,8 @@ void SdlAnimSprite::Draw(void *pv, Size *psiz) {
|
||||
rcBounds.Height()
|
||||
};
|
||||
|
||||
if (surface_ != NULL) {
|
||||
// Create a texture from the surface
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface((SDL_Renderer *)pv, surface_->GetSurface());
|
||||
|
||||
// Render the texture
|
||||
SDL_RenderCopy((SDL_Renderer *)pv, texture, NULL, &rc);
|
||||
|
||||
// Destroy
|
||||
SDL_DestroyTexture(texture);
|
||||
if (pbm_ != NULL) {
|
||||
SDL_RenderCopy((SDL_Renderer *)pv, pbm_->Texture(), NULL, &rc);
|
||||
}
|
||||
|
||||
crit_.Leave();
|
||||
|
||||
@ -44,7 +44,7 @@ private:
|
||||
dword hash_;
|
||||
int cx_, cy_;
|
||||
int xOrigin_, yOrigin_;
|
||||
DibBitmap *surface_;
|
||||
DibBitmap *pbm_;
|
||||
SpriteManager *psprm_;
|
||||
float nScaleStart_, nScaleEnd_;
|
||||
long msAnimateStart_;
|
||||
|
||||
@ -55,7 +55,9 @@ void TBitmap::BltTo(class DibBitmap *pbmDst, int xDst, int yDst, Side side, Rect
|
||||
// Flash unit?
|
||||
|
||||
if (side == (Side)-1) {
|
||||
SetLum(32768)->BltTo(pbmDst, xDst, yDst, prcSrc);
|
||||
DibBitmap *pbm = Flash();
|
||||
pbmDst->Blt(pbm, prcSrc, xDst, yDst);
|
||||
delete pbm;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -118,40 +120,44 @@ void TBitmap::FillTo(class DibBitmap *pbmDst, int xDst, int yDst,
|
||||
}
|
||||
}
|
||||
|
||||
DibBitmap *TBitmap::SetLum(word lum, Side side) {
|
||||
DibBitmap *TBitmap::Flash() {
|
||||
// Returns a DibBitmap of this TBitmap where all
|
||||
// the pixels have been changed to (255, 255, 255)
|
||||
// while maintaining their original alpha value
|
||||
|
||||
// Copy pixels into an DibBitmap
|
||||
#if defined(SDL)
|
||||
|
||||
DibBitmap *pbm = CreateDibBitmap(NULL, m_cxOrig, m_cyOrig, true);
|
||||
BltTo(pbm, 0, 0, side);
|
||||
Uint32 *i0p = (Uint32 *)pbm->GetBits();
|
||||
// Blt from the texture atlas into a dib
|
||||
|
||||
DibBitmap *pbm = CreateDibBitmap(NULL, m_cxOrig, m_cyOrig);
|
||||
BltTo(pbm, 0, 0, ksidmSide1);
|
||||
|
||||
// Read pixels from dib
|
||||
|
||||
int cpixels = m_cxOrig * m_cyOrig;
|
||||
dword *pixels = new dword[cpixels];
|
||||
int pitch = m_cxOrig * sizeof(dword);
|
||||
|
||||
SDL_Renderer *renderer = gpdisp->Renderer();
|
||||
if (SDL_SetRenderTarget(renderer, pbm->Texture()) != 0)
|
||||
return NULL;
|
||||
|
||||
// SDL_RenderReadPixels() is a slow operation
|
||||
|
||||
if (SDL_RenderReadPixels(renderer, NULL, 0, pixels, pitch) != 0)
|
||||
return NULL;
|
||||
|
||||
// Loop through the pixels and convert to (255, 255, 255, a)
|
||||
|
||||
byte r, g, b, a;
|
||||
word h, s, l;
|
||||
|
||||
// Loop helpers
|
||||
|
||||
int npixels = m_cxOrig * m_cyOrig;
|
||||
dword *ppixels = pbm->GetBits();
|
||||
dword *ppixel = ppixels;
|
||||
dword *end = ppixels + npixels;
|
||||
|
||||
for (; ppixel < end; ppixel++, i0p++) {
|
||||
SDL_GetRGBA(*i0p, pbm->GetSurface()->format, &r, &g, &b, &a);
|
||||
RgbToHsl(r, g, b, &h, &s, &l);
|
||||
|
||||
if (lum > 32768)
|
||||
lum = 32768;
|
||||
if (lum < 0)
|
||||
lum = 0;
|
||||
|
||||
// Change the pixel value
|
||||
|
||||
HslToRgb(h, s, lum, &r, &g, &b);
|
||||
*ppixel = SDL_MapRGBA(pbm->GetSurface()->format, r, g, b, a);
|
||||
for (int i = 0; i < cpixels; i++) {
|
||||
SDL_GetRGBA(pixels[i], pbm->m_ppfmt, &r, &g, &b, &a);
|
||||
pixels[i] = SDL_MapRGBA(pbm->m_ppfmt, 255, 255, 255, a);
|
||||
}
|
||||
|
||||
return pbm;
|
||||
delete pbm;
|
||||
return CreateDibBitmap(pixels, m_cxOrig, m_cyOrig);
|
||||
#endif // SDL
|
||||
}
|
||||
|
||||
} // namespace wi
|
||||
|
||||
@ -109,7 +109,7 @@ bool TileMap::Load(char *psz, Size *psizPlayfield)
|
||||
return false;
|
||||
|
||||
for (int nTile = 0; nTile < m_cTiles; nTile++) {
|
||||
m_tiles[nTile] = CreateBigDibBitmap(apbTileData[nTile], m_cxTile, m_cyTile);
|
||||
m_tiles[nTile] = CreateDibBitmap(apbTileData[nTile], m_cxTile, m_cyTile);
|
||||
}
|
||||
delete[] apbTileData;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user