mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-14 03:59:36 +00:00
Lots of Android fixes and stubs. Increase SDL log level on Android. Add GL context loss handling.
This commit is contained in:
@@ -322,6 +322,11 @@ bool GpFileSystem_Win32::IsVirtualDirectoryLooseResources(PortabilityLayer::Virt
|
||||
return false;
|
||||
}
|
||||
|
||||
void GpFileSystem_Win32::SetMainThreadRelay(IGpThreadRelay *relay)
|
||||
{
|
||||
(void)relay;
|
||||
}
|
||||
|
||||
bool GpFileSystem_Win32::ValidateFilePath(const char *str, size_t length) const
|
||||
{
|
||||
for (size_t i = 0; i < length; i++)
|
||||
|
||||
@@ -23,6 +23,8 @@ public:
|
||||
|
||||
bool IsVirtualDirectoryLooseResources(PortabilityLayer::VirtualDirectory_t virtualDir) const override;
|
||||
|
||||
void SetMainThreadRelay(IGpThreadRelay *relay) override;
|
||||
|
||||
const wchar_t *GetBasePath() const;
|
||||
|
||||
static GpFileSystem_Win32 *GetInstance();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "GpFileSystem_Android.h"
|
||||
#include "GpIOStream.h"
|
||||
#include "HostDirectoryCursor.h"
|
||||
#include "IGpThreadRelay.h"
|
||||
#include "VirtualDirectory.h"
|
||||
|
||||
#include "SDL.h"
|
||||
@@ -254,7 +255,32 @@ void GpFileStream_Android_File::Flush()
|
||||
fflush(m_f);
|
||||
}
|
||||
|
||||
static bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution, bool &isAsset)
|
||||
bool GpFileSystem_Android::ResolvePathInDownloadsDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution, bool &isAsset)
|
||||
{
|
||||
JNIEnv *jni = static_cast<JNIEnv *>(SDL_AndroidGetJNIEnv());
|
||||
|
||||
jstring fname = jni->NewStringUTF(paths[0]);
|
||||
|
||||
jobject resultName = jni->CallObjectMethod(m_activity, this->m_selectSourceExportPathMID, fname);
|
||||
int n = 0;
|
||||
jstring resultPath = static_cast<jstring>(resultName);
|
||||
jni->DeleteLocalRef(fname);
|
||||
|
||||
const char *pathStrChars = jni->GetStringUTFChars(resultPath, nullptr);
|
||||
resolution = std::string(pathStrChars, static_cast<size_t>(jni->GetStringUTFLength(resultPath)));
|
||||
|
||||
jni->ReleaseStringUTFChars(resultPath, pathStrChars);
|
||||
jni->DeleteLocalRef(resultPath);
|
||||
|
||||
resolution = SDL_AndroidGetExternalStoragePath();
|
||||
resolution += "/SourceCode.zip";
|
||||
|
||||
isAsset = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpFileSystem_Android::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution, bool &isAsset)
|
||||
{
|
||||
const char *prefsAppend = nullptr;
|
||||
|
||||
@@ -285,6 +311,8 @@ static bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, c
|
||||
case PortabilityLayer::VirtualDirectories::kPrefs:
|
||||
prefsAppend = "Prefs";
|
||||
break;
|
||||
case PortabilityLayer::VirtualDirectories::kSourceExport:
|
||||
return ResolvePathInDownloadsDirectory(virtualDirectory, paths, numPaths, resolution, isAsset);
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
@@ -308,6 +336,7 @@ static bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, c
|
||||
|
||||
GpFileSystem_Android::GpFileSystem_Android()
|
||||
: m_activity(nullptr)
|
||||
, m_relay(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -323,6 +352,7 @@ void GpFileSystem_Android::InitJNI()
|
||||
jclass activityClassLR = static_cast<jclass>(jni->GetObjectClass(activityLR));
|
||||
|
||||
m_scanAssetDirectoryMID = jni->GetMethodID(activityClassLR, "scanAssetDirectory", "(Ljava/lang/String;)[Ljava/lang/String;");
|
||||
m_selectSourceExportPathMID = jni->GetMethodID(activityClassLR, "selectSourceExportPath", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
|
||||
m_activity = jni->NewGlobalRef(activityLR);
|
||||
|
||||
@@ -407,7 +437,8 @@ GpIOStream *GpFileSystem_Android::OpenFileNested(PortabilityLayer::VirtualDirect
|
||||
bool canWrite = false;
|
||||
bool needResetPosition = false;
|
||||
|
||||
switch (createDisposition) {
|
||||
switch (createDisposition)
|
||||
{
|
||||
case GpFileCreationDispositions::kCreateOrOverwrite:
|
||||
mode = "w+b";
|
||||
break;
|
||||
@@ -506,6 +537,25 @@ bool GpFileSystem_Android::DeleteFile(PortabilityLayer::VirtualDirectory_t virtu
|
||||
}
|
||||
|
||||
PortabilityLayer::HostDirectoryCursor *GpFileSystem_Android::ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *const *paths, size_t numPaths)
|
||||
{
|
||||
ScanDirectoryNestedContext ctx;
|
||||
ctx.m_this = this;
|
||||
ctx.m_returnValue = nullptr;
|
||||
ctx.m_virtualDirectory = virtualDirectory;
|
||||
ctx.m_paths = paths;
|
||||
ctx.m_numPaths = numPaths;
|
||||
m_relay->Invoke(ScanDirectoryNestedThunk, &ctx);
|
||||
|
||||
return ctx.m_returnValue;
|
||||
}
|
||||
|
||||
void GpFileSystem_Android::ScanDirectoryNestedThunk(void *context)
|
||||
{
|
||||
ScanDirectoryNestedContext *ctx = static_cast<ScanDirectoryNestedContext*>(context);
|
||||
ctx->m_returnValue = ctx->m_this->ScanDirectoryNestedInternal(ctx->m_virtualDirectory, ctx->m_paths, ctx->m_numPaths);
|
||||
}
|
||||
|
||||
PortabilityLayer::HostDirectoryCursor *GpFileSystem_Android::ScanDirectoryNestedInternal(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *const *paths, size_t numPaths)
|
||||
{
|
||||
if (virtualDirectory == PortabilityLayer::VirtualDirectories::kGameData || virtualDirectory == PortabilityLayer::VirtualDirectories::kApplicationData)
|
||||
return ScanAssetDirectory(virtualDirectory, paths, numPaths);
|
||||
@@ -564,6 +614,11 @@ bool GpFileSystem_Android::IsVirtualDirectoryLooseResources(PortabilityLayer::Vi
|
||||
return false;
|
||||
}
|
||||
|
||||
void GpFileSystem_Android::SetMainThreadRelay(IGpThreadRelay *relay)
|
||||
{
|
||||
m_relay = relay;
|
||||
}
|
||||
|
||||
GpFileSystem_Android *GpFileSystem_Android::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
@@ -647,6 +702,7 @@ void GpDirectoryCursor_POSIX::Destroy()
|
||||
|
||||
PortabilityLayer::HostDirectoryCursor *GpFileSystem_Android::ScanAssetDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths)
|
||||
{
|
||||
|
||||
std::string resolvedPath;
|
||||
std::vector<std::string> subPaths;
|
||||
bool isAsset = true;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "GpCoreDefs.h"
|
||||
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
|
||||
class GpFileSystem_Android final : public PortabilityLayer::HostFileSystem
|
||||
{
|
||||
@@ -26,14 +27,35 @@ public:
|
||||
|
||||
bool IsVirtualDirectoryLooseResources(PortabilityLayer::VirtualDirectory_t virtualDir) const override;
|
||||
|
||||
void SetMainThreadRelay(IGpThreadRelay *relay) override;
|
||||
|
||||
static GpFileSystem_Android *GetInstance();
|
||||
|
||||
private:
|
||||
struct ScanDirectoryNestedContext
|
||||
{
|
||||
GpFileSystem_Android *m_this;
|
||||
|
||||
PortabilityLayer::HostDirectoryCursor *m_returnValue;
|
||||
PortabilityLayer::VirtualDirectory_t m_virtualDirectory;
|
||||
char const *const *m_paths;
|
||||
size_t m_numPaths;
|
||||
};
|
||||
|
||||
static void ScanDirectoryNestedThunk(void *context);
|
||||
PortabilityLayer::HostDirectoryCursor *ScanDirectoryNestedInternal(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths);
|
||||
|
||||
PortabilityLayer::HostDirectoryCursor *ScanAssetDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths);
|
||||
PortabilityLayer::HostDirectoryCursor *ScanStorageDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths);
|
||||
|
||||
bool ResolvePathInDownloadsDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution, bool &isAsset);
|
||||
bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution, bool &isAsset);
|
||||
|
||||
IGpThreadRelay *m_relay;
|
||||
|
||||
jobject m_activity;
|
||||
jmethodID m_scanAssetDirectoryMID;
|
||||
jmethodID m_selectSourceExportPathMID;
|
||||
|
||||
static GpFileSystem_Android ms_instance;
|
||||
};
|
||||
|
||||
@@ -30,6 +30,8 @@ IGpAudioDriver *GpDriver_CreateAudioDriver_SDL(const GpAudioDriverProperties &pr
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN);
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
android:installLocation="auto">
|
||||
|
||||
<!-- OpenGL ES 2.0 -->
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
||||
|
||||
<!-- Touchscreen support -->
|
||||
<uses-feature
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
package org.thecodedeposit.aerofoil;
|
||||
|
||||
import org.libsdl.app.SDLActivity;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.content.res.AssetManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
|
||||
|
||||
|
||||
public class GpActivity extends SDLActivity
|
||||
{
|
||||
@@ -27,4 +36,28 @@ public class GpActivity extends SDLActivity
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
|
||||
{
|
||||
if (requestCode == 1111 && resultCode == RESULT_OK && intent != null)
|
||||
{
|
||||
Uri uri = intent.getData();
|
||||
int n = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
}
|
||||
}
|
||||
|
||||
public String selectSourceExportPath(String fname)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT)
|
||||
.setType("application/zip")
|
||||
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
.putExtra(Intent.EXTRA_TITLE, "SourceCode.zip");
|
||||
startActivityForResult(intent, 1111);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,15 +629,17 @@ GLuint GpGLShader<TShaderType>::GetID() const
|
||||
class GpDisplayDriverSurface_GL2 : public IGpDisplayDriverSurface
|
||||
{
|
||||
public:
|
||||
GpDisplayDriverSurface_GL2(GpDisplayDriver_SDL_GL2 *driver, size_t width, size_t height, size_t pitch, GpGLTexture *texture, GpPixelFormat_t pixelFormat);
|
||||
GpDisplayDriverSurface_GL2(GpDisplayDriver_SDL_GL2 *driver, size_t width, size_t height, size_t pitch, GpGLTexture *texture, GpPixelFormat_t pixelFormat, IGpDisplayDriver::SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext);
|
||||
~GpDisplayDriverSurface_GL2();
|
||||
|
||||
static GpDisplayDriverSurface_GL2 *Create(GpDisplayDriver_SDL_GL2 *driver, size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat);
|
||||
static GpDisplayDriverSurface_GL2 *Create(GpDisplayDriver_SDL_GL2 *driver, size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, GpDisplayDriverSurface_GL2 *prevSurface, IGpDisplayDriver::SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext);
|
||||
|
||||
void Upload(const void *data, size_t x, size_t y, size_t width, size_t height, size_t pitch);
|
||||
void UploadEntire(const void *data, size_t pitch);
|
||||
void Destroy();
|
||||
|
||||
bool RecreateAll();
|
||||
|
||||
size_t GetImageWidth() const;
|
||||
size_t GetPaddedTextureWidth() const;
|
||||
size_t GetHeight() const;
|
||||
@@ -645,7 +647,8 @@ public:
|
||||
GpGLTexture *GetTexture() const;
|
||||
|
||||
private:
|
||||
bool Init();
|
||||
bool Init(GpDisplayDriverSurface_GL2 *prevSurface);
|
||||
bool RecreateSingle();
|
||||
GLenum ResolveGLFormat() const;
|
||||
GLenum ResolveGLInternalFormat() const;
|
||||
GLenum ResolveGLType() const;
|
||||
@@ -657,6 +660,13 @@ private:
|
||||
size_t m_paddedTextureWidth;
|
||||
size_t m_pitch;
|
||||
size_t m_height;
|
||||
|
||||
GpDisplayDriver_SDL_GL2 *m_driver;
|
||||
GpDisplayDriverSurface_GL2 *m_next;
|
||||
GpDisplayDriverSurface_GL2 *m_prev;
|
||||
|
||||
IGpDisplayDriver::SurfaceInvalidateCallback_t m_invalidateCallback;
|
||||
void *m_invalidateContext;
|
||||
};
|
||||
|
||||
class GpCursor_SDL2 final : public IGpCursor
|
||||
@@ -714,7 +724,7 @@ public:
|
||||
void Run() override;
|
||||
void Shutdown() override;
|
||||
void GetDisplayResolution(unsigned int *width, unsigned int *height) override;
|
||||
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat) override;
|
||||
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext) override;
|
||||
void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects) override;
|
||||
IGpCursor *CreateBWCursor(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY) override;
|
||||
IGpCursor *CreateColorCursor(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY) override;
|
||||
@@ -733,6 +743,8 @@ public:
|
||||
void ApplyPrefs(const void *identifier, size_t identifierSize, const void *contents, size_t contentsSize, uint32_t version) override;
|
||||
bool SavePrefs(void *context, WritePrefsFunc_t writeFunc) override;
|
||||
|
||||
void UnlinkSurface(GpDisplayDriverSurface_GL2 *surface, GpDisplayDriverSurface_GL2 *prev, GpDisplayDriverSurface_GL2 *next);
|
||||
|
||||
const GpGLFunctions *GetGLFunctions() const;
|
||||
|
||||
template<GLuint TShaderType> GpComPtr<GpGLShader<TShaderType> > CreateShader(const char *shaderSrc);
|
||||
@@ -776,15 +788,6 @@ private:
|
||||
GpGLFunctions m_gl;
|
||||
GpDisplayDriverProperties m_properties;
|
||||
|
||||
GpComPtr<GpGLRenderTargetView> m_virtualScreenTextureRTV;
|
||||
GpComPtr<GpGLTexture> m_virtualScreenTexture;
|
||||
|
||||
GpComPtr<GpGLVertexArray> m_quadVertexArray;
|
||||
GpComPtr<GpGLBuffer> m_quadVertexBufferKeepalive;
|
||||
GpComPtr<GpGLBuffer> m_quadIndexBuffer;
|
||||
|
||||
GpComPtr<GpGLTexture> m_paletteTexture;
|
||||
|
||||
struct DrawQuadProgram
|
||||
{
|
||||
GpComPtr<GpGLProgram> m_program;
|
||||
@@ -815,6 +818,17 @@ private:
|
||||
bool Link(GpDisplayDriver_SDL_GL2 *driver, const GpGLShader<GL_VERTEX_SHADER> *vertexShader, const GpGLShader<GL_FRAGMENT_SHADER> *pixelShader);
|
||||
};
|
||||
|
||||
struct InstancedResources
|
||||
{
|
||||
GpComPtr<GpGLRenderTargetView> m_virtualScreenTextureRTV;
|
||||
GpComPtr<GpGLTexture> m_virtualScreenTexture;
|
||||
|
||||
GpComPtr<GpGLVertexArray> m_quadVertexArray;
|
||||
GpComPtr<GpGLBuffer> m_quadVertexBufferKeepalive;
|
||||
GpComPtr<GpGLBuffer> m_quadIndexBuffer;
|
||||
|
||||
GpComPtr<GpGLTexture> m_paletteTexture;
|
||||
|
||||
BlitQuadProgram m_scaleQuadProgram;
|
||||
BlitQuadProgram m_copyQuadProgram;
|
||||
|
||||
@@ -826,6 +840,9 @@ private:
|
||||
DrawQuadProgram m_drawQuadPaletteICCFlickerProgram;
|
||||
DrawQuadProgram m_drawQuadRGBICCProgram;
|
||||
DrawQuadProgram m_drawQuad15BitICCProgram;
|
||||
};
|
||||
|
||||
InstancedResources m_res;
|
||||
|
||||
SDL_Window *m_window;
|
||||
SDL_GLContext m_glContext;
|
||||
@@ -834,6 +851,7 @@ private:
|
||||
SDL_Cursor *m_iBeamCursor;
|
||||
SDL_Cursor *m_arrowCursor;
|
||||
bool m_cursorIsHidden;
|
||||
bool m_contextLost;
|
||||
|
||||
bool m_isResettingSwapChain;
|
||||
|
||||
@@ -872,10 +890,16 @@ private:
|
||||
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock>::duration m_syncTimeBase;
|
||||
GpRingBuffer<CompactedPresentHistoryItem, 60> m_presentHistory;
|
||||
|
||||
GpDisplayDriverSurface_GL2 *m_firstSurface;
|
||||
GpDisplayDriverSurface_GL2 *m_lastSurface;
|
||||
|
||||
uint8_t m_paletteStorage[256 * 4 + GP_SYSTEM_MEMORY_ALIGNMENT];
|
||||
uint8_t *m_paletteData;
|
||||
};
|
||||
|
||||
|
||||
GpDisplayDriverSurface_GL2::GpDisplayDriverSurface_GL2(GpDisplayDriver_SDL_GL2 *driver, size_t width, size_t height, size_t pitch, GpGLTexture *texture, GpPixelFormat_t pixelFormat)
|
||||
GpDisplayDriverSurface_GL2::GpDisplayDriverSurface_GL2(GpDisplayDriver_SDL_GL2 *driver, size_t width, size_t height, size_t pitch, GpGLTexture *texture, GpPixelFormat_t pixelFormat, IGpDisplayDriver::SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext)
|
||||
: m_gl(driver->GetGLFunctions())
|
||||
, m_texture(texture)
|
||||
, m_pixelFormat(pixelFormat)
|
||||
@@ -883,6 +907,11 @@ GpDisplayDriverSurface_GL2::GpDisplayDriverSurface_GL2(GpDisplayDriver_SDL_GL2 *
|
||||
, m_paddedTextureWidth(0)
|
||||
, m_height(height)
|
||||
, m_pitch(pitch)
|
||||
, m_driver(driver)
|
||||
, m_prev(nullptr)
|
||||
, m_next(nullptr)
|
||||
, m_invalidateCallback(invalidateCallback)
|
||||
, m_invalidateContext(invalidateContext)
|
||||
{
|
||||
size_t paddingPixels = 0;
|
||||
|
||||
@@ -915,9 +944,15 @@ GpDisplayDriverSurface_GL2::GpDisplayDriverSurface_GL2(GpDisplayDriver_SDL_GL2 *
|
||||
|
||||
GpDisplayDriverSurface_GL2::~GpDisplayDriverSurface_GL2()
|
||||
{
|
||||
if (m_prev)
|
||||
m_prev->m_next = m_next;
|
||||
if (m_next)
|
||||
m_next->m_prev = m_prev;
|
||||
|
||||
m_driver->UnlinkSurface(this, m_prev, m_next);
|
||||
}
|
||||
|
||||
GpDisplayDriverSurface_GL2 *GpDisplayDriverSurface_GL2::Create(GpDisplayDriver_SDL_GL2 *driver, size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat)
|
||||
GpDisplayDriverSurface_GL2 *GpDisplayDriverSurface_GL2::Create(GpDisplayDriver_SDL_GL2 *driver, size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, GpDisplayDriverSurface_GL2 *prevSurface, IGpDisplayDriver::SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext)
|
||||
{
|
||||
GpComPtr<GpGLTexture> texture = GpComPtr<GpGLTexture>(GpGLTexture::Create(driver));
|
||||
if (!texture)
|
||||
@@ -927,8 +962,8 @@ GpDisplayDriverSurface_GL2 *GpDisplayDriverSurface_GL2::Create(GpDisplayDriver_S
|
||||
if (!surface)
|
||||
return nullptr;
|
||||
|
||||
new (surface) GpDisplayDriverSurface_GL2(driver, width, height, pitch, texture, pixelFormat);
|
||||
if (!surface->Init())
|
||||
new (surface) GpDisplayDriverSurface_GL2(driver, width, height, pitch, texture, pixelFormat, invalidateCallback, invalidateContext);
|
||||
if (!surface->Init(prevSurface))
|
||||
{
|
||||
surface->Destroy();
|
||||
return nullptr;
|
||||
@@ -967,6 +1002,23 @@ void GpDisplayDriverSurface_GL2::Destroy()
|
||||
free(this);
|
||||
}
|
||||
|
||||
bool GpDisplayDriverSurface_GL2::RecreateAll()
|
||||
{
|
||||
for (GpDisplayDriverSurface_GL2 *scan = this; scan; scan = scan->m_next)
|
||||
{
|
||||
scan->m_invalidateCallback(scan->m_invalidateContext);
|
||||
scan->m_texture = nullptr;
|
||||
}
|
||||
|
||||
for (GpDisplayDriverSurface_GL2 *scan = this; scan; scan = scan->m_next)
|
||||
{
|
||||
if (!scan->RecreateSingle())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t GpDisplayDriverSurface_GL2::GetImageWidth() const
|
||||
{
|
||||
return m_imageWidth;
|
||||
@@ -993,7 +1045,7 @@ GpGLTexture *GpDisplayDriverSurface_GL2::GetTexture() const
|
||||
}
|
||||
|
||||
|
||||
bool GpDisplayDriverSurface_GL2::Init()
|
||||
bool GpDisplayDriverSurface_GL2::Init(GpDisplayDriverSurface_GL2 *prevSurface)
|
||||
{
|
||||
CheckGLError(*m_gl);
|
||||
|
||||
@@ -1011,6 +1063,12 @@ bool GpDisplayDriverSurface_GL2::Init()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpDisplayDriverSurface_GL2::RecreateSingle()
|
||||
{
|
||||
m_texture = GpGLTexture::Create(m_driver);
|
||||
return m_texture != nullptr;
|
||||
}
|
||||
|
||||
GLenum GpDisplayDriverSurface_GL2::ResolveGLFormat() const
|
||||
{
|
||||
switch (m_pixelFormat)
|
||||
@@ -1101,6 +1159,9 @@ GpDisplayDriver_SDL_GL2::GpDisplayDriver_SDL_GL2(const GpDisplayDriverProperties
|
||||
, m_iBeamCursor(nullptr)
|
||||
, m_arrowCursor(nullptr)
|
||||
, m_cursorIsHidden(false)
|
||||
, m_contextLost(true)
|
||||
, m_lastSurface(nullptr)
|
||||
, m_firstSurface(nullptr)
|
||||
{
|
||||
m_bgColor[0] = 0.f;
|
||||
m_bgColor[1] = 0.f;
|
||||
@@ -1118,6 +1179,12 @@ GpDisplayDriver_SDL_GL2::GpDisplayDriver_SDL_GL2(const GpDisplayDriverProperties
|
||||
m_waitCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||
m_iBeamCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
|
||||
m_arrowCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||
|
||||
m_paletteData = m_paletteStorage;
|
||||
while (reinterpret_cast<uintptr_t>(m_paletteData) % GP_SYSTEM_MEMORY_ALIGNMENT != 0)
|
||||
m_paletteData++;
|
||||
|
||||
memset(m_paletteData, 255, 256 * 4);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -1724,7 +1791,45 @@ void GpDisplayDriver_SDL_GL2::Run()
|
||||
m_vosEvent = m_properties.m_systemServices->CreateThreadEvent(true, false);
|
||||
m_vosFiber = new GpFiber_SDL(nullptr, m_vosEvent);
|
||||
|
||||
m_window = SDL_CreateWindow(GP_APPLICATION_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_windowWidthPhysical, m_windowHeightPhysical, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||
uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
|
||||
if (m_isFullScreenDesired)
|
||||
{
|
||||
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
m_isFullScreen = true;
|
||||
}
|
||||
else
|
||||
windowFlags |= SDL_WINDOW_RESIZABLE;
|
||||
|
||||
m_window = SDL_CreateWindow(GP_APPLICATION_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_windowWidthPhysical, m_windowHeightPhysical, windowFlags);
|
||||
|
||||
if (m_isFullScreen)
|
||||
{
|
||||
m_windowModeRevertWidth = m_windowWidthPhysical;
|
||||
m_windowModeRevertHeight = m_windowHeightPhysical;
|
||||
|
||||
int windowWidth = 0;
|
||||
int windowHeight = 0;
|
||||
SDL_GetWindowSize(m_window, &windowWidth, &windowHeight);
|
||||
|
||||
m_windowWidthPhysical = windowWidth;
|
||||
m_windowHeightPhysical = windowHeight;
|
||||
|
||||
|
||||
uint32_t desiredWidth = windowWidth;
|
||||
uint32_t desiredHeight = windowHeight;
|
||||
uint32_t virtualWidth = m_windowWidthVirtual;
|
||||
uint32_t virtualHeight = m_windowHeightVirtual;
|
||||
float pixelScaleX = m_pixelScaleX;
|
||||
float pixelScaleY = m_pixelScaleY;
|
||||
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
|
||||
{
|
||||
m_windowWidthVirtual = virtualWidth;
|
||||
m_windowHeightVirtual = virtualHeight;
|
||||
m_pixelScaleX = pixelScaleX;
|
||||
m_pixelScaleY = pixelScaleY;
|
||||
}
|
||||
}
|
||||
|
||||
const bool obstructiveTextInput = m_properties.m_systemServices->IsTextInputObstructive();
|
||||
|
||||
@@ -1736,8 +1841,6 @@ void GpDisplayDriver_SDL_GL2::Run()
|
||||
if (!m_gl.LookUpFunctions())
|
||||
return;
|
||||
|
||||
InitResources(m_windowWidthVirtual, m_windowHeightVirtual);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SDL_Event msg;
|
||||
@@ -1750,8 +1853,11 @@ void GpDisplayDriver_SDL_GL2::Run()
|
||||
}
|
||||
//else if (msg.type == SDL_MOUSELEAVE) // Does SDL support this??
|
||||
// m_mouseIsInClientArea = false;
|
||||
else if (msg.type == SDL_RENDER_DEVICE_RESET || msg.type == SDL_RENDER_TARGETS_RESET)
|
||||
m_contextLost = true;
|
||||
|
||||
TranslateSDLMessage(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY, obstructiveTextInput);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1761,6 +1867,9 @@ void GpDisplayDriver_SDL_GL2::Run()
|
||||
BecomeFullScreen();
|
||||
else
|
||||
BecomeWindowed();
|
||||
|
||||
m_contextLost = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
int clientWidth = 0;
|
||||
@@ -1784,7 +1893,6 @@ void GpDisplayDriver_SDL_GL2::Run()
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
|
||||
{
|
||||
bool resizedOK = ResizeOpenGLWindow(m_windowWidthPhysical, m_windowHeightPhysical, desiredWidth, desiredHeight, logger);
|
||||
resizedOK = resizedOK && InitBackBuffer(virtualWidth, virtualHeight);
|
||||
|
||||
if (!resizedOK)
|
||||
break; // Critical video driver error, exit
|
||||
@@ -1803,9 +1911,30 @@ void GpDisplayDriver_SDL_GL2::Run()
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newWidth = m_windowWidthVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newHeight = m_windowHeightVirtual;
|
||||
}
|
||||
|
||||
m_contextLost = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_contextLost)
|
||||
{
|
||||
// Drop everything and reset
|
||||
m_res.~InstancedResources();
|
||||
new (&m_res) InstancedResources();
|
||||
|
||||
if (m_firstSurface)
|
||||
m_firstSurface->RecreateAll();
|
||||
|
||||
if (!InitBackBuffer(m_windowWidthVirtual, m_windowHeightVirtual))
|
||||
break;
|
||||
|
||||
InitResources(m_windowWidthVirtual, m_windowHeightVirtual);
|
||||
|
||||
m_contextLost = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
GpDisplayDriverTickStatus_t tickStatus = PresentFrameAndSync();
|
||||
if (tickStatus == GpDisplayDriverTickStatuses::kFatalFault || tickStatus == GpDisplayDriverTickStatuses::kApplicationTerminated)
|
||||
break;
|
||||
@@ -1830,9 +1959,16 @@ void GpDisplayDriver_SDL_GL2::GetDisplayResolution(unsigned int *width, unsigned
|
||||
*height = m_windowHeightVirtual;
|
||||
}
|
||||
|
||||
IGpDisplayDriverSurface *GpDisplayDriver_SDL_GL2::CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat)
|
||||
IGpDisplayDriverSurface *GpDisplayDriver_SDL_GL2::CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext)
|
||||
{
|
||||
return GpDisplayDriverSurface_GL2::Create(this, width, height, pitch, pixelFormat);
|
||||
GpDisplayDriverSurface_GL2 *surface = GpDisplayDriverSurface_GL2::Create(this, width, height, pitch, pixelFormat, m_lastSurface, invalidateCallback, invalidateContext);
|
||||
if (surface)
|
||||
{
|
||||
m_lastSurface = surface;
|
||||
if (m_firstSurface == nullptr)
|
||||
m_firstSurface = surface;
|
||||
}
|
||||
return surface;
|
||||
}
|
||||
|
||||
void GpDisplayDriver_SDL_GL2::DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects)
|
||||
@@ -1840,7 +1976,7 @@ void GpDisplayDriver_SDL_GL2::DrawSurface(IGpDisplayDriverSurface *surface, int3
|
||||
if (!effects)
|
||||
effects = &gs_defaultEffects;
|
||||
|
||||
GpGLVertexArray *vaPtr = m_quadVertexArray;
|
||||
GpGLVertexArray *vaPtr = m_res.m_quadVertexArray;
|
||||
size_t vbStride = sizeof(float) * 2;
|
||||
size_t zero = 0;
|
||||
|
||||
@@ -1854,16 +1990,16 @@ void GpDisplayDriver_SDL_GL2::DrawSurface(IGpDisplayDriverSurface *surface, int3
|
||||
if (m_useICCProfile)
|
||||
{
|
||||
if (effects->m_flicker)
|
||||
program = &m_drawQuadPaletteICCFlickerProgram;
|
||||
program = &m_res.m_drawQuadPaletteICCFlickerProgram;
|
||||
else
|
||||
program = &m_drawQuadPaletteICCNoFlickerProgram;
|
||||
program = &m_res.m_drawQuadPaletteICCNoFlickerProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (effects->m_flicker)
|
||||
program = &m_drawQuadPaletteFlickerProgram;
|
||||
program = &m_res.m_drawQuadPaletteFlickerProgram;
|
||||
else
|
||||
program = &m_drawQuadPaletteNoFlickerProgram;
|
||||
program = &m_res.m_drawQuadPaletteNoFlickerProgram;
|
||||
}
|
||||
}
|
||||
else if (pixelFormat == GpPixelFormats::kRGB555)
|
||||
@@ -1937,7 +2073,7 @@ void GpDisplayDriver_SDL_GL2::DrawSurface(IGpDisplayDriverSurface *surface, int3
|
||||
|
||||
GLint vpos[1] = { program->m_vertexPosUVLocation };
|
||||
|
||||
m_quadVertexArray->Activate(vpos);
|
||||
m_res.m_quadVertexArray->Activate(vpos);
|
||||
|
||||
m_gl.ActiveTexture(GL_TEXTURE0);
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, glSurface->GetTexture()->GetID());
|
||||
@@ -1946,11 +2082,11 @@ void GpDisplayDriver_SDL_GL2::DrawSurface(IGpDisplayDriverSurface *surface, int3
|
||||
if (pixelFormat == GpPixelFormats::k8BitStandard || pixelFormat == GpPixelFormats::k8BitCustom)
|
||||
{
|
||||
m_gl.ActiveTexture(GL_TEXTURE1);
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_paletteTexture->GetID());
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_res.m_paletteTexture->GetID());
|
||||
m_gl.Uniform1i(program->m_pixelPaletteTextureLocation, 1);
|
||||
}
|
||||
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadIndexBuffer->GetID());
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_res.m_quadIndexBuffer->GetID());
|
||||
m_gl.DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
@@ -1965,7 +2101,7 @@ void GpDisplayDriver_SDL_GL2::DrawSurface(IGpDisplayDriverSurface *surface, int3
|
||||
m_gl.ActiveTexture(GL_TEXTURE0);
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_quadVertexArray->Deactivate(vpos);
|
||||
m_res.m_quadVertexArray->Deactivate(vpos);
|
||||
|
||||
m_gl.UseProgram(0);
|
||||
|
||||
@@ -2032,8 +2168,11 @@ void GpDisplayDriver_SDL_GL2::SetStandardCursor(EGpStandardCursor_t standardCurs
|
||||
|
||||
void GpDisplayDriver_SDL_GL2::UpdatePalette(const void *paletteData)
|
||||
{
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_paletteTexture->GetID());
|
||||
m_gl.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, paletteData);
|
||||
memcpy(m_paletteData, paletteData, 256 * 4);
|
||||
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_res.m_paletteTexture->GetID());
|
||||
m_gl.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
m_gl.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_paletteData);
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
@@ -2093,6 +2232,15 @@ bool GpDisplayDriver_SDL_GL2::SavePrefs(void *context, WritePrefsFunc_t writeFun
|
||||
return true;
|
||||
}
|
||||
|
||||
void GpDisplayDriver_SDL_GL2::UnlinkSurface(GpDisplayDriverSurface_GL2 *surface, GpDisplayDriverSurface_GL2 *prev, GpDisplayDriverSurface_GL2 *next)
|
||||
{
|
||||
if (m_lastSurface == surface)
|
||||
m_lastSurface = prev;
|
||||
|
||||
if (m_firstSurface == surface)
|
||||
m_firstSurface = next;
|
||||
}
|
||||
|
||||
const GpGLFunctions *GpDisplayDriver_SDL_GL2::GetGLFunctions() const
|
||||
{
|
||||
return &m_gl;
|
||||
@@ -2154,8 +2302,8 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t virtualWidth, uint32_t virt
|
||||
{
|
||||
const uint16_t indexBufferData[] = { 0, 1, 2, 1, 3, 2 };
|
||||
|
||||
m_quadIndexBuffer = GpGLBuffer::Create(this);
|
||||
if (!m_quadIndexBuffer)
|
||||
m_res.m_quadIndexBuffer = GpGLBuffer::Create(this);
|
||||
if (!m_res.m_quadIndexBuffer)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriver_SDL_GL2::InitResources: CreateBuffer for draw quad index buffer failed");
|
||||
@@ -2163,7 +2311,7 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t virtualWidth, uint32_t virt
|
||||
return false;
|
||||
}
|
||||
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadIndexBuffer->GetID());
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_res.m_quadIndexBuffer->GetID());
|
||||
m_gl.BufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexBufferData), indexBufferData, GL_STATIC_DRAW);
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
@@ -2178,8 +2326,8 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t virtualWidth, uint32_t virt
|
||||
1.f, 1.f,
|
||||
};
|
||||
|
||||
m_quadVertexBufferKeepalive = GpGLBuffer::Create(this);
|
||||
if (!m_quadVertexBufferKeepalive)
|
||||
m_res.m_quadVertexBufferKeepalive = GpGLBuffer::Create(this);
|
||||
if (!m_res.m_quadVertexBufferKeepalive)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriver_SDL_GL2::InitResources: GpGLBuffer::Create for draw quad vertex buffer failed");
|
||||
@@ -2187,12 +2335,12 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t virtualWidth, uint32_t virt
|
||||
return false;
|
||||
}
|
||||
|
||||
m_gl.BindBuffer(GL_ARRAY_BUFFER, m_quadVertexBufferKeepalive->GetID());
|
||||
m_gl.BindBuffer(GL_ARRAY_BUFFER, m_res.m_quadVertexBufferKeepalive->GetID());
|
||||
m_gl.BufferData(GL_ARRAY_BUFFER, sizeof(vertexBufferData), vertexBufferData, GL_STATIC_DRAW);
|
||||
m_gl.BindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
m_quadVertexArray = GpGLVertexArray::Create(this);
|
||||
if (!m_quadVertexBufferKeepalive)
|
||||
m_res.m_quadVertexArray = GpGLVertexArray::Create(this);
|
||||
if (!m_res.m_quadVertexBufferKeepalive)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriver_SDL_GL2::InitResources: GpGLVertexArray::Create for draw quad vertex buffer failed");
|
||||
@@ -2202,7 +2350,7 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t virtualWidth, uint32_t virt
|
||||
|
||||
GpGLVertexArraySpec specs[] =
|
||||
{
|
||||
m_quadVertexBufferKeepalive,
|
||||
m_res.m_quadVertexBufferKeepalive,
|
||||
0, // index
|
||||
2, // size
|
||||
GL_FLOAT, // type
|
||||
@@ -2211,7 +2359,7 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t virtualWidth, uint32_t virt
|
||||
0
|
||||
};
|
||||
|
||||
if (!m_quadVertexArray->InitWithSpecs(specs, sizeof(specs) / sizeof(specs[0])))
|
||||
if (!m_res.m_quadVertexArray->InitWithSpecs(specs, sizeof(specs) / sizeof(specs[0])))
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriver_SDL_GL2::InitResources: InitWithSpecs for draw quad vertex buffer failed");
|
||||
@@ -2232,31 +2380,22 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t virtualWidth, uint32_t virt
|
||||
GpComPtr<GpGLShader<GL_FRAGMENT_SHADER>> scaleQuadPixelShader = CreateShader<GL_FRAGMENT_SHADER>(GpBinarizedShaders::g_scaleQuadP_GL2);
|
||||
GpComPtr<GpGLShader<GL_FRAGMENT_SHADER>> copyQuadPixelShader = CreateShader<GL_FRAGMENT_SHADER>(GpBinarizedShaders::g_copyQuadP_GL2);
|
||||
|
||||
if (!m_drawQuadPaletteFlickerProgram.Link(this, drawQuadVertexShader, drawQuadPaletteFlickerPixelShader)
|
||||
|| !m_drawQuadPaletteNoFlickerProgram.Link(this, drawQuadVertexShader, drawQuadPaletteFlickerPixelShader)
|
||||
if (!m_res.m_drawQuadPaletteFlickerProgram.Link(this, drawQuadVertexShader, drawQuadPaletteFlickerPixelShader)
|
||||
|| !m_res.m_drawQuadPaletteNoFlickerProgram.Link(this, drawQuadVertexShader, drawQuadPaletteFlickerPixelShader)
|
||||
//|| !m_drawQuadRGBProgram.Link(this, drawQuadVertexShader, drawQuadRGBPixelShader)
|
||||
//|| !m_drawQuad15BitProgram.Link(this, drawQuadVertexShader, drawQuad15BitPixelShader)
|
||||
|| !m_drawQuadPaletteICCFlickerProgram.Link(this, drawQuadVertexShader, drawQuadPaletteICCFPixelShader)
|
||||
|| !m_drawQuadPaletteICCNoFlickerProgram.Link(this, drawQuadVertexShader, drawQuadPaletteICCNFPixelShader)
|
||||
|| !m_res.m_drawQuadPaletteICCFlickerProgram.Link(this, drawQuadVertexShader, drawQuadPaletteICCFPixelShader)
|
||||
|| !m_res.m_drawQuadPaletteICCNoFlickerProgram.Link(this, drawQuadVertexShader, drawQuadPaletteICCNFPixelShader)
|
||||
//|| !m_drawQuadRGBICCProgram.Link(this, drawQuadVertexShader, drawQuadRGBICCPixelShader)
|
||||
//|| !m_drawQuad15BitICCProgram.Link(this, drawQuadVertexShader, drawQuad15BitICCPixelShader)
|
||||
|| !m_scaleQuadProgram.Link(this, drawQuadVertexShader, scaleQuadPixelShader)
|
||||
|| !m_copyQuadProgram.Link(this, drawQuadVertexShader, copyQuadPixelShader))
|
||||
|| !m_res.m_scaleQuadProgram.Link(this, drawQuadVertexShader, scaleQuadPixelShader)
|
||||
|| !m_res.m_copyQuadProgram.Link(this, drawQuadVertexShader, copyQuadPixelShader))
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
// Palette texture
|
||||
{
|
||||
uint8_t initialDataBytes[256][4];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
for (int ch = 0; ch < 4; ch++)
|
||||
initialDataBytes[i][ch] = 255;
|
||||
}
|
||||
|
||||
m_paletteTexture = GpGLTexture::Create(this);
|
||||
if (!m_paletteTexture)
|
||||
m_res.m_paletteTexture = GpGLTexture::Create(this);
|
||||
if (!m_res.m_paletteTexture)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriver_SDL_GL2::InitResources: GpGLTexture::Create failed");
|
||||
@@ -2264,9 +2403,9 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t virtualWidth, uint32_t virt
|
||||
return false;
|
||||
}
|
||||
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_paletteTexture->GetID());
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_res.m_paletteTexture->GetID());
|
||||
m_gl.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
m_gl.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, initialDataBytes);
|
||||
m_gl.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_paletteData);
|
||||
m_gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
m_gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
m_gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
@@ -2387,14 +2526,10 @@ bool GpDisplayDriver_SDL_GL2::ResizeOpenGLWindow(uint32_t &windowWidth, uint32_t
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "ResizeOpenGLWindow: %i x %i", static_cast<int>(desiredWidth), static_cast<int>(desiredHeight));
|
||||
|
||||
if (desiredWidth < 640)
|
||||
desiredWidth = 640;
|
||||
else if (desiredWidth > 32768)
|
||||
if (desiredWidth > 32768)
|
||||
desiredWidth = 32768;
|
||||
|
||||
if (desiredHeight < 480)
|
||||
desiredHeight = 480;
|
||||
else if (desiredHeight > 32768)
|
||||
if (desiredHeight > 32768)
|
||||
desiredHeight = 32768;
|
||||
|
||||
if (logger)
|
||||
@@ -2416,8 +2551,8 @@ bool GpDisplayDriver_SDL_GL2::InitBackBuffer(uint32_t width, uint32_t height)
|
||||
logger->Printf(IGpLogDriver::Category_Information, "GpDisplayDriver_SDL_GL2::InitBackBuffer");
|
||||
|
||||
{
|
||||
m_virtualScreenTexture = GpGLTexture::Create(this);
|
||||
if (!m_virtualScreenTexture)
|
||||
m_res.m_virtualScreenTexture = GpGLTexture::Create(this);
|
||||
if (!m_res.m_virtualScreenTexture)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriver_SDL_GL2::InitBackBuffer: GpGLTexture::Create for virtual screen texture failed");
|
||||
@@ -2425,7 +2560,7 @@ bool GpDisplayDriver_SDL_GL2::InitBackBuffer(uint32_t width, uint32_t height)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_virtualScreenTexture->GetID());
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_res.m_virtualScreenTexture->GetID());
|
||||
m_gl.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
m_gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
m_gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
@@ -2436,9 +2571,9 @@ bool GpDisplayDriver_SDL_GL2::InitBackBuffer(uint32_t width, uint32_t height)
|
||||
}
|
||||
|
||||
{
|
||||
m_virtualScreenTextureRTV = GpGLRenderTargetView::Create(this);
|
||||
m_res.m_virtualScreenTextureRTV = GpGLRenderTargetView::Create(this);
|
||||
|
||||
if (!m_virtualScreenTextureRTV)
|
||||
if (!m_res.m_virtualScreenTextureRTV)
|
||||
{
|
||||
if (logger)
|
||||
logger->Printf(IGpLogDriver::Category_Error, "GpDisplayDriver_SDL_GL2::InitBackBuffer: GpGLRenderTargetView::Create for virtual screen texture failed");
|
||||
@@ -2446,8 +2581,8 @@ bool GpDisplayDriver_SDL_GL2::InitBackBuffer(uint32_t width, uint32_t height)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_gl.BindFramebuffer(GL_FRAMEBUFFER, m_virtualScreenTextureRTV->GetID());
|
||||
m_gl.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_virtualScreenTexture->GetID(), 0);
|
||||
m_gl.BindFramebuffer(GL_FRAMEBUFFER, m_res.m_virtualScreenTextureRTV->GetID());
|
||||
m_gl.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_res.m_virtualScreenTexture->GetID(), 0);
|
||||
GLenum status = m_gl.CheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
@@ -2471,7 +2606,7 @@ void GpDisplayDriver_SDL_GL2::ScaleVirtualScreen()
|
||||
|
||||
const bool isIntegralScale = (m_pixelScaleX == floor(m_pixelScaleX) && m_pixelScaleY == floor(m_pixelScaleY));
|
||||
|
||||
const BlitQuadProgram &program = isIntegralScale ? m_copyQuadProgram : m_scaleQuadProgram;
|
||||
const BlitQuadProgram &program = isIntegralScale ? m_res.m_copyQuadProgram : m_res.m_scaleQuadProgram;
|
||||
|
||||
{
|
||||
const float twoDivWidth = 2.0f / static_cast<float>(m_windowWidthPhysical);
|
||||
@@ -2514,13 +2649,13 @@ void GpDisplayDriver_SDL_GL2::ScaleVirtualScreen()
|
||||
|
||||
GLint attribLocations[] = { program.m_vertexPosUVLocation };
|
||||
|
||||
m_quadVertexArray->Activate(attribLocations);
|
||||
m_res.m_quadVertexArray->Activate(attribLocations);
|
||||
|
||||
m_gl.ActiveTexture(GL_TEXTURE0 + 0);
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_virtualScreenTexture->GetID());
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, m_res.m_virtualScreenTexture->GetID());
|
||||
m_gl.Uniform1i(program.m_pixelSurfaceTextureLocation, 0);
|
||||
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadIndexBuffer->GetID());
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_res.m_quadIndexBuffer->GetID());
|
||||
m_gl.DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
|
||||
|
||||
m_gl.UseProgram(0);
|
||||
@@ -2528,7 +2663,7 @@ void GpDisplayDriver_SDL_GL2::ScaleVirtualScreen()
|
||||
m_gl.ActiveTexture(GL_TEXTURE0 + 0);
|
||||
m_gl.BindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_quadVertexArray->Deactivate(attribLocations);
|
||||
m_res.m_quadVertexArray->Deactivate(attribLocations);
|
||||
|
||||
m_gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
@@ -2631,7 +2766,7 @@ GpDisplayDriverTickStatus_t GpDisplayDriver_SDL_GL2::PresentFrameAndSync()
|
||||
}
|
||||
|
||||
//ID3D11RenderTargetView *const rtv = m_backBufferRTV;
|
||||
GpGLRenderTargetView *const vsRTV = m_virtualScreenTextureRTV;
|
||||
GpGLRenderTargetView *const vsRTV = m_res.m_virtualScreenTextureRTV;
|
||||
|
||||
m_gl.BindFramebuffer(GL_FRAMEBUFFER, vsRTV->GetID());
|
||||
|
||||
|
||||
@@ -326,25 +326,24 @@ public:
|
||||
|
||||
void AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualHeight, float &pixelScaleX, float &pixelScaleY) override
|
||||
{
|
||||
if (physicalWidth < 640)
|
||||
physicalWidth = 640;
|
||||
|
||||
if (physicalHeight < 480)
|
||||
physicalHeight = 480;
|
||||
|
||||
double minMul = 1.0;
|
||||
|
||||
if (isAutoScale)
|
||||
if (isAutoScale || physicalWidth < 640 && physicalHeight < 480)
|
||||
{
|
||||
double xMul = static_cast<double>(physicalWidth) / 640.0;
|
||||
double yMul = static_cast<double>(physicalHeight) / 480.0;
|
||||
|
||||
minMul = std::min(xMul, yMul);
|
||||
|
||||
if (minMul >= 1.0)
|
||||
{
|
||||
double granularity = 2.0;
|
||||
|
||||
xMul = floor(xMul * granularity) / granularity;
|
||||
yMul = floor(yMul * granularity) / granularity;
|
||||
|
||||
minMul = std::max<double>(1.0, std::min(xMul, yMul));
|
||||
minMul = std::min(xMul, yMul);
|
||||
}
|
||||
}
|
||||
|
||||
virtualWidth = physicalWidth / minMul;
|
||||
|
||||
@@ -13,11 +13,14 @@
|
||||
#include "WindowManager.h"
|
||||
|
||||
int gpAppMain();
|
||||
void gpAppInit();
|
||||
|
||||
class GpAppInterfaceImpl final : public GpAppInterface
|
||||
{
|
||||
public:
|
||||
void ApplicationInit() override;
|
||||
int ApplicationMain() override;
|
||||
|
||||
void PL_IncrementTickCounter(uint32_t count) override;
|
||||
void PL_Render(IGpDisplayDriver *displayDriver) override;
|
||||
void PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) override;
|
||||
@@ -32,6 +35,10 @@ public:
|
||||
bool PL_AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY) override;
|
||||
};
|
||||
|
||||
void GpAppInterfaceImpl::ApplicationInit()
|
||||
{
|
||||
gpAppInit();
|
||||
}
|
||||
|
||||
int GpAppInterfaceImpl::ApplicationMain()
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "IGpDisplayDriver.h"
|
||||
#include "GpIOStream.h"
|
||||
#include "House.h"
|
||||
#include "MenuManager.h"
|
||||
#include "RenderedFont.h"
|
||||
#include "ResolveCachingColor.h"
|
||||
#include "WindowManager.h"
|
||||
@@ -425,6 +426,12 @@ void PreloadFonts()
|
||||
StepLoadScreen(1);
|
||||
}
|
||||
|
||||
void gpAppInit()
|
||||
{
|
||||
// This is called before the display driver is initialized
|
||||
InstallResolutionHandler();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- main
|
||||
// Here is main(). The first function called when Glider PRO comes up.
|
||||
|
||||
@@ -439,7 +446,9 @@ int gpAppMain()
|
||||
|
||||
ToolBoxInit();
|
||||
CheckOurEnvirons();
|
||||
InstallResolutionHandler();
|
||||
|
||||
if (thisMac.isTouchscreen)
|
||||
PortabilityLayer::MenuManager::GetInstance()->SetMenuTouchScreenStyle(true);
|
||||
|
||||
if (!thisMac.hasColor)
|
||||
RedAlert(kErrNeedColorQD);
|
||||
|
||||
@@ -224,7 +224,10 @@ void OpenMainWindow (void)
|
||||
mainWindowRect.bottom - mainWindowRect.top, false);
|
||||
|
||||
const short mainWindowLeft = (thisMac.fullScreen.left + thisMac.fullScreen.right + thisMac.constrainedScreen.left - thisMac.constrainedScreen.right) / 2;
|
||||
const short mainWindowTop = (thisMac.fullScreen.top + thisMac.fullScreen.bottom + thisMac.constrainedScreen.top - thisMac.constrainedScreen.bottom) / 2 + kScoreboardTall;
|
||||
short mainWindowTop = (thisMac.fullScreen.top + thisMac.fullScreen.bottom + thisMac.constrainedScreen.top - thisMac.constrainedScreen.bottom) / 2;
|
||||
|
||||
if (!PortabilityLayer::MenuManager::GetInstance()->IsMenuTouchScreenStyle())
|
||||
mainWindowTop += kScoreboardTall;
|
||||
|
||||
MoveWindow(boardWindow, mainWindowLeft, 0, true);
|
||||
MoveWindow(mainWindow, mainWindowLeft, mainWindowTop, true); // thisMac.menuHigh
|
||||
|
||||
@@ -711,7 +711,7 @@ bool ExportSourceToStream (GpIOStream *stream)
|
||||
|
||||
void DoExportSourceCode (void)
|
||||
{
|
||||
GpIOStream *stream = PortabilityLayer::HostFileSystem::GetInstance()->OpenFile(PortabilityLayer::VirtualDirectories::kPrefs, "SourceExport.zip", true, GpFileCreationDispositions::kCreateOrOverwrite);
|
||||
GpIOStream *stream = PortabilityLayer::HostFileSystem::GetInstance()->OpenFile(PortabilityLayer::VirtualDirectories::kSourceExport, "SourceExport.zip", true, GpFileCreationDispositions::kCreateOrOverwrite);
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
|
||||
@@ -26,13 +26,14 @@ struct GpDisplayDriverSurfaceEffects
|
||||
// Display drivers are responsible for timing and calling the game tick function.
|
||||
struct IGpDisplayDriver
|
||||
{
|
||||
public:
|
||||
typedef void (*SurfaceInvalidateCallback_t) (void *context);
|
||||
|
||||
virtual void Run() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual void GetDisplayResolution(unsigned int *width, unsigned int *height) = 0;
|
||||
|
||||
virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat) = 0;
|
||||
virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext) = 0;
|
||||
virtual void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects) = 0;
|
||||
|
||||
virtual IGpCursor *CreateBWCursor(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY) = 0;
|
||||
|
||||
8
GpCommon/IGpThreadRelay.h
Normal file
8
GpCommon/IGpThreadRelay.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
struct IGpThreadRelay
|
||||
{
|
||||
typedef void (*Callback_t) (void *context);
|
||||
|
||||
virtual void Invoke(Callback_t callback, void *context) const = 0;
|
||||
};
|
||||
@@ -1248,7 +1248,7 @@ void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned in
|
||||
*height = m_windowHeightVirtual;
|
||||
}
|
||||
|
||||
IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat)
|
||||
IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, IGpDisplayDriver::SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext)
|
||||
{
|
||||
return GpDisplayDriverSurfaceD3D11::Create(m_device, m_deviceContext, width, height, pixelFormat);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
|
||||
void GetDisplayResolution(unsigned int *width, unsigned int *height) override;
|
||||
|
||||
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat) override;
|
||||
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, IGpDisplayDriver::SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext) override;
|
||||
void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects) override;
|
||||
|
||||
IGpCursor *CreateColorCursor(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY) override;
|
||||
|
||||
@@ -34,6 +34,7 @@ GpAppEnvironment::~GpAppEnvironment()
|
||||
|
||||
void GpAppEnvironment::Init()
|
||||
{
|
||||
GpAppInterface_Get()->ApplicationInit();
|
||||
}
|
||||
|
||||
GpDisplayDriverTickStatus_t GpAppEnvironment::Tick(IGpFiber *vosFiber)
|
||||
@@ -196,7 +197,7 @@ void GpAppEnvironment::DispatchSystemCall(PortabilityLayer::HostSuspendCallID ca
|
||||
m_delaySuspendTicks = 1;
|
||||
break;
|
||||
case PortabilityLayer::HostSuspendCallID_CallOnVOSThread:
|
||||
args[0].m_functionPtr(static_cast<const PortabilityLayer::HostSuspendCallArgument*>(args[1].m_constPointer), static_cast<PortabilityLayer::HostSuspendCallArgument*>(args[2].m_pointer));
|
||||
args[0].m_functionPtr(args[1].m_pointer);
|
||||
m_applicationState = ApplicationState_Running;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -37,6 +37,7 @@ struct IGpDisplayDriver;
|
||||
class GpAppInterface
|
||||
{
|
||||
public:
|
||||
virtual void ApplicationInit() = 0;
|
||||
virtual int ApplicationMain() = 0;
|
||||
virtual void PL_IncrementTickCounter(uint32_t count) = 0;
|
||||
virtual void PL_Render(IGpDisplayDriver *displayDriver) = 0;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
class GpIOStream;
|
||||
struct IGpThreadRelay;
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
@@ -31,6 +32,8 @@ namespace PortabilityLayer
|
||||
|
||||
GpIOStream *OpenFile(VirtualDirectory_t virtualDirectory, const char *path, bool writeAccess, GpFileCreationDisposition_t createDisposition);
|
||||
|
||||
virtual void SetMainThreadRelay(IGpThreadRelay *relay) = 0;
|
||||
|
||||
private:
|
||||
static HostFileSystem *ms_instance;
|
||||
};
|
||||
|
||||
@@ -13,6 +13,6 @@ namespace PortabilityLayer
|
||||
size_t m_size;
|
||||
void *m_pointer;
|
||||
const void *m_constPointer;
|
||||
void (*m_functionPtr)(const HostSuspendCallArgument *args, HostSuspendCallArgument *returnValue);
|
||||
void (*m_functionPtr)(void *context);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -159,6 +159,9 @@ namespace PortabilityLayer
|
||||
|
||||
void RenderFrame(IGpDisplayDriver *displayDriver) override;
|
||||
|
||||
void SetMenuTouchScreenStyle(bool isTouchScreen) override;
|
||||
bool IsMenuTouchScreenStyle() const override;
|
||||
|
||||
static MenuManagerImpl *GetInstance();
|
||||
|
||||
private:
|
||||
@@ -199,13 +202,18 @@ namespace PortabilityLayer
|
||||
void ProcessMouseMoveToMenuBar(const Vec2i &point);
|
||||
void ProcessMouseMoveToMenu(const Vec2i &point);
|
||||
|
||||
bool IsYInMenuBarRange(int32_t y) const;
|
||||
|
||||
static bool ItemIsSeparator(const Menu &menu, const MenuItem &item);
|
||||
|
||||
static const unsigned int kIconResID = 128;
|
||||
static const unsigned int kMenuFontSize = 12;
|
||||
static const unsigned int kTouchScreenMenuFontSize = 24;
|
||||
static const unsigned int kMenuBarIconYOffset = 2;
|
||||
static const unsigned int kMenuBarTextYOffset = 14;
|
||||
static const unsigned int kTouchScreenMenuBarTextYOffset = 26;
|
||||
static const unsigned int kMenuBarHeight = 20;
|
||||
static const unsigned int kTouchscreenMenuBarHeight = 38;
|
||||
static const unsigned int kMenuBarItemPadding = 6;
|
||||
static const unsigned int kMenuBarInitialPadding = 16;
|
||||
|
||||
@@ -223,6 +231,7 @@ namespace PortabilityLayer
|
||||
static const unsigned int kMenuItemLeftPadding = 16 + 2 + 2; // 2 for left border, 16 for icon, 2 for spacing
|
||||
|
||||
static const int kMenuFontFlags = PortabilityLayer::FontFamilyFlag_Bold;
|
||||
static const int kTouchScreenMenuFontFlags = PortabilityLayer::FontFamilyFlag_None;
|
||||
|
||||
DrawSurface *m_menuBarGraf;
|
||||
|
||||
@@ -231,6 +240,7 @@ namespace PortabilityLayer
|
||||
bool m_haveMenuBarLayout;
|
||||
bool m_haveIcon;
|
||||
bool m_menuBarVisible;
|
||||
bool m_isTouchScreen;
|
||||
|
||||
uint8_t m_iconColors[16 * 16];
|
||||
uint8_t m_iconMask[32];
|
||||
@@ -252,6 +262,7 @@ namespace PortabilityLayer
|
||||
, m_haveIcon(false)
|
||||
, m_iconGraphic(nullptr)
|
||||
, m_menuBarVisible(false)
|
||||
, m_isTouchScreen(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -634,7 +645,7 @@ namespace PortabilityLayer
|
||||
|
||||
bool MenuManagerImpl::IsPointInMenuBar(const Vec2i &point) const
|
||||
{
|
||||
return point.m_y >= 0 && static_cast<uint32_t>(point.m_y) < kMenuBarHeight;
|
||||
return IsYInMenuBarRange(point.m_y);
|
||||
}
|
||||
|
||||
uint16_t MenuManagerImpl::GetMenuBarHeight() const
|
||||
@@ -829,7 +840,9 @@ namespace PortabilityLayer
|
||||
|
||||
PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance();
|
||||
|
||||
const Rect menuRect = Rect::Create(0, 0, kMenuBarHeight, width);
|
||||
const int16_t menuHeight = m_isTouchScreen ? kTouchscreenMenuBarHeight : kMenuBarHeight;
|
||||
|
||||
const Rect menuRect = Rect::Create(0, 0, menuHeight, width);
|
||||
|
||||
if (m_menuBarGraf == nullptr)
|
||||
{
|
||||
@@ -863,7 +876,7 @@ namespace PortabilityLayer
|
||||
|
||||
// Left stripe
|
||||
{
|
||||
const Rect rect = Rect::Create(0, 0, kMenuBarHeight - 1, 1);
|
||||
const Rect rect = Rect::Create(0, 0, menuHeight - 1, 1);
|
||||
m_menuBarGraf->FillRect(rect, barBrightColor);
|
||||
}
|
||||
|
||||
@@ -871,13 +884,13 @@ namespace PortabilityLayer
|
||||
|
||||
// Bottom stripe
|
||||
{
|
||||
const Rect rect = Rect::Create(kMenuBarHeight - 2, 1, kMenuBarHeight - 1, width);
|
||||
const Rect rect = Rect::Create(menuHeight - 2, 1, menuHeight - 1, width);
|
||||
m_menuBarGraf->FillRect(rect, barDarkColor);
|
||||
}
|
||||
|
||||
// Right stripe
|
||||
{
|
||||
const Rect rect = Rect::Create(0, width - 1, kMenuBarHeight - 1, width);
|
||||
const Rect rect = Rect::Create(0, width - 1, menuHeight - 1, width);
|
||||
m_menuBarGraf->FillRect(rect, barDarkColor);
|
||||
}
|
||||
|
||||
@@ -885,7 +898,7 @@ namespace PortabilityLayer
|
||||
|
||||
// Bottom edge
|
||||
{
|
||||
const Rect rect = Rect::Create(kMenuBarHeight - 1, 0, kMenuBarHeight, width);
|
||||
const Rect rect = Rect::Create(menuHeight - 1, 0, menuHeight, width);
|
||||
m_menuBarGraf->FillRect(rect, barBottomEdgeColor);
|
||||
}
|
||||
|
||||
@@ -917,20 +930,31 @@ namespace PortabilityLayer
|
||||
// Middle
|
||||
{
|
||||
ResolveCachingColor barHighlightMidColor = gs_barHighlightMidColor;
|
||||
const Rect rect = Rect::Create(1, left, kMenuBarHeight - 2, right);
|
||||
const Rect rect = Rect::Create(1, left, menuHeight - 2, right);
|
||||
m_menuBarGraf->FillRect(rect, barHighlightMidColor);
|
||||
}
|
||||
|
||||
{
|
||||
ResolveCachingColor barHighlightDarkColor = gs_barHighlightDarkColor;
|
||||
const Rect rect = Rect::Create(kMenuBarHeight - 2, left, kMenuBarHeight - 1, right);
|
||||
const Rect rect = Rect::Create(menuHeight - 2, left, menuHeight - 1, right);
|
||||
m_menuBarGraf->FillRect(rect, barHighlightDarkColor);
|
||||
}
|
||||
}
|
||||
|
||||
// Text items
|
||||
ResolveCachingColor barNormalTextColor = gs_barNormalTextColor;
|
||||
PortabilityLayer::RenderedFont *sysFont = GetSystemFont(kMenuFontSize, PortabilityLayer::FontFamilyFlag_Bold, true);
|
||||
PortabilityLayer::RenderedFont *sysFont = nullptr;
|
||||
unsigned int textYOffset = 0;
|
||||
if (m_isTouchScreen)
|
||||
{
|
||||
sysFont = GetApplicationFont(kTouchScreenMenuFontSize, kTouchScreenMenuFontFlags, true);
|
||||
textYOffset = kTouchScreenMenuBarTextYOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
sysFont = GetSystemFont(kMenuFontSize, kMenuFontFlags, true);
|
||||
textYOffset = kMenuBarTextYOffset;
|
||||
}
|
||||
|
||||
{
|
||||
Menu **menuHdl = m_firstMenu;
|
||||
@@ -951,7 +975,7 @@ namespace PortabilityLayer
|
||||
{
|
||||
if (menuHdl != selectedMenuHdl)
|
||||
{
|
||||
const Point itemPos = Point::Create(static_cast<int16_t>(xCoordinate), kMenuBarTextYOffset);
|
||||
const Point itemPos = Point::Create(static_cast<int16_t>(xCoordinate), textYOffset);
|
||||
graf->DrawString(itemPos, PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)), barNormalTextColor, sysFont);
|
||||
}
|
||||
}
|
||||
@@ -971,7 +995,7 @@ namespace PortabilityLayer
|
||||
|
||||
size_t xCoordinate = menu->cumulativeOffset + (menu->menuIndex * 2) * kMenuBarItemPadding + kMenuBarInitialPadding;
|
||||
|
||||
const Point itemPos = Point::Create(static_cast<int16_t>(xCoordinate), kMenuBarTextYOffset);
|
||||
const Point itemPos = Point::Create(static_cast<int16_t>(xCoordinate), textYOffset);
|
||||
graf->DrawString(itemPos, PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)), barHighlightTextColor, sysFont);
|
||||
}
|
||||
}
|
||||
@@ -1001,7 +1025,16 @@ namespace PortabilityLayer
|
||||
const PixMap *pixMap = *m_menuBarGraf->m_port.GetPixMap();
|
||||
const size_t width = pixMap->m_rect.right - pixMap->m_rect.left;
|
||||
const size_t height = pixMap->m_rect.bottom - pixMap->m_rect.top;
|
||||
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, 0, width, height, nullptr);
|
||||
int32_t y = 0;
|
||||
|
||||
if (m_isTouchScreen)
|
||||
{
|
||||
unsigned int displayHeight = 0;
|
||||
displayDriver->GetDisplayResolution(nullptr, &displayHeight);
|
||||
y = static_cast<int32_t>(displayHeight) - kTouchscreenMenuBarHeight;
|
||||
}
|
||||
|
||||
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, y, width, height, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1030,6 +1063,16 @@ namespace PortabilityLayer
|
||||
}
|
||||
}
|
||||
|
||||
void MenuManagerImpl::SetMenuTouchScreenStyle(bool isTouchScreenStyle)
|
||||
{
|
||||
m_isTouchScreen = isTouchScreenStyle;
|
||||
}
|
||||
|
||||
bool MenuManagerImpl::IsMenuTouchScreenStyle() const
|
||||
{
|
||||
return m_isTouchScreen;
|
||||
}
|
||||
|
||||
void MenuManagerImpl::RefreshMenuBarLayout()
|
||||
{
|
||||
if (m_haveMenuBarLayout)
|
||||
@@ -1037,11 +1080,29 @@ namespace PortabilityLayer
|
||||
|
||||
PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance();
|
||||
|
||||
PortabilityLayer::FontFamily *fontFamily = PortabilityLayer::FontManager::GetInstance()->GetSystemFont(kMenuFontSize, kMenuFontFlags);
|
||||
PortabilityLayer::FontFamily *fontFamily = nullptr;
|
||||
|
||||
unsigned int fontSize = 0;
|
||||
unsigned int fontFlags = 0;
|
||||
|
||||
if (m_isTouchScreen)
|
||||
{
|
||||
fontSize = kTouchScreenMenuFontSize;
|
||||
fontFlags = PortabilityLayer::FontFamilyFlag_None;
|
||||
fontFamily = PortabilityLayer::FontManager::GetInstance()->GetApplicationFont(kTouchScreenMenuFontSize, PortabilityLayer::FontFamilyFlag_None);
|
||||
}
|
||||
else
|
||||
{
|
||||
fontSize = kMenuFontSize;
|
||||
fontFlags = kMenuFontFlags;
|
||||
fontFamily = PortabilityLayer::FontManager::GetInstance()->GetSystemFont(kMenuFontSize, kMenuFontFlags);
|
||||
}
|
||||
|
||||
|
||||
if (!fontFamily)
|
||||
return;
|
||||
|
||||
PortabilityLayer::RenderedFont *rfont = PortabilityLayer::FontManager::GetInstance()->GetRenderedFontFromFamily(fontFamily, kMenuFontSize, true, kMenuFontFlags);
|
||||
PortabilityLayer::RenderedFont *rfont = PortabilityLayer::FontManager::GetInstance()->GetRenderedFontFromFamily(fontFamily, fontSize, true, fontFlags);
|
||||
if (!rfont)
|
||||
return;
|
||||
|
||||
@@ -1137,7 +1198,7 @@ namespace PortabilityLayer
|
||||
if (point.m_y < 0)
|
||||
return;
|
||||
|
||||
if (!m_menuSelectionState.IsPopup() && point.m_y < static_cast<int>(kMenuBarHeight))
|
||||
if (!m_menuSelectionState.IsPopup() && IsYInMenuBarRange(point.m_y))
|
||||
{
|
||||
m_menuSelectionState.ClearSelection();
|
||||
ProcessMouseMoveToMenuBar(point);
|
||||
@@ -1235,6 +1296,18 @@ namespace PortabilityLayer
|
||||
m_menuSelectionState.ClearSelection();
|
||||
}
|
||||
|
||||
bool MenuManagerImpl::IsYInMenuBarRange(int32_t y) const
|
||||
{
|
||||
if (m_isTouchScreen)
|
||||
{
|
||||
unsigned int displayHeight = 0;
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, &displayHeight);
|
||||
return y >= (static_cast<int32_t>(displayHeight - kTouchscreenMenuBarHeight)) && y < static_cast<int32_t>(displayHeight);
|
||||
}
|
||||
else
|
||||
return y >= 0 && y < static_cast<int32_t>(kMenuBarHeight);
|
||||
}
|
||||
|
||||
bool MenuManagerImpl::ItemIsSeparator(const Menu &menu, const MenuItem &item)
|
||||
{
|
||||
const uint8_t *strBlob = static_cast<const uint8_t*>(menu.stringBlobHandle->m_contents);
|
||||
|
||||
@@ -54,6 +54,9 @@ namespace PortabilityLayer
|
||||
|
||||
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
|
||||
|
||||
virtual void SetMenuTouchScreenStyle(bool isTouchScreenStyle) = 0;
|
||||
virtual bool IsMenuTouchScreenStyle() const = 0;
|
||||
|
||||
static MenuManager *GetInstance();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "HostVOSEventQueue.h"
|
||||
#include "IGpCursor.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
#include "IGpThreadRelay.h"
|
||||
#include "InputManager.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "MacFileInfo.h"
|
||||
@@ -47,6 +48,29 @@
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
class PLMainThreadRelay final : public IGpThreadRelay
|
||||
{
|
||||
public:
|
||||
void Invoke(Callback_t callback, void *context) const override;
|
||||
|
||||
static PLMainThreadRelay *GetInstance();
|
||||
|
||||
private:
|
||||
static PLMainThreadRelay ms_instance;
|
||||
};
|
||||
|
||||
void PLMainThreadRelay::Invoke(Callback_t callback, void *context) const
|
||||
{
|
||||
PLSysCalls::RunOnVOSThread(callback, context);
|
||||
}
|
||||
|
||||
PLMainThreadRelay *PLMainThreadRelay::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
PLMainThreadRelay PLMainThreadRelay::ms_instance;
|
||||
|
||||
static bool ConvertFilenameToSafePStr(const char *str, uint8_t *pstr)
|
||||
{
|
||||
const char *strBase = str;
|
||||
@@ -650,6 +674,8 @@ void PL_Init()
|
||||
PortabilityLayer::DisplayDeviceManager::GetInstance()->Init();
|
||||
PortabilityLayer::QDManager::GetInstance()->Init();
|
||||
PortabilityLayer::MenuManager::GetInstance()->Init();
|
||||
|
||||
PortabilityLayer::HostFileSystem::GetInstance()->SetMainThreadRelay(PLMainThreadRelay::GetInstance());
|
||||
}
|
||||
|
||||
WindowPtr PL_GetPutInFrontWindowPtr()
|
||||
|
||||
@@ -189,4 +189,13 @@ namespace PLSysCalls
|
||||
{
|
||||
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_ForceSyncFrame, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void RunOnVOSThread(void(*callback)(void *context), void *context)
|
||||
{
|
||||
PortabilityLayer::HostSuspendCallArgument args[2];
|
||||
args[0].m_functionPtr = callback;
|
||||
args[1].m_pointer = context;
|
||||
|
||||
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_CallOnVOSThread, args, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,5 @@ namespace PLSysCalls
|
||||
{
|
||||
void Sleep(uint32_t ticks);
|
||||
void ForceSyncFrame();
|
||||
void RunOnVOSThread(void(*callback)(void *context), void *context);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ void DrawSurface::PushToDDSurface(IGpDisplayDriver *displayDriver)
|
||||
}
|
||||
|
||||
if (m_ddSurface == nullptr)
|
||||
m_ddSurface = displayDriver->CreateSurface(pixMap->m_rect.right - pixMap->m_rect.left, pixMap->m_rect.bottom - pixMap->m_rect.top, pixMap->m_pitch, pixMap->m_pixelFormat);
|
||||
m_ddSurface = displayDriver->CreateSurface(pixMap->m_rect.right - pixMap->m_rect.left, pixMap->m_rect.bottom - pixMap->m_rect.top, pixMap->m_pitch, pixMap->m_pixelFormat, DrawSurface::StaticOnDriverInvalidate, this);
|
||||
|
||||
if (m_port.IsDirty(PortabilityLayer::QDPortDirtyFlag_Contents) && m_ddSurface != nullptr)
|
||||
{
|
||||
@@ -36,3 +36,13 @@ void DrawSurface::PushToDDSurface(IGpDisplayDriver *displayDriver)
|
||||
m_port.ClearDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSurface::StaticOnDriverInvalidate(void *context)
|
||||
{
|
||||
static_cast<DrawSurface*>(context)->OnDriverInvalidate();
|
||||
}
|
||||
|
||||
void DrawSurface::OnDriverInvalidate()
|
||||
{
|
||||
m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
|
||||
}
|
||||
|
||||
@@ -89,4 +89,8 @@ struct DrawSurface
|
||||
PortabilityLayer::RGBAColor m_cachedAAColor;
|
||||
|
||||
PortabilityLayer::QDPort m_port;
|
||||
|
||||
private:
|
||||
static void StaticOnDriverInvalidate(void *context);
|
||||
void OnDriverInvalidate();
|
||||
};
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace PortabilityLayer
|
||||
kCursors,
|
||||
kHighScores,
|
||||
kLogs,
|
||||
|
||||
kSourceExport,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1434,6 +1434,7 @@ namespace PortabilityLayer
|
||||
void WindowManagerImpl::HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight)
|
||||
{
|
||||
const uint32_t menuBarHeight = PortabilityLayer::MenuManager::GetInstance()->GetMenuBarHeight();
|
||||
const bool menuIsTouchScreen = PortabilityLayer::MenuManager::GetInstance()->IsMenuTouchScreenStyle();
|
||||
|
||||
for (PortabilityLayer::WindowImpl *window = m_windowStackTop; window != nullptr; window = window->GetWindowBelow())
|
||||
{
|
||||
@@ -1457,6 +1458,8 @@ namespace PortabilityLayer
|
||||
|
||||
int64_t newY = 0;
|
||||
int32_t currentY = window->GetPosition().m_y;
|
||||
if (!menuIsTouchScreen)
|
||||
{
|
||||
if (currentY < static_cast<int32_t>(menuBarHeight))
|
||||
newY = currentY;
|
||||
else
|
||||
@@ -1470,6 +1473,24 @@ namespace PortabilityLayer
|
||||
newY = (static_cast<int64_t>(currentY) - static_cast<int64_t>(menuBarHeight) - chromePadding[WindowChromeSides::kTop]) * static_cast<int64_t>(newClearanceY) / static_cast<int64_t>(prevClearanceY) + menuBarHeight + chromePadding[WindowChromeSides::kTop];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t heightWithoutMenu = surfaceRect.Height() - menuBarHeight;
|
||||
if (currentY + static_cast<int32_t>(paddedHeight) >= heightWithoutMenu)
|
||||
newY = currentY;
|
||||
else
|
||||
{
|
||||
if (newHeight <= (paddedHeight + menuBarHeight) || prevHeight <= paddedHeight + menuBarHeight)
|
||||
newY = (static_cast<int64_t>(newHeight) - paddedHeight - menuBarHeight) / 2 + menuBarHeight;
|
||||
else
|
||||
{
|
||||
uint32_t prevClearanceY = prevHeight - paddedHeight - menuBarHeight;
|
||||
uint32_t newClearanceY = newHeight - paddedHeight - menuBarHeight;
|
||||
newY = (static_cast<int64_t>(currentY) - static_cast<int64_t>(menuBarHeight) - chromePadding[WindowChromeSides::kTop]) * static_cast<int64_t>(newClearanceY) / static_cast<int64_t>(prevClearanceY) + chromePadding[WindowChromeSides::kTop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newX = std::max<int64_t>(0, std::min<int64_t>(newX, newWidth - 1));
|
||||
newY = std::max<int64_t>(0, std::min<int64_t>(newY, newHeight - 1));
|
||||
|
||||
Reference in New Issue
Block a user