mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2026-03-29 00:09:40 -06:00
SDL display improvements
This commit is contained in:
parent
3ae02f81eb
commit
4f2a0de55c
@ -31,11 +31,19 @@ Display::Display()
|
||||
m_pbmBack = NULL;
|
||||
m_pbmFront = NULL;
|
||||
m_pbmClip = NULL;
|
||||
|
||||
m_gameDisplay = NULL;
|
||||
m_gameSurfacePixels = NULL;
|
||||
m_gameSurface = NULL;
|
||||
|
||||
m_window = NULL;
|
||||
m_renderer = NULL;
|
||||
m_texture = NULL;
|
||||
|
||||
m_gamePixels = NULL;
|
||||
m_gamePixels32 = NULL;
|
||||
memset(m_palette, 0, sizeof(m_palette));
|
||||
m_pitch32 = 0;
|
||||
m_pixelCount = 0;
|
||||
|
||||
m_density = 0;
|
||||
m_fShouldRender = false;
|
||||
}
|
||||
|
||||
Display::~Display()
|
||||
@ -46,24 +54,23 @@ Display::~Display()
|
||||
m_pbmFront = NULL;
|
||||
delete m_pbmClip;
|
||||
m_pbmClip = NULL;
|
||||
|
||||
delete m_gameDisplay;
|
||||
m_gameDisplay = NULL;
|
||||
|
||||
m_pixelCount = 0;
|
||||
m_gameSurfacePixels = NULL;
|
||||
SDL_FreeSurface(m_gameSurface);
|
||||
m_gameSurface = NULL;
|
||||
SDL_DestroyWindow(window);
|
||||
window = NULL;
|
||||
SDL_DestroyTexture(texture);
|
||||
texture = NULL;
|
||||
|
||||
SDL_DestroyWindow(m_window);
|
||||
m_window = NULL;
|
||||
SDL_DestroyRenderer(m_renderer);
|
||||
m_renderer = NULL;
|
||||
SDL_DestroyTexture(m_texture);
|
||||
m_texture = NULL;
|
||||
|
||||
delete m_gamePixels;
|
||||
m_gamePixels = NULL;
|
||||
delete m_gamePixels32;
|
||||
m_gamePixels32 = NULL;
|
||||
}
|
||||
|
||||
bool Display::Init()
|
||||
{
|
||||
Uint32 videoflags;
|
||||
int cxScreen, cyScreen;
|
||||
dword videoflags;
|
||||
|
||||
/* Initialize SDL */
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
@ -80,7 +87,7 @@ bool Display::Init()
|
||||
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight LandscapeLeft");
|
||||
#endif
|
||||
|
||||
// The host wants to process mouse and touch events separately
|
||||
// Android wants to process mouse and touch events separately
|
||||
#if defined(__ANDROID__)
|
||||
SDL_SetHint(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1");
|
||||
#endif
|
||||
@ -88,27 +95,36 @@ bool Display::Init()
|
||||
// Get surface properties
|
||||
SurfaceProperties props;
|
||||
HostHelpers::GetSurfaceProperties(&props);
|
||||
cxScreen = props.cxWidth;
|
||||
cyScreen = props.cyHeight;
|
||||
m_cx = props.cxWidth;
|
||||
m_cy = props.cyHeight;
|
||||
m_density = props.density;
|
||||
|
||||
// Create window
|
||||
if ((window = SDL_CreateWindow("Hostile Takeover", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, cxScreen, cyScreen, videoflags)) == NULL) {
|
||||
LOG() << "Couldn't create window: " << cxScreen << "x" << cyScreen << " \nError: " << SDL_GetError();
|
||||
if ((m_window = SDL_CreateWindow("Hostile Takeover", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_cx, m_cy, videoflags)) == NULL) {
|
||||
LOG() << "Couldn't create window: " << m_cx << "x" << m_cy << " \nError: " << SDL_GetError();
|
||||
return false;
|
||||
}
|
||||
|
||||
renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_TARGETTEXTURE);
|
||||
// Create renderer
|
||||
m_renderer = SDL_CreateRenderer(m_window, 0, SDL_RENDERER_TARGETTEXTURE);
|
||||
this->SetShouldRender(true);
|
||||
|
||||
// Keep the screen size around
|
||||
s_siz.cx = cxScreen;
|
||||
s_siz.cy = cyScreen;
|
||||
s_siz.cx = m_cx;
|
||||
s_siz.cy = m_cy;
|
||||
|
||||
m_gameSurface = SDL_CreateRGBSurface(videoflags, cxScreen, cyScreen, 32, 0, 0, 0, 0);
|
||||
m_pixelCount = cxScreen * cyScreen;
|
||||
m_gameDisplay = (byte *)malloc(m_pixelCount);
|
||||
m_gameSurfacePixels = (Uint32 *)m_gameSurface->pixels;
|
||||
// Create texture
|
||||
m_texture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, m_cx, m_cy);
|
||||
|
||||
// Set pixel info
|
||||
m_pixelCount = m_cx * m_cy;
|
||||
m_gamePixels = (byte *)malloc(m_pixelCount);
|
||||
m_gamePixels32 = (dword *)malloc(m_pixelCount * 4);
|
||||
m_pitch32 = m_cx * sizeof(dword);
|
||||
|
||||
// Keep the screen size around
|
||||
s_siz.cx = m_cx;
|
||||
s_siz.cy = m_cy;
|
||||
|
||||
ModeInfo *pmode = m_amodeInfo;
|
||||
|
||||
@ -178,7 +194,7 @@ void Display::SetPalette(Palette *ppal)
|
||||
}
|
||||
|
||||
for (int i = 0; i < cEntries; i++) {
|
||||
m_32bppColors[i] = ((Uint8)aclr[i].r << 16) | ((Uint8)aclr[i].g << 8) | ((Uint8)aclr[i].b << 0);
|
||||
m_palette[i] = ((Uint8)aclr[i].r << 16) | ((Uint8)aclr[i].g << 8) | ((Uint8)aclr[i].b << 0);
|
||||
}
|
||||
|
||||
}
|
||||
@ -217,7 +233,7 @@ bool Display::SetMode(int imode)
|
||||
if (pbmBack == NULL)
|
||||
return false;
|
||||
|
||||
DibBitmap *pbmFront = CreateDibBitmap(m_gameDisplay, pmode->cx, pmode->cy);
|
||||
DibBitmap *pbmFront = CreateDibBitmap(m_gamePixels, pmode->cx, pmode->cy);
|
||||
if (pbmFront == NULL) {
|
||||
delete pbmBack;
|
||||
return NULL;
|
||||
@ -269,38 +285,35 @@ void Display::FrameStart()
|
||||
{
|
||||
// surface->pixels can change every time the surface is locked.
|
||||
// TODO(darrinm): problem for, e.g. scrolling optimizations?
|
||||
m_pbmFront->Init(m_gameDisplay, m_gameSurface->w, m_gameSurface->h);
|
||||
m_pbmFront->Init(m_gamePixels, m_cx, m_cy);
|
||||
}
|
||||
|
||||
void Display::FrameComplete(int cfrmm, UpdateMap **apupd, Rect *arc,
|
||||
bool fScrolled)
|
||||
{
|
||||
for (int i = 0; i < m_pixelCount; i++) {
|
||||
m_gameSurfacePixels[i] = m_32bppColors[m_gameDisplay[i]];
|
||||
m_gamePixels32[i] = m_palette[m_gamePixels[i]];
|
||||
}
|
||||
|
||||
RenderGameSurface();
|
||||
}
|
||||
|
||||
void Display::RenderGameSurface() {
|
||||
if (!m_fshouldRender)
|
||||
if (!m_fShouldRender)
|
||||
return;
|
||||
|
||||
// Create the texture
|
||||
texture = SDL_CreateTextureFromSurface(renderer, m_gameSurface);
|
||||
// Update the texture
|
||||
SDL_UpdateTexture(m_texture, NULL, m_gamePixels32, m_pitch32);
|
||||
|
||||
// Prepare the renderer
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
// Draw any sprites onto the texture
|
||||
SDL_SetRenderTarget(m_renderer, m_texture);
|
||||
s_psprm->DrawSprites(m_renderer, s_siz);
|
||||
SDL_SetRenderTarget(m_renderer, NULL);
|
||||
|
||||
// Draw on any sprites
|
||||
s_psprm->DrawSprites(renderer, s_siz);
|
||||
|
||||
// Present the renderer
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
// Free memory from the created texture
|
||||
SDL_DestroyTexture(texture);
|
||||
// Present the renderer to the screen
|
||||
SDL_RenderClear(m_renderer);
|
||||
SDL_RenderCopy(m_renderer, m_texture, NULL, NULL);
|
||||
SDL_RenderPresent(m_renderer);
|
||||
}
|
||||
|
||||
void Display::ResetScrollOffset()
|
||||
@ -329,7 +342,7 @@ float Display::Density() {
|
||||
}
|
||||
|
||||
void Display::SetShouldRender(bool fsr) {
|
||||
m_fshouldRender = fsr;
|
||||
m_fShouldRender = fsr;
|
||||
}
|
||||
|
||||
} // namespace wi
|
||||
|
||||
@ -454,6 +454,11 @@ bool ProcessSdlEvent(base::Message *pmsg, Event *pevt)
|
||||
pevt->eType = appStopEvent;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
gpmfrmm->DrawFrame(true);
|
||||
gpdisp->RenderGameSurface();
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -137,17 +137,18 @@ private:
|
||||
DibBitmap *m_pbmFront;
|
||||
DibBitmap *m_pbmClip;
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
SDL_Texture *texture;
|
||||
SDL_Window *m_window;
|
||||
SDL_Renderer *m_renderer;
|
||||
SDL_Texture *m_texture;
|
||||
|
||||
byte *m_gameDisplay;
|
||||
SDL_Surface *m_gameSurface;
|
||||
Uint32 *m_gameSurfacePixels;
|
||||
Uint32 m_32bppColors[256];
|
||||
byte *m_gamePixels;
|
||||
Uint32 *m_gamePixels32;
|
||||
Uint32 m_palette[256];
|
||||
int m_pitch32;
|
||||
int m_pixelCount;
|
||||
|
||||
float m_density;
|
||||
bool m_fshouldRender;
|
||||
bool m_fShouldRender;
|
||||
};
|
||||
|
||||
#define kfDtClearLine 1
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
#include "game/sdl/sdlselectionsprite.h"
|
||||
|
||||
#define GRABBIE_SIZE 10
|
||||
#define GRABBIE_SIZE_HALF GRABBIE_SIZE/2
|
||||
|
||||
namespace wi {
|
||||
|
||||
SdlSelectionSprite::SdlSelectionSprite(SpriteManager *psprm) {
|
||||
@ -41,27 +44,21 @@ void SdlSelectionSprite::Draw(void *pv, Size *psiz) {
|
||||
DPoint apt[4];
|
||||
drc_.GetPoints(apt);
|
||||
|
||||
float density = gpdisp->Density();
|
||||
|
||||
#define renderer (SDL_Renderer *)pv
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
for (int i = 0; i < ARRAYSIZE(apt); i++) {
|
||||
int next = i + 1 == ARRAYSIZE(apt) ? 0 : i + 1;
|
||||
|
||||
// x/y points for point a/b of the selection sprite line
|
||||
int x1 = roundf(apt[i].y * density);
|
||||
int y1 = roundf(apt[i].x * density);
|
||||
int x2 = roundf(apt[next].y * density);
|
||||
int y2 = roundf(apt[next].x * density);
|
||||
// x/y are swapped
|
||||
Point pt1 = {apt[i].y, apt[i].x};
|
||||
Point pt2 = {apt[next].y, apt[next].x};
|
||||
|
||||
// draw the selection sprite line
|
||||
SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
|
||||
|
||||
int gs = 20; // grabbie size
|
||||
int gsh = gs / 2; // grabbie size half
|
||||
SDL_RenderDrawLine(renderer, pt1.x, pt1.y, pt2.x, pt2.y);
|
||||
|
||||
// create and draw a grabbie rect
|
||||
SDL_Rect rect = {x1 - gsh, y1 - gsh , gs, gs};
|
||||
SDL_Rect rect = {pt1.x - GRABBIE_SIZE_HALF, pt1.y - GRABBIE_SIZE_HALF,
|
||||
GRABBIE_SIZE, GRABBIE_SIZE};
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,8 @@ SdlSpriteManager::SdlSpriteManager() {
|
||||
pcrit_ = new base::CriticalSection();
|
||||
cpspr_ = 0;
|
||||
fSpriteDirty_ = false;
|
||||
memset(&rcClip1_, 0, sizeof(rcClip1_));
|
||||
memset(&rcClip2_, 0, sizeof(rcClip2_));
|
||||
}
|
||||
|
||||
SdlSpriteManager::~SdlSpriteManager() {
|
||||
@ -64,8 +66,28 @@ void SdlSpriteManager::DrawSprites(SDL_Renderer *renderer, Size siz) {
|
||||
}
|
||||
|
||||
for (int i = 0; i < cpspr_; i++) {
|
||||
// Draw clipped to rcClip1
|
||||
SDL_RenderSetClipRect(renderer, &rcClip1_);
|
||||
apspr_[i]->Draw(renderer, &siz);
|
||||
|
||||
// Draw clipped to rcClip2
|
||||
SDL_RenderSetClipRect(renderer, &rcClip2_);
|
||||
apspr_[i]->Draw(renderer, &siz);
|
||||
}
|
||||
|
||||
SDL_RenderSetClipRect(renderer, NULL);
|
||||
}
|
||||
|
||||
void SdlSpriteManager::SetClipRects(wi::Rect *prc1, wi::Rect *prc2) {
|
||||
rcClip1_.x = prc1->left;
|
||||
rcClip1_.y = prc1->top;
|
||||
rcClip1_.w = prc1->Width();
|
||||
rcClip1_.h = prc1->Height();
|
||||
|
||||
rcClip2_.x = prc2->left;
|
||||
rcClip2_.y = prc2->top;
|
||||
rcClip2_.w = prc2->Width();
|
||||
rcClip2_.h = prc2->Height();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -11,10 +11,7 @@ public:
|
||||
SdlSpriteManager();
|
||||
~SdlSpriteManager();
|
||||
|
||||
virtual void SetClipRects(wi::Rect *prc1, wi::Rect *prc2) {
|
||||
LOG() << "SdlSpriteManager::SetClipRects not implemented yet";
|
||||
return;
|
||||
}
|
||||
virtual void SetClipRects(wi::Rect *prc1, wi::Rect *prc2);
|
||||
virtual wi::AnimSprite *CreateAnimSprite() {
|
||||
LOG() << "SdlSpriteManager::CreateAnimSprite not implemented yet";
|
||||
return NULL;
|
||||
@ -32,6 +29,8 @@ private:
|
||||
int cpspr_;
|
||||
wi::Sprite *apspr_[16];
|
||||
bool fSpriteDirty_;
|
||||
SDL_Rect rcClip1_;
|
||||
SDL_Rect rcClip2_;
|
||||
};
|
||||
|
||||
} // namespace wi
|
||||
|
||||
Loading…
Reference in New Issue
Block a user