mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2026-04-03 19:59:16 -06:00
OTG mouse events don’t get processed correctly. With this hint removed, SDL mouse events will be handled as touch events and touch will raise fake mouse events.
344 lines
7.4 KiB
C++
344 lines
7.4 KiB
C++
#include "../ht.h"
|
|
#include "game/sdl/sdlspritemgr.h"
|
|
#include "game/sdl/hosthelpers.h"
|
|
#include "game/sdl/sdlspritemgr.h"
|
|
|
|
namespace wi {
|
|
|
|
static SdlSpriteManager *s_psprm;
|
|
static Size s_siz;
|
|
|
|
Display *HostCreateDisplay() {
|
|
// Create a display
|
|
|
|
Display *pdisp = new Display();
|
|
if (pdisp == NULL)
|
|
return NULL;
|
|
if (!pdisp->Init()) {
|
|
delete pdisp;
|
|
return NULL;
|
|
}
|
|
return pdisp;
|
|
}
|
|
|
|
Display::Display()
|
|
{
|
|
m_cx = 0;
|
|
m_cy = 0;
|
|
memset(m_amodeInfo, 0, sizeof(m_amodeInfo));
|
|
m_imode = -1;
|
|
m_cmodes = 0;
|
|
m_pbmBack = NULL;
|
|
m_pbmFront = NULL;
|
|
m_pbmClip = 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()
|
|
{
|
|
delete m_pbmBack;
|
|
m_pbmBack = NULL;
|
|
delete m_pbmFront;
|
|
m_pbmFront = NULL;
|
|
delete m_pbmClip;
|
|
m_pbmClip = NULL;
|
|
|
|
SDL_DestroyWindow(m_window);
|
|
m_window = NULL;
|
|
SDL_DestroyRenderer(m_renderer);
|
|
m_renderer = NULL;
|
|
SDL_DestroyTexture(m_texture);
|
|
m_texture = NULL;
|
|
|
|
free(m_gamePixels);
|
|
m_gamePixels = NULL;
|
|
free(m_gamePixels32);
|
|
m_gamePixels32 = NULL;
|
|
}
|
|
|
|
bool Display::Init()
|
|
{
|
|
dword videoflags;
|
|
|
|
/* Initialize SDL */
|
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
|
LOG() << "Couldn't initialize SDL: " << SDL_GetError();
|
|
return false;
|
|
}
|
|
|
|
// 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;
|
|
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight LandscapeLeft");
|
|
#endif
|
|
|
|
// Get surface properties
|
|
SurfaceProperties props;
|
|
HostHelpers::GetSurfaceProperties(&props);
|
|
m_cx = props.cxWidth;
|
|
m_cy = props.cyHeight;
|
|
m_density = props.density;
|
|
|
|
// Create window
|
|
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;
|
|
}
|
|
|
|
// Create renderer
|
|
m_renderer = SDL_CreateRenderer(m_window, 0, SDL_RENDERER_TARGETTEXTURE);
|
|
this->SetShouldRender(true);
|
|
|
|
// Keep the screen size around
|
|
s_siz.cx = m_cx;
|
|
s_siz.cy = m_cy;
|
|
|
|
// 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;
|
|
|
|
#if 1
|
|
pmode->nDepth = 8;
|
|
pmode->cx = props.cxWidth;
|
|
pmode->cy = props.cyHeight;
|
|
pmode->cyGraffiti = 0;
|
|
pmode->fNative = true;
|
|
pmode->nDegreeOrientation = 0;
|
|
pmode++;
|
|
#endif
|
|
|
|
#if 0
|
|
pmode->nDepth = 8;
|
|
pmode->cx = props.cyHeight;
|
|
pmode->cy = props.cxWidth;
|
|
pmode->cyGraffiti = 0;
|
|
pmode->fNative = true;
|
|
pmode->nDegreeOrientation = 90; // leftie controls
|
|
pmode++;
|
|
#endif
|
|
|
|
#if 0
|
|
pmode->nDepth = 8;
|
|
pmode->cx = props.cxWidth;
|
|
pmode->cy = props.cyHeight;
|
|
pmode->cyGraffiti = 0;
|
|
pmode->fNative = true;
|
|
pmode->nDegreeOrientation = 180; // bizzaro controls
|
|
pmode++;
|
|
#endif
|
|
|
|
#if 0
|
|
pmode->nDepth = 8;
|
|
pmode->cx = props.cyHeight;
|
|
pmode->cy = props.cxWidth;
|
|
pmode->cyGraffiti = 0;
|
|
pmode->fNative = true;
|
|
pmode->nDegreeOrientation = 270; // rightie controls
|
|
pmode++;
|
|
#endif
|
|
|
|
m_cmodes = pmode - m_amodeInfo;
|
|
|
|
HostOutputDebugString("Display::Init %d", pmode - m_amodeInfo);
|
|
HostOutputDebugString("Display::Init %d modes", m_cmodes);
|
|
|
|
#if defined(__IPHONEOS__)
|
|
HostHelpers::DisplayInitComplete();
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
void Display::SetPalette(Palette *ppal)
|
|
{
|
|
SDL_Color aclr[256];
|
|
int cEntries = BigWord(ppal->cEntries);
|
|
byte *pb = (byte *)ppal->argb;
|
|
SDL_Color *pclr = aclr;
|
|
|
|
for (int i = 0; i < cEntries; i++) {
|
|
pclr->r = *pb++;
|
|
pclr->g = *pb++;
|
|
pclr->b = *pb++;
|
|
pclr++;
|
|
}
|
|
|
|
for (int i = 0; i < cEntries; i++) {
|
|
m_palette[i] = ((Uint8)aclr[i].r << 16) | ((Uint8)aclr[i].g << 8) | ((Uint8)aclr[i].b << 0);
|
|
}
|
|
|
|
}
|
|
|
|
int Display::GetModeCount()
|
|
{
|
|
return m_cmodes;
|
|
}
|
|
|
|
void Display::GetModeInfo(int imode, ModeInfo *pmode)
|
|
{
|
|
memset(pmode, 0, sizeof(*pmode));
|
|
if (imode >= 0 && imode < m_cmodes)
|
|
*pmode = m_amodeInfo[imode];
|
|
}
|
|
|
|
int Display::GetMode(ModeInfo *pmode)
|
|
{
|
|
if (pmode != NULL) {
|
|
if (m_imode == -1) {
|
|
memset(pmode, 0, sizeof(*pmode));
|
|
} else {
|
|
*pmode = m_amodeInfo[m_imode];
|
|
}
|
|
}
|
|
return m_imode;
|
|
}
|
|
|
|
bool Display::SetMode(int imode)
|
|
{
|
|
// Allocate dib
|
|
|
|
ModeInfo *pmode = &m_amodeInfo[imode];
|
|
|
|
DibBitmap *pbmBack = CreateDibBitmap(NULL, pmode->cx, pmode->cy);
|
|
if (pbmBack == NULL)
|
|
return false;
|
|
|
|
DibBitmap *pbmFront = CreateDibBitmap(m_gamePixels, pmode->cx, pmode->cy);
|
|
if (pbmFront == NULL) {
|
|
delete pbmBack;
|
|
return NULL;
|
|
}
|
|
delete m_pbmBack;
|
|
delete m_pbmFront;
|
|
m_pbmBack = pbmBack;
|
|
m_pbmFront = pbmFront;
|
|
m_imode = imode;
|
|
|
|
return true;
|
|
}
|
|
|
|
void Display::DrawText(const char *psz, int x, int y, word wf)
|
|
{
|
|
}
|
|
|
|
void Display::DrawFrameInclusive(Rect *prc)
|
|
{
|
|
}
|
|
|
|
DibBitmap *Display::GetBackDib()
|
|
{
|
|
return m_pbmBack;
|
|
}
|
|
|
|
DibBitmap *Display::GetFrontDib()
|
|
{
|
|
return m_pbmFront;
|
|
}
|
|
|
|
DibBitmap *Display::GetClippingDib()
|
|
{
|
|
DibBitmap *pbm = CreateDibBitmap(NULL, kcCopyBy4Procs * 4, kcCopyBy4Procs * 4);
|
|
if (pbm == NULL)
|
|
return NULL;
|
|
m_pbmClip = pbm;
|
|
return pbm;
|
|
}
|
|
|
|
void Display::GetHslAdjustments(short *pnHueOffset, short *pnSatMultiplier, short *pnLumOffset)
|
|
{
|
|
*pnHueOffset = 0;
|
|
*pnSatMultiplier = 0;
|
|
*pnLumOffset = 0;
|
|
}
|
|
|
|
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_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_gamePixels32[i] = m_palette[m_gamePixels[i]];
|
|
}
|
|
|
|
RenderGameSurface();
|
|
}
|
|
|
|
void Display::RenderGameSurface() {
|
|
if (!m_fShouldRender)
|
|
return;
|
|
|
|
// Update the texture
|
|
SDL_UpdateTexture(m_texture, NULL, m_gamePixels32, m_pitch32);
|
|
|
|
// Draw any sprites onto the texture
|
|
SDL_SetRenderTarget(m_renderer, m_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_RenderPresent(m_renderer);
|
|
}
|
|
|
|
void Display::ResetScrollOffset()
|
|
{
|
|
#if 0 // TODO(darrinm): SDL-ify
|
|
IPhone::ResetScrollOffset();
|
|
#endif
|
|
}
|
|
|
|
SpriteManager *Display::GetSpriteManager()
|
|
{
|
|
if (s_psprm == NULL)
|
|
s_psprm = new SdlSpriteManager();
|
|
return s_psprm;
|
|
}
|
|
|
|
void Display::SetFormMgrs(FormMgr *pfrmmSimUI, FormMgr *pfrmmInput)
|
|
{
|
|
#if 0 // TODO(darrinm): SDL-ify
|
|
IPhone::SetFormMgrs(pfrmmSimUI, pfrmmInput);
|
|
#endif
|
|
}
|
|
|
|
float Display::Density() {
|
|
return m_density;
|
|
}
|
|
|
|
void Display::SetShouldRender(bool fsr) {
|
|
m_fShouldRender = fsr;
|
|
}
|
|
|
|
} // namespace wi
|