Touchscreen things
@@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
GpSystemServices_Win32::GpSystemServices_Win32()
|
||||
: m_isTouchscreenSimulation(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -84,6 +85,20 @@ void GpSystemServices_Win32::Beep() const
|
||||
MessageBeep(MB_OK);
|
||||
}
|
||||
|
||||
bool GpSystemServices_Win32::IsTouchscreen() const
|
||||
{
|
||||
return m_isTouchscreenSimulation;
|
||||
}
|
||||
|
||||
bool GpSystemServices_Win32::IsUsingMouseAsTouch() const
|
||||
{
|
||||
return m_isTouchscreenSimulation;
|
||||
}
|
||||
|
||||
void GpSystemServices_Win32::SetTouchscreenSimulation(bool isTouchscreenSimulation)
|
||||
{
|
||||
m_isTouchscreenSimulation = isTouchscreenSimulation;
|
||||
}
|
||||
|
||||
GpSystemServices_Win32 *GpSystemServices_Win32::GetInstance()
|
||||
{
|
||||
|
@@ -22,10 +22,16 @@ public:
|
||||
PortabilityLayer::HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) override;
|
||||
uint64_t GetFreeMemoryCosmetic() const override;
|
||||
void Beep() const override;
|
||||
bool IsTouchscreen() const override;
|
||||
bool IsUsingMouseAsTouch() const override;
|
||||
|
||||
void SetTouchscreenSimulation(bool isTouchscreenSimulation);
|
||||
|
||||
static GpSystemServices_Win32 *GetInstance();
|
||||
|
||||
private:
|
||||
bool m_isTouchscreenSimulation;
|
||||
|
||||
static GpSystemServices_Win32 ms_instance;
|
||||
};
|
||||
|
||||
|
@@ -1,4 +1,268 @@
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include "GpFileSystem_Android.h"
|
||||
#include "GpIOStream.h"
|
||||
#include "VirtualDirectory.h"
|
||||
|
||||
#include "SDL_rwops.h"
|
||||
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
|
||||
class GpFileStream_SDLRWops final : public GpIOStream
|
||||
{
|
||||
public:
|
||||
GpFileStream_SDLRWops(SDL_RWops *f, bool readOnly, bool writeOnly);
|
||||
~GpFileStream_SDLRWops();
|
||||
|
||||
size_t Read(void *bytesOut, size_t size) override;
|
||||
size_t Write(const void *bytes, size_t size) override;
|
||||
bool IsSeekable() const override;
|
||||
bool IsReadOnly() const override;
|
||||
bool IsWriteOnly() const override;
|
||||
bool SeekStart(GpUFilePos_t loc) override;
|
||||
bool SeekCurrent(GpFilePos_t loc) override;
|
||||
bool SeekEnd(GpUFilePos_t loc) override;
|
||||
bool Truncate(GpUFilePos_t loc) override;
|
||||
GpUFilePos_t Size() const override;
|
||||
GpUFilePos_t Tell() const override;
|
||||
void Close() override;
|
||||
void Flush() override;
|
||||
|
||||
private:
|
||||
SDL_RWops *m_rw;
|
||||
bool m_isReadOnly;
|
||||
bool m_isWriteOnly;
|
||||
};
|
||||
|
||||
|
||||
GpFileStream_SDLRWops::GpFileStream_SDLRWops(SDL_RWops *f, bool readOnly, bool writeOnly)
|
||||
: m_rw(f)
|
||||
, m_isReadOnly(readOnly)
|
||||
, m_isWriteOnly(writeOnly)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GpFileStream_SDLRWops::~GpFileStream_SDLRWops()
|
||||
{
|
||||
m_rw->close(m_rw);
|
||||
}
|
||||
|
||||
size_t GpFileStream_SDLRWops::Read(void *bytesOut, size_t size)
|
||||
{
|
||||
return m_rw->read(m_rw, bytesOut, 1, size);
|
||||
}
|
||||
|
||||
size_t GpFileStream_SDLRWops::Write(const void *bytes, size_t size)
|
||||
{
|
||||
return m_rw->write(m_rw, bytes, 1, size);
|
||||
}
|
||||
|
||||
bool GpFileStream_SDLRWops::IsSeekable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpFileStream_SDLRWops::IsReadOnly() const
|
||||
{
|
||||
return m_isReadOnly;
|
||||
}
|
||||
|
||||
bool GpFileStream_SDLRWops::IsWriteOnly() const
|
||||
{
|
||||
return m_isWriteOnly;
|
||||
}
|
||||
|
||||
bool GpFileStream_SDLRWops::SeekStart(GpUFilePos_t loc)
|
||||
{
|
||||
return m_rw->seek(m_rw, static_cast<Sint64>(loc), RW_SEEK_SET) >= 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_SDLRWops::SeekCurrent(GpFilePos_t loc)
|
||||
{
|
||||
return m_rw->seek(m_rw, static_cast<Sint64>(loc), RW_SEEK_CUR) >= 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_SDLRWops::SeekEnd(GpUFilePos_t loc)
|
||||
{
|
||||
return m_rw->seek(m_rw, -static_cast<Sint64>(loc), RW_SEEK_END) >= 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_SDLRWops::Truncate(GpUFilePos_t loc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_SDLRWops::Size() const
|
||||
{
|
||||
return m_rw->size(m_rw);
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_SDLRWops::GpFileStream_SDLRWops::Tell() const
|
||||
{
|
||||
return SDL_RWtell(m_rw);
|
||||
}
|
||||
|
||||
void GpFileStream_SDLRWops::Close()
|
||||
{
|
||||
this->~GpFileStream_SDLRWops();
|
||||
free(this);
|
||||
}
|
||||
|
||||
void GpFileStream_SDLRWops::Flush()
|
||||
{
|
||||
}
|
||||
|
||||
class GpFileStream_Android_File final : public GpIOStream
|
||||
{
|
||||
public:
|
||||
GpFileStream_Android_File(FILE *f, int fd, bool readOnly, bool writeOnly);
|
||||
~GpFileStream_Android_File();
|
||||
|
||||
size_t Read(void *bytesOut, size_t size) override;
|
||||
size_t Write(const void *bytes, size_t size) override;
|
||||
bool IsSeekable() const override;
|
||||
bool IsReadOnly() const override;
|
||||
bool IsWriteOnly() const override;
|
||||
bool SeekStart(GpUFilePos_t loc) override;
|
||||
bool SeekCurrent(GpFilePos_t loc) override;
|
||||
bool SeekEnd(GpUFilePos_t loc) override;
|
||||
bool Truncate(GpUFilePos_t loc) override;
|
||||
GpUFilePos_t Size() const override;
|
||||
GpUFilePos_t Tell() const override;
|
||||
void Close() override;
|
||||
void Flush() override;
|
||||
|
||||
private:
|
||||
FILE *m_f;
|
||||
int m_fd;
|
||||
bool m_seekable;
|
||||
bool m_isReadOnly;
|
||||
bool m_isWriteOnly;
|
||||
};
|
||||
|
||||
GpFileStream_Android_File::GpFileStream_Android_File(FILE *f, int fd, bool readOnly, bool writeOnly)
|
||||
: m_f(f)
|
||||
, m_fd(fd)
|
||||
, m_isReadOnly(readOnly)
|
||||
, m_isWriteOnly(writeOnly)
|
||||
{
|
||||
m_seekable = (fseek(m_f, 0, SEEK_CUR) == 0);
|
||||
}
|
||||
|
||||
GpFileStream_Android_File::~GpFileStream_Android_File()
|
||||
{
|
||||
fclose(m_f);
|
||||
}
|
||||
|
||||
size_t GpFileStream_Android_File::Read(void *bytesOut, size_t size)
|
||||
{
|
||||
if (m_isWriteOnly)
|
||||
return 0;
|
||||
return fread(bytesOut, 1, size, m_f);
|
||||
}
|
||||
|
||||
size_t GpFileStream_Android_File::Write(const void *bytes, size_t size)
|
||||
{
|
||||
if (m_isReadOnly)
|
||||
return 0;
|
||||
return fwrite(bytes, 1, size, m_f);
|
||||
}
|
||||
|
||||
bool GpFileStream_Android_File::IsSeekable() const
|
||||
{
|
||||
return m_seekable;
|
||||
}
|
||||
|
||||
bool GpFileStream_Android_File::IsReadOnly() const
|
||||
{
|
||||
return m_isReadOnly;
|
||||
}
|
||||
|
||||
bool GpFileStream_Android_File::IsWriteOnly() const
|
||||
{
|
||||
return m_isWriteOnly;
|
||||
}
|
||||
|
||||
bool GpFileStream_Android_File::SeekStart(GpUFilePos_t loc)
|
||||
{
|
||||
if (!m_seekable)
|
||||
return false;
|
||||
|
||||
return lseek64(m_fd, static_cast<off64_t>(loc), SEEK_SET) >= 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_Android_File::SeekCurrent(GpFilePos_t loc)
|
||||
{
|
||||
if (!m_seekable)
|
||||
return false;
|
||||
|
||||
return lseek64(m_fd, static_cast<off64_t>(loc), SEEK_CUR) >= 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_Android_File::SeekEnd(GpUFilePos_t loc)
|
||||
{
|
||||
if (!m_seekable)
|
||||
return false;
|
||||
|
||||
return lseek64(m_fd, -static_cast<off64_t>(loc), SEEK_END) >= 0;
|
||||
}
|
||||
|
||||
bool GpFileStream_Android_File::Truncate(GpUFilePos_t loc)
|
||||
{
|
||||
return ftruncate64(m_fd, static_cast<off64_t>(loc)) >= 0;
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_Android_File::Size() const
|
||||
{
|
||||
struct stat64 s;
|
||||
if (fstat64(m_fd, &s) < 0)
|
||||
return 0;
|
||||
|
||||
return static_cast<GpUFilePos_t>(s.st_size);
|
||||
}
|
||||
|
||||
GpUFilePos_t GpFileStream_Android_File::Tell() const
|
||||
{
|
||||
return static_cast<GpUFilePos_t>(ftell(m_f));
|
||||
}
|
||||
|
||||
void GpFileStream_Android_File::Close()
|
||||
{
|
||||
this->~GpFileStream_Android_File();
|
||||
free(this);
|
||||
}
|
||||
|
||||
void GpFileStream_Android_File::Flush()
|
||||
{
|
||||
fflush(m_f);
|
||||
}
|
||||
|
||||
static bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, std::string &resolution, bool &isAsset)
|
||||
{
|
||||
isAsset = false;
|
||||
switch (virtualDirectory)
|
||||
{
|
||||
case PortabilityLayer::VirtualDirectories::kApplicationData:
|
||||
resolution = std::string("Packaged/") + path;
|
||||
isAsset = true;
|
||||
return true;
|
||||
case PortabilityLayer::VirtualDirectories::kGameData:
|
||||
resolution = std::string("Packaged/Houses/") + path;
|
||||
isAsset = true;
|
||||
return true;
|
||||
case PortabilityLayer::VirtualDirectories::kFonts:
|
||||
resolution = std::string("Resources/") + path;
|
||||
isAsset = true;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
GpFileSystem_Android::GpFileSystem_Android()
|
||||
{
|
||||
@@ -6,25 +270,140 @@ GpFileSystem_Android::GpFileSystem_Android()
|
||||
|
||||
bool GpFileSystem_Android::FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path)
|
||||
{
|
||||
std::string resolvedPath;
|
||||
bool isAsset;
|
||||
if (!ResolvePath(virtualDirectory, path, resolvedPath, isAsset))
|
||||
return false;
|
||||
|
||||
if (isAsset)
|
||||
{
|
||||
SDL_RWops *rw = SDL_RWFromFile(resolvedPath.c_str(), "rb");
|
||||
if (!rw)
|
||||
return false;
|
||||
SDL_RWclose(rw);
|
||||
}
|
||||
|
||||
struct stat s;
|
||||
return stat(resolvedPath.c_str(), &s) == 0;
|
||||
}
|
||||
|
||||
bool GpFileSystem_Android::FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool *exists)
|
||||
{
|
||||
std::string resolvedPath;
|
||||
bool isAsset;
|
||||
if (!ResolvePath(virtualDirectory, path, resolvedPath, isAsset))
|
||||
{
|
||||
*exists = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isAsset)
|
||||
return true;
|
||||
|
||||
int permissions = access(resolvedPath.c_str(), W_OK | F_OK);
|
||||
*exists = ((permissions & F_OK) != 0);
|
||||
return ((permissions & W_OK) != 0);
|
||||
}
|
||||
|
||||
GpIOStream *GpFileSystem_Android::OpenFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool writeAccess, GpFileCreationDisposition_t createDisposition)
|
||||
{
|
||||
const char *mode = nullptr;
|
||||
bool canWrite = false;
|
||||
|
||||
switch (createDisposition) {
|
||||
case GpFileCreationDispositions::kCreateOrOverwrite:
|
||||
mode = "w+b";
|
||||
break;
|
||||
case GpFileCreationDispositions::kCreateNew:
|
||||
mode = "x+b";
|
||||
break;
|
||||
case GpFileCreationDispositions::kCreateOrOpen:
|
||||
mode = "c+b";
|
||||
break;
|
||||
case GpFileCreationDispositions::kOpenExisting:
|
||||
mode = writeAccess ? "r+b" : "rb";
|
||||
break;
|
||||
case GpFileCreationDispositions::kOverwriteExisting:
|
||||
mode = "r+b";
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
std::string resolvedPath;
|
||||
bool isAsset;
|
||||
if (!ResolvePath(virtualDirectory, path, resolvedPath, isAsset))
|
||||
return nullptr;
|
||||
|
||||
if (isAsset)
|
||||
{
|
||||
if (createDisposition == GpFileCreationDispositions::kOverwriteExisting || writeAccess)
|
||||
return nullptr;
|
||||
|
||||
void *objStorage = malloc(sizeof(GpFileStream_SDLRWops));
|
||||
if (!objStorage)
|
||||
return nullptr;
|
||||
|
||||
SDL_RWops *rw = SDL_RWFromFile(resolvedPath.c_str(), mode);
|
||||
if (!rw)
|
||||
{
|
||||
free(objStorage);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new (objStorage) GpFileStream_SDLRWops(rw, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
void *objStorage = malloc(sizeof(GpFileStream_Android_File));
|
||||
if (!objStorage)
|
||||
return nullptr;
|
||||
|
||||
FILE *f = fopen(resolvedPath.c_str(), mode);
|
||||
if (!f)
|
||||
{
|
||||
free(objStorage);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int fd = fileno(f);
|
||||
|
||||
if (createDisposition == GpFileCreationDispositions::kOverwriteExisting)
|
||||
{
|
||||
if (ftruncate64(fd, 0) < 0)
|
||||
{
|
||||
free(objStorage);
|
||||
fclose(f);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return new (objStorage) GpFileStream_Android_File(f, fd, !writeAccess, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool GpFileSystem_Android::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed)
|
||||
{
|
||||
std::string resolvedPath;
|
||||
bool isAsset;
|
||||
if (!ResolvePath(virtualDirectory, path, resolvedPath, isAsset))
|
||||
{
|
||||
existed = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isAsset)
|
||||
return false;
|
||||
|
||||
if (unlink(resolvedPath.c_str()) < 0)
|
||||
{
|
||||
existed = (errno != ENOENT);
|
||||
return false;
|
||||
}
|
||||
existed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
PortabilityLayer::HostDirectoryCursor *GpFileSystem_Android::ScanDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory)
|
||||
{
|
||||
return nullptr;
|
||||
|
@@ -21,7 +21,5 @@ public:
|
||||
static GpFileSystem_Android *GetInstance();
|
||||
|
||||
private:
|
||||
bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, wchar_t *outPath);
|
||||
|
||||
static GpFileSystem_Android ms_instance;
|
||||
};
|
||||
|
1
AerofoilAndroid/app/src/main/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
assets
|
2
AerofoilAndroid/app/src/main/assets/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
Packaged
|
||||
Resources
|
@@ -17,6 +17,7 @@ mklink /D app\jni\zlib ..\..\..\zlib
|
||||
mklink /D app\jni\rapidjson ..\..\..\rapidjson
|
||||
mklink /D app\jni\MacRomanConversion ..\..\..\MacRomanConversion
|
||||
mklink /D app\jni\stb ..\..\..\stb
|
||||
mklink /D app\src\main\assets ..\..\..\..\Packaged
|
||||
mklink /D app\src\main\assets\Packaged ..\..\..\..\..\Packaged
|
||||
mklink /D app\src\main\assets\Resources ..\..\..\..\..\Resources
|
||||
|
||||
pause
|
||||
|
@@ -14,4 +14,5 @@ rmdir app\jni\zlib
|
||||
rmdir app\jni\rapidjson
|
||||
rmdir app\jni\MacRomanConversion
|
||||
rmdir app\jni\stb
|
||||
rmdir app\src\main\assets
|
||||
rmdir app\src\main\assets\Packaged
|
||||
rmdir app\src\main\assets\Resources
|
||||
|
@@ -50,6 +50,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
{
|
||||
if (!wcscmp(cmdLineArgs[i], L"-diagnostics"))
|
||||
GpLogDriver_Win32::Init();
|
||||
|
||||
if (!wcscmp(cmdLineArgs[i], L"-touchscreensimulation"))
|
||||
GpSystemServices_Win32::GetInstance()->SetTouchscreenSimulation(true);
|
||||
}
|
||||
|
||||
IGpLogDriver *logger = GpLogDriver_Win32::GetInstance();
|
||||
|
BIN
ApplicationResourcePatches/PICT/1973.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1974.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1975.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1976.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1977.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1978.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1979.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1980.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1981.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1982.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1983.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1984.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1985.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1986.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
ApplicationResourcePatches/PICT/1987.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
@@ -6,7 +6,22 @@
|
||||
"DITL/2001.json" : "ApplicationResourcePatches/DITL/2001.json",
|
||||
"DITL/2002.json" : "ApplicationResourcePatches/DITL/2002.json",
|
||||
"DITL/2003.json" : "ApplicationResourcePatches/DITL/2003.json",
|
||||
"DITL/2004.json" : "ApplicationResourcePatches/DITL/2004.json"
|
||||
"DITL/2004.json" : "ApplicationResourcePatches/DITL/2004.json",
|
||||
"PICT/1973.bmp" : "ApplicationResourcePatches/PICT/1973.bmp",
|
||||
"PICT/1974.bmp" : "ApplicationResourcePatches/PICT/1974.bmp",
|
||||
"PICT/1975.bmp" : "ApplicationResourcePatches/PICT/1975.bmp",
|
||||
"PICT/1976.bmp" : "ApplicationResourcePatches/PICT/1976.bmp",
|
||||
"PICT/1977.bmp" : "ApplicationResourcePatches/PICT/1977.bmp",
|
||||
"PICT/1978.bmp" : "ApplicationResourcePatches/PICT/1978.bmp",
|
||||
"PICT/1979.bmp" : "ApplicationResourcePatches/PICT/1979.bmp",
|
||||
"PICT/1980.bmp" : "ApplicationResourcePatches/PICT/1980.bmp",
|
||||
"PICT/1981.bmp" : "ApplicationResourcePatches/PICT/1981.bmp",
|
||||
"PICT/1982.bmp" : "ApplicationResourcePatches/PICT/1982.bmp",
|
||||
"PICT/1983.bmp" : "ApplicationResourcePatches/PICT/1983.bmp",
|
||||
"PICT/1984.bmp" : "ApplicationResourcePatches/PICT/1984.bmp",
|
||||
"PICT/1985.bmp" : "ApplicationResourcePatches/PICT/1985.bmp",
|
||||
"PICT/1986.bmp" : "ApplicationResourcePatches/PICT/1986.bmp",
|
||||
"PICT/1987.bmp" : "ApplicationResourcePatches/PICT/1987.bmp"
|
||||
},
|
||||
"delete" :
|
||||
[
|
||||
|
@@ -265,6 +265,9 @@ Boolean GetColorCursors (acurHandle ballCursH, compiledAcurHandle compiledBallCu
|
||||
|
||||
void InitAnimatedCursor (acurHandle ballCursH)
|
||||
{
|
||||
if (thisMac.isTouchscreen)
|
||||
return;
|
||||
|
||||
compiledAcurHandle compiledBallCursorH;
|
||||
|
||||
if (ballCursH == nil)
|
||||
@@ -275,7 +278,6 @@ void InitAnimatedCursor (acurHandle ballCursH)
|
||||
if (!compiledBallCursorH)
|
||||
RedAlert(kErrFailedResourceLoad);
|
||||
|
||||
GetColorCursors(ballCursH, compiledBallCursorH);
|
||||
DisposCursors();
|
||||
|
||||
animCursorH = ballCursH;
|
||||
@@ -335,8 +337,9 @@ void IncrementCursor (void)
|
||||
InitAnimatedCursor(nil);
|
||||
if (animCursorH)
|
||||
{
|
||||
(*animCursorH)->index++;
|
||||
(*animCursorH)->index %= (*animCursorH)->n;
|
||||
acurRec *acur = *animCursorH;
|
||||
acur->index++;
|
||||
acur->index %= acur->n;
|
||||
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor((*compiledAnimCursorH)->frame[(*animCursorH)->index].hwCursor);
|
||||
}
|
||||
|
@@ -301,6 +301,9 @@ void CheckOurEnvirons (void)
|
||||
thisMac.numScreens = HowManyUsableScreens(false, true, true);
|
||||
|
||||
thisMac.isResolutionDirty = true;
|
||||
thisMac.isTouchscreen = PortabilityLayer::HostSystemServices::GetInstance()->IsTouchscreen();
|
||||
thisMac.isMouseTouchscreen = PortabilityLayer::HostSystemServices::GetInstance()->IsUsingMouseAsTouch();
|
||||
|
||||
FlushResolutionChange();
|
||||
}
|
||||
|
||||
|
@@ -29,6 +29,8 @@ typedef struct
|
||||
Boolean hasQT;
|
||||
Boolean hasDrag;
|
||||
Boolean isResolutionDirty;
|
||||
Boolean isTouchscreen;
|
||||
Boolean isMouseTouchscreen;
|
||||
} macEnviron;
|
||||
|
||||
|
||||
|
@@ -362,4 +362,72 @@ typedef struct
|
||||
short object;
|
||||
} retroLink, *retroLinkPtr;
|
||||
|
||||
namespace TouchScreenCtrlIDs
|
||||
{
|
||||
enum TouchScreenCtrlID
|
||||
{
|
||||
None,
|
||||
|
||||
MoveLeft,
|
||||
MoveRight,
|
||||
Flip,
|
||||
Bands,
|
||||
BatteryHelium,
|
||||
|
||||
Count,
|
||||
};
|
||||
};
|
||||
|
||||
typedef TouchScreenCtrlIDs::TouchScreenCtrlID TouchScreenCtrlID_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fingerID;
|
||||
Point point;
|
||||
TouchScreenCtrlID_t capturingControl;
|
||||
} touchScreenFingerState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rect graphicRect;
|
||||
Rect touchRect;
|
||||
Boolean isEnabled;
|
||||
} touchScreenControl;
|
||||
|
||||
namespace touchScreenControlGraphics
|
||||
{
|
||||
enum touchScreenControlGraphic
|
||||
{
|
||||
BandsDisabled,
|
||||
BandsActive,
|
||||
BandsIdle,
|
||||
FlipActive,
|
||||
FlipIdle,
|
||||
MoveRightActive,
|
||||
MoveRightIdle,
|
||||
MoveLeftActive,
|
||||
MoveLeftIdle,
|
||||
HeliumDisabled,
|
||||
HeliumActive,
|
||||
HeliumIdle,
|
||||
BatteryDisabled,
|
||||
BatteryActive,
|
||||
BatteryIdle,
|
||||
|
||||
Count,
|
||||
};
|
||||
|
||||
static const int kTouchScreenGraphicStartID = 1973;
|
||||
}
|
||||
|
||||
typedef touchScreenControlGraphics::touchScreenControlGraphic touchScreenControlGraphic_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
static const int kMaxFingers = 4;
|
||||
|
||||
touchScreenControl controls[TouchScreenCtrlIDs::Count];
|
||||
touchScreenFingerState fingers[kMaxFingers];
|
||||
|
||||
DrawSurface *graphics[touchScreenControlGraphics::Count];
|
||||
} touchScreenControlState, *touchScreenControlStatePtr;
|
||||
|
208
GpApp/Play.cpp
@@ -13,9 +13,12 @@
|
||||
#include "Environ.h"
|
||||
#include "House.h"
|
||||
#include "MainWindow.h"
|
||||
#include "PLEventQueue.h"
|
||||
#include "PLTimeTaggedVOSEvent.h"
|
||||
#include "RectUtils.h"
|
||||
#include "ResolveCachingColor.h"
|
||||
#include "Scoreboard.h"
|
||||
#include "Utilities.h"
|
||||
|
||||
|
||||
#define kHouseBannerAlert 1009
|
||||
@@ -42,8 +45,6 @@ void HandleRoomVisitation (void);
|
||||
void SetObjectsToDefaults (void);
|
||||
void InitTelephone (void);
|
||||
void HandleTelephone (void);
|
||||
Boolean DoesStarCodeExist (short);
|
||||
short GetNumStarsRemaining (short, short);
|
||||
|
||||
|
||||
phoneType thePhone, theChimes;
|
||||
@@ -55,11 +56,14 @@ short batteryTotal, bandsTotal, foilTotal, mortals;
|
||||
Boolean playing, evenFrame, twoPlayerGame, showFoil, demoGoing;
|
||||
Boolean doBackground, playerSuicide, phoneBitSet, tvOn;
|
||||
|
||||
touchScreenControlState touchScreen;
|
||||
|
||||
extern VFileSpec *theHousesSpecs;
|
||||
extern demoPtr demoData;
|
||||
extern gameType smallGame;
|
||||
extern Rect gliderSrc[kNumGliderSrcRects];
|
||||
extern Rect boardDestRect, boardSrcRect;
|
||||
extern Rect localRoomsDest[];
|
||||
extern long incrementModeTime;
|
||||
extern short numBands, otherPlayerEscaped, demoIndex, demoHouseIndex;
|
||||
extern short splashOriginH, splashOriginV, countDown, thisHouseIndex;
|
||||
@@ -384,15 +388,215 @@ void HandleGameResolutionChange(void)
|
||||
DumpScreenOn(&justRoomsRect, true);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleTouchUp
|
||||
|
||||
void HandleTouchUp(int fingerID)
|
||||
{
|
||||
for (int i = 0; i < touchScreenControlState::kMaxFingers; i++)
|
||||
{
|
||||
if (touchScreen.fingers[i].fingerID == fingerID)
|
||||
{
|
||||
touchScreen.fingers[i].fingerID = -1;
|
||||
touchScreen.fingers[i].capturingControl = TouchScreenCtrlIDs::None;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleTouchMove
|
||||
|
||||
void HandleTouchMove(int fingerID, const Point &pt)
|
||||
{
|
||||
for (int i = 0; i < touchScreenControlState::kMaxFingers; i++)
|
||||
{
|
||||
if (touchScreen.fingers[i].fingerID == fingerID)
|
||||
{
|
||||
touchScreen.fingers[i].point = pt;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleTouchDown
|
||||
|
||||
void HandleTouchDown(int fingerID, const Point &pt)
|
||||
{
|
||||
int freeFingerIndex = -1;
|
||||
|
||||
for (int i = 0; i < touchScreenControlState::kMaxFingers; i++)
|
||||
{
|
||||
if (touchScreen.fingers[i].fingerID == fingerID)
|
||||
{
|
||||
// Finger is already considered down, something weird happened
|
||||
HandleTouchMove(fingerID, pt);
|
||||
return;
|
||||
}
|
||||
else if (touchScreen.fingers[i].fingerID < 0)
|
||||
freeFingerIndex = i;
|
||||
}
|
||||
|
||||
if (freeFingerIndex < 0)
|
||||
return;
|
||||
|
||||
touchScreenFingerState &fingerState = touchScreen.fingers[freeFingerIndex];
|
||||
|
||||
for (int j = 0; j < TouchScreenCtrlIDs::Count; j++)
|
||||
{
|
||||
if (touchScreen.controls[j].isEnabled)
|
||||
{
|
||||
if (touchScreen.controls[j].touchRect.Contains(pt))
|
||||
{
|
||||
fingerState.fingerID = fingerID;
|
||||
fingerState.capturingControl = static_cast<TouchScreenCtrlID_t>(j);
|
||||
fingerState.point = pt;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleTouchLeave
|
||||
|
||||
void HandleTouchLeave(int fingerID)
|
||||
{
|
||||
for (int i = 0; i < touchScreenControlState::kMaxFingers; i++)
|
||||
{
|
||||
if (touchScreen.fingers[i].fingerID == fingerID)
|
||||
{
|
||||
touchScreen.fingers[i].fingerID = -1;
|
||||
touchScreen.fingers[i].capturingControl = TouchScreenCtrlIDs::None;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleInGameEvents
|
||||
|
||||
void HandleInGameEvents(void)
|
||||
{
|
||||
PortabilityLayer::EventQueue *queue = PortabilityLayer::EventQueue::GetInstance();
|
||||
|
||||
TimeTaggedVOSEvent evt;
|
||||
while (queue->Dequeue(&evt))
|
||||
{
|
||||
if (thisMac.isTouchscreen)
|
||||
{
|
||||
if (thisMac.isMouseTouchscreen && evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
|
||||
{
|
||||
const GpMouseInputEvent &mouseInput = evt.m_vosEvent.m_event.m_mouseInputEvent;
|
||||
|
||||
const Point mousePt = mainWindow->MouseToLocal(mouseInput);
|
||||
|
||||
switch (mouseInput.m_eventType)
|
||||
{
|
||||
case GpMouseEventTypes::kDown:
|
||||
if (mouseInput.m_button == GpMouseButtons::kLeft)
|
||||
HandleTouchDown(0, mousePt);
|
||||
break;
|
||||
case GpMouseEventTypes::kLeave:
|
||||
HandleTouchLeave(0);
|
||||
break;
|
||||
case GpMouseEventTypes::kUp:
|
||||
HandleTouchMove(0, mousePt);
|
||||
HandleTouchUp(0);
|
||||
break;
|
||||
case GpMouseEventTypes::kMove:
|
||||
HandleTouchMove(0, mousePt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- ResetTouchScreenControlBounds
|
||||
|
||||
static int16_t touchScreenControlSize = 32;
|
||||
|
||||
void ResetTouchScreenControlBounds (void)
|
||||
{
|
||||
if (!thisMac.isTouchscreen)
|
||||
return;
|
||||
|
||||
|
||||
const Rect centerRoomRect = localRoomsDest[kCentralRoom];
|
||||
|
||||
int16_t touchScreenControlInterSpacing = 16;
|
||||
int16_t touchScreenControlEdgeSpacing = 24;
|
||||
|
||||
Point points[TouchScreenCtrlIDs::Count];
|
||||
Point sizes[TouchScreenCtrlIDs::Count];
|
||||
|
||||
points[TouchScreenCtrlIDs::MoveLeft] = Point::Create(mainWindowRect.left + touchScreenControlEdgeSpacing, mainWindowRect.bottom - touchScreenControlEdgeSpacing - touchScreenControlSize);
|
||||
points[TouchScreenCtrlIDs::MoveRight] = points[TouchScreenCtrlIDs::MoveLeft] + Point::Create(touchScreenControlInterSpacing + touchScreenControlSize, 0);
|
||||
|
||||
points[TouchScreenCtrlIDs::BatteryHelium] = Point::Create(mainWindowRect.right - touchScreenControlEdgeSpacing - touchScreenControlSize, mainWindowRect.bottom - touchScreenControlEdgeSpacing - touchScreenControlSize);
|
||||
points[TouchScreenCtrlIDs::Flip] = points[TouchScreenCtrlIDs::BatteryHelium] + Point::Create(0, -touchScreenControlInterSpacing - touchScreenControlSize);
|
||||
points[TouchScreenCtrlIDs::Bands] = points[TouchScreenCtrlIDs::BatteryHelium] + Point::Create(-touchScreenControlInterSpacing - touchScreenControlSize, 0);
|
||||
|
||||
for (int i = 0; i < TouchScreenCtrlIDs::Count; i++)
|
||||
sizes[i] = Point::Create(touchScreenControlSize, touchScreenControlSize);
|
||||
|
||||
for (int i = 0; i < TouchScreenCtrlIDs::Count; i++)
|
||||
{
|
||||
Point lowerRight = points[i] + sizes[i];
|
||||
touchScreen.controls[i].graphicRect = Rect::Create(points[i].v, points[i].h, lowerRight.v, lowerRight.h);
|
||||
touchScreen.controls[i].touchRect = touchScreen.controls[i].graphicRect.Inset(-(touchScreenControlInterSpacing / 2), -(touchScreenControlInterSpacing / 2));
|
||||
}
|
||||
|
||||
// Clear all active touches
|
||||
for (int i = 0; i < touchScreenControlState::kMaxFingers; i++)
|
||||
{
|
||||
touchScreen.fingers[i].fingerID = -1;
|
||||
touchScreen.fingers[i].capturingControl = TouchScreenCtrlIDs::None;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- InitTouchScreenControlState
|
||||
|
||||
void InitTouchScreenControlState(void)
|
||||
{
|
||||
if (!thisMac.isTouchscreen)
|
||||
return;
|
||||
|
||||
ResetTouchScreenControlBounds();
|
||||
|
||||
for (int i = 0; i < touchScreenControlGraphics::Count; i++)
|
||||
{
|
||||
if (touchScreen.graphics[i] != nil)
|
||||
continue;
|
||||
|
||||
int resID = touchScreenControlGraphics::kTouchScreenGraphicStartID + i;
|
||||
|
||||
Rect resRect = Rect::Create(0, 0, touchScreenControlSize, touchScreenControlSize);
|
||||
(void)CreateOffScreenGWorld(&touchScreen.graphics[i], &resRect);
|
||||
LoadGraphic(touchScreen.graphics[i], resID);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- PlayGame
|
||||
|
||||
void PlayGame (void)
|
||||
{
|
||||
InitTouchScreenControlState();
|
||||
|
||||
touchScreen.controls[TouchScreenCtrlIDs::MoveLeft].isEnabled = true;
|
||||
touchScreen.controls[TouchScreenCtrlIDs::MoveRight].isEnabled = true;
|
||||
touchScreen.controls[TouchScreenCtrlIDs::Flip].isEnabled = true;
|
||||
touchScreen.controls[TouchScreenCtrlIDs::Bands].isEnabled = true;
|
||||
touchScreen.controls[TouchScreenCtrlIDs::BatteryHelium].isEnabled = true;
|
||||
|
||||
while ((playing) && (!quitting))
|
||||
{
|
||||
HandleInGameEvents();
|
||||
|
||||
if (thisMac.isResolutionDirty)
|
||||
{
|
||||
HandleGameResolutionChange();
|
||||
ResetTouchScreenControlBounds();
|
||||
}
|
||||
|
||||
gameFrame++;
|
||||
|
@@ -29,6 +29,7 @@ void RenderSparkles (void);
|
||||
void RenderStars (void);
|
||||
void RenderBands (void);
|
||||
void RenderShreds (void);
|
||||
void RenderTouchScreenControls (void);
|
||||
void CopyRectsQD (void);
|
||||
|
||||
|
||||
@@ -55,6 +56,7 @@ extern short numBands, numStars, numShredded;
|
||||
extern short numSparkles, numFlyingPts, numPendulums, clockFrame;
|
||||
extern short numFlames, numSavedMaps, numTikiFlames, numCoals;
|
||||
extern Boolean evenFrame, shadowVisible, twoPlayerGame, tvOn;
|
||||
extern touchScreenControlState touchScreen;
|
||||
|
||||
|
||||
//============================================================== Functions
|
||||
@@ -604,6 +606,66 @@ void RenderShreds (void)
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- RenderTouchScreenControls
|
||||
|
||||
void RenderTouchScreenControls (void)
|
||||
{
|
||||
DrawSurface *ctrlGraphics[TouchScreenCtrlIDs::Count];
|
||||
|
||||
for (int i = 0; i < TouchScreenCtrlIDs::Count; i++)
|
||||
ctrlGraphics[i] = nullptr;
|
||||
|
||||
ctrlGraphics[TouchScreenCtrlIDs::MoveLeft] = touchScreen.graphics[touchScreenControlGraphics::MoveLeftIdle];
|
||||
ctrlGraphics[TouchScreenCtrlIDs::MoveRight] = touchScreen.graphics[touchScreenControlGraphics::MoveRightIdle];
|
||||
ctrlGraphics[TouchScreenCtrlIDs::Flip] = touchScreen.graphics[touchScreenControlGraphics::FlipIdle];
|
||||
ctrlGraphics[TouchScreenCtrlIDs::Bands] = touchScreen.graphics[touchScreenControlGraphics::BandsDisabled];
|
||||
ctrlGraphics[TouchScreenCtrlIDs::BatteryHelium] = touchScreen.graphics[touchScreenControlGraphics::BatteryDisabled];
|
||||
|
||||
if (batteryTotal < 0)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::BatteryHelium] = touchScreen.graphics[touchScreenControlGraphics::HeliumIdle];
|
||||
else if (batteryTotal > 0)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::BatteryHelium] = touchScreen.graphics[touchScreenControlGraphics::BatteryIdle];
|
||||
|
||||
if (bandsTotal > 0)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::Bands] = touchScreen.graphics[touchScreenControlGraphics::BandsIdle];
|
||||
|
||||
for (int i = 0; i < touchScreenControlState::kMaxFingers; i++)
|
||||
{
|
||||
if (touchScreen.fingers[i].capturingControl == TouchScreenCtrlIDs::BatteryHelium)
|
||||
{
|
||||
if (batteryTotal < 0)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::BatteryHelium] = touchScreen.graphics[touchScreenControlGraphics::HeliumActive];
|
||||
else if (batteryTotal > 0)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::BatteryHelium] = touchScreen.graphics[touchScreenControlGraphics::BandsActive];
|
||||
}
|
||||
else if (touchScreen.fingers[i].capturingControl == TouchScreenCtrlIDs::Bands)
|
||||
{
|
||||
if (bandsTotal > 0)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::Bands] = touchScreen.graphics[touchScreenControlGraphics::BandsActive];
|
||||
}
|
||||
else if (touchScreen.fingers[i].capturingControl == TouchScreenCtrlIDs::Flip)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::Flip] = touchScreen.graphics[touchScreenControlGraphics::FlipActive];
|
||||
else if (touchScreen.fingers[i].capturingControl == TouchScreenCtrlIDs::MoveLeft)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::MoveLeft] = touchScreen.graphics[touchScreenControlGraphics::MoveLeftActive];
|
||||
else if (touchScreen.fingers[i].capturingControl == TouchScreenCtrlIDs::MoveRight)
|
||||
ctrlGraphics[TouchScreenCtrlIDs::MoveRight] = touchScreen.graphics[touchScreenControlGraphics::MoveRightActive];
|
||||
}
|
||||
|
||||
for (int i = 0; i < TouchScreenCtrlIDs::Count; i++)
|
||||
{
|
||||
DrawSurface *graphic = ctrlGraphics[i];
|
||||
if (!graphic)
|
||||
continue;
|
||||
|
||||
const Rect sourceRect = ctrlGraphics[i]->m_port.GetRect();
|
||||
Rect destRect = touchScreen.controls[i].graphicRect;
|
||||
|
||||
CopyMask(*GetGWorldPixMap(ctrlGraphics[i]), *GetGWorldPixMap(ctrlGraphics[i]), *GetGWorldPixMap(workSrcMap), &sourceRect, &sourceRect, &destRect);
|
||||
AddRectToBackRects(&destRect);
|
||||
AddRectToWorkRects(&destRect);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- CopyRectsQD
|
||||
|
||||
void CopyRectsQD (void)
|
||||
@@ -655,6 +717,7 @@ void RenderFrame (void)
|
||||
RenderGlider(&theGlider2, false);
|
||||
RenderShreds();
|
||||
RenderBands();
|
||||
RenderTouchScreenControls();
|
||||
|
||||
while (TickCount() < nextFrame)
|
||||
{
|
||||
|
@@ -109,4 +109,4 @@ LOCAL_SRC_FILES := \
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := zlib MacRomanConversion stb
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
@@ -23,6 +23,8 @@ namespace PortabilityLayer
|
||||
virtual HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) = 0;
|
||||
virtual uint64_t GetFreeMemoryCosmetic() const = 0; // Returns free memory in bytes, does not have to be accurate
|
||||
virtual void Beep() const = 0;
|
||||
virtual bool IsTouchscreen() const = 0;
|
||||
virtual bool IsUsingMouseAsTouch() const = 0;
|
||||
|
||||
static void SetInstance(HostSystemServices *instance);
|
||||
static HostSystemServices *GetInstance();
|
||||
|