Touchscreen things

This commit is contained in:
elasota
2020-10-11 19:50:03 -04:00
parent 5c98783bbb
commit 184daefe7b
34 changed files with 799 additions and 35 deletions

View File

@@ -10,6 +10,7 @@
#endif #endif
GpSystemServices_Win32::GpSystemServices_Win32() GpSystemServices_Win32::GpSystemServices_Win32()
: m_isTouchscreenSimulation(false)
{ {
} }
@@ -84,6 +85,20 @@ void GpSystemServices_Win32::Beep() const
MessageBeep(MB_OK); 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() GpSystemServices_Win32 *GpSystemServices_Win32::GetInstance()
{ {

View File

@@ -22,10 +22,16 @@ public:
PortabilityLayer::HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) override; PortabilityLayer::HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) override;
uint64_t GetFreeMemoryCosmetic() const override; uint64_t GetFreeMemoryCosmetic() const override;
void Beep() const override; void Beep() const override;
bool IsTouchscreen() const override;
bool IsUsingMouseAsTouch() const override;
void SetTouchscreenSimulation(bool isTouchscreenSimulation);
static GpSystemServices_Win32 *GetInstance(); static GpSystemServices_Win32 *GetInstance();
private: private:
bool m_isTouchscreenSimulation;
static GpSystemServices_Win32 ms_instance; static GpSystemServices_Win32 ms_instance;
}; };

View File

@@ -1,4 +1,268 @@
#define _LARGEFILE64_SOURCE
#include "GpFileSystem_Android.h" #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() GpFileSystem_Android::GpFileSystem_Android()
{ {
@@ -6,25 +270,140 @@ GpFileSystem_Android::GpFileSystem_Android()
bool GpFileSystem_Android::FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) bool GpFileSystem_Android::FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path)
{ {
std::string resolvedPath;
bool isAsset;
if (!ResolvePath(virtualDirectory, path, resolvedPath, isAsset))
return false; 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) 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; 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) 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; 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) 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; existed = false;
return 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) PortabilityLayer::HostDirectoryCursor *GpFileSystem_Android::ScanDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory)
{ {
return nullptr; return nullptr;

View File

@@ -21,7 +21,5 @@ public:
static GpFileSystem_Android *GetInstance(); static GpFileSystem_Android *GetInstance();
private: private:
bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, wchar_t *outPath);
static GpFileSystem_Android ms_instance; static GpFileSystem_Android ms_instance;
}; };

View File

@@ -1 +0,0 @@
assets

View File

@@ -0,0 +1,2 @@
Packaged
Resources

View File

@@ -17,6 +17,7 @@ mklink /D app\jni\zlib ..\..\..\zlib
mklink /D app\jni\rapidjson ..\..\..\rapidjson mklink /D app\jni\rapidjson ..\..\..\rapidjson
mklink /D app\jni\MacRomanConversion ..\..\..\MacRomanConversion mklink /D app\jni\MacRomanConversion ..\..\..\MacRomanConversion
mklink /D app\jni\stb ..\..\..\stb 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 pause

View File

@@ -14,4 +14,5 @@ rmdir app\jni\zlib
rmdir app\jni\rapidjson rmdir app\jni\rapidjson
rmdir app\jni\MacRomanConversion rmdir app\jni\MacRomanConversion
rmdir app\jni\stb rmdir app\jni\stb
rmdir app\src\main\assets rmdir app\src\main\assets\Packaged
rmdir app\src\main\assets\Resources

View File

@@ -50,6 +50,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
{ {
if (!wcscmp(cmdLineArgs[i], L"-diagnostics")) if (!wcscmp(cmdLineArgs[i], L"-diagnostics"))
GpLogDriver_Win32::Init(); GpLogDriver_Win32::Init();
if (!wcscmp(cmdLineArgs[i], L"-touchscreensimulation"))
GpSystemServices_Win32::GetInstance()->SetTouchscreenSimulation(true);
} }
IGpLogDriver *logger = GpLogDriver_Win32::GetInstance(); IGpLogDriver *logger = GpLogDriver_Win32::GetInstance();

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -6,7 +6,22 @@
"DITL/2001.json" : "ApplicationResourcePatches/DITL/2001.json", "DITL/2001.json" : "ApplicationResourcePatches/DITL/2001.json",
"DITL/2002.json" : "ApplicationResourcePatches/DITL/2002.json", "DITL/2002.json" : "ApplicationResourcePatches/DITL/2002.json",
"DITL/2003.json" : "ApplicationResourcePatches/DITL/2003.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" : "delete" :
[ [

View File

@@ -265,6 +265,9 @@ Boolean GetColorCursors (acurHandle ballCursH, compiledAcurHandle compiledBallCu
void InitAnimatedCursor (acurHandle ballCursH) void InitAnimatedCursor (acurHandle ballCursH)
{ {
if (thisMac.isTouchscreen)
return;
compiledAcurHandle compiledBallCursorH; compiledAcurHandle compiledBallCursorH;
if (ballCursH == nil) if (ballCursH == nil)
@@ -275,7 +278,6 @@ void InitAnimatedCursor (acurHandle ballCursH)
if (!compiledBallCursorH) if (!compiledBallCursorH)
RedAlert(kErrFailedResourceLoad); RedAlert(kErrFailedResourceLoad);
GetColorCursors(ballCursH, compiledBallCursorH);
DisposCursors(); DisposCursors();
animCursorH = ballCursH; animCursorH = ballCursH;
@@ -335,8 +337,9 @@ void IncrementCursor (void)
InitAnimatedCursor(nil); InitAnimatedCursor(nil);
if (animCursorH) if (animCursorH)
{ {
(*animCursorH)->index++; acurRec *acur = *animCursorH;
(*animCursorH)->index %= (*animCursorH)->n; acur->index++;
acur->index %= acur->n;
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor((*compiledAnimCursorH)->frame[(*animCursorH)->index].hwCursor); PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor((*compiledAnimCursorH)->frame[(*animCursorH)->index].hwCursor);
} }

View File

@@ -301,6 +301,9 @@ void CheckOurEnvirons (void)
thisMac.numScreens = HowManyUsableScreens(false, true, true); thisMac.numScreens = HowManyUsableScreens(false, true, true);
thisMac.isResolutionDirty = true; thisMac.isResolutionDirty = true;
thisMac.isTouchscreen = PortabilityLayer::HostSystemServices::GetInstance()->IsTouchscreen();
thisMac.isMouseTouchscreen = PortabilityLayer::HostSystemServices::GetInstance()->IsUsingMouseAsTouch();
FlushResolutionChange(); FlushResolutionChange();
} }

View File

@@ -29,6 +29,8 @@ typedef struct
Boolean hasQT; Boolean hasQT;
Boolean hasDrag; Boolean hasDrag;
Boolean isResolutionDirty; Boolean isResolutionDirty;
Boolean isTouchscreen;
Boolean isMouseTouchscreen;
} macEnviron; } macEnviron;

View File

@@ -362,4 +362,72 @@ typedef struct
short object; short object;
} retroLink, *retroLinkPtr; } 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;

View File

@@ -13,9 +13,12 @@
#include "Environ.h" #include "Environ.h"
#include "House.h" #include "House.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "PLEventQueue.h"
#include "PLTimeTaggedVOSEvent.h"
#include "RectUtils.h" #include "RectUtils.h"
#include "ResolveCachingColor.h" #include "ResolveCachingColor.h"
#include "Scoreboard.h" #include "Scoreboard.h"
#include "Utilities.h"
#define kHouseBannerAlert 1009 #define kHouseBannerAlert 1009
@@ -42,8 +45,6 @@ void HandleRoomVisitation (void);
void SetObjectsToDefaults (void); void SetObjectsToDefaults (void);
void InitTelephone (void); void InitTelephone (void);
void HandleTelephone (void); void HandleTelephone (void);
Boolean DoesStarCodeExist (short);
short GetNumStarsRemaining (short, short);
phoneType thePhone, theChimes; phoneType thePhone, theChimes;
@@ -55,11 +56,14 @@ short batteryTotal, bandsTotal, foilTotal, mortals;
Boolean playing, evenFrame, twoPlayerGame, showFoil, demoGoing; Boolean playing, evenFrame, twoPlayerGame, showFoil, demoGoing;
Boolean doBackground, playerSuicide, phoneBitSet, tvOn; Boolean doBackground, playerSuicide, phoneBitSet, tvOn;
touchScreenControlState touchScreen;
extern VFileSpec *theHousesSpecs; extern VFileSpec *theHousesSpecs;
extern demoPtr demoData; extern demoPtr demoData;
extern gameType smallGame; extern gameType smallGame;
extern Rect gliderSrc[kNumGliderSrcRects]; extern Rect gliderSrc[kNumGliderSrcRects];
extern Rect boardDestRect, boardSrcRect; extern Rect boardDestRect, boardSrcRect;
extern Rect localRoomsDest[];
extern long incrementModeTime; extern long incrementModeTime;
extern short numBands, otherPlayerEscaped, demoIndex, demoHouseIndex; extern short numBands, otherPlayerEscaped, demoIndex, demoHouseIndex;
extern short splashOriginH, splashOriginV, countDown, thisHouseIndex; extern short splashOriginH, splashOriginV, countDown, thisHouseIndex;
@@ -384,15 +388,215 @@ void HandleGameResolutionChange(void)
DumpScreenOn(&justRoomsRect, true); 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 //-------------------------------------------------------------- PlayGame
void PlayGame (void) 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)) while ((playing) && (!quitting))
{ {
HandleInGameEvents();
if (thisMac.isResolutionDirty) if (thisMac.isResolutionDirty)
{ {
HandleGameResolutionChange(); HandleGameResolutionChange();
ResetTouchScreenControlBounds();
} }
gameFrame++; gameFrame++;

View File

@@ -29,6 +29,7 @@ void RenderSparkles (void);
void RenderStars (void); void RenderStars (void);
void RenderBands (void); void RenderBands (void);
void RenderShreds (void); void RenderShreds (void);
void RenderTouchScreenControls (void);
void CopyRectsQD (void); void CopyRectsQD (void);
@@ -55,6 +56,7 @@ extern short numBands, numStars, numShredded;
extern short numSparkles, numFlyingPts, numPendulums, clockFrame; extern short numSparkles, numFlyingPts, numPendulums, clockFrame;
extern short numFlames, numSavedMaps, numTikiFlames, numCoals; extern short numFlames, numSavedMaps, numTikiFlames, numCoals;
extern Boolean evenFrame, shadowVisible, twoPlayerGame, tvOn; extern Boolean evenFrame, shadowVisible, twoPlayerGame, tvOn;
extern touchScreenControlState touchScreen;
//============================================================== Functions //============================================================== 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 //-------------------------------------------------------------- CopyRectsQD
void CopyRectsQD (void) void CopyRectsQD (void)
@@ -655,6 +717,7 @@ void RenderFrame (void)
RenderGlider(&theGlider2, false); RenderGlider(&theGlider2, false);
RenderShreds(); RenderShreds();
RenderBands(); RenderBands();
RenderTouchScreenControls();
while (TickCount() < nextFrame) while (TickCount() < nextFrame)
{ {

View File

@@ -109,4 +109,4 @@ LOCAL_SRC_FILES := \
LOCAL_STATIC_LIBRARIES := zlib MacRomanConversion stb LOCAL_STATIC_LIBRARIES := zlib MacRomanConversion stb
include $(BUILD_SHARED_LIBRARY) include $(BUILD_STATIC_LIBRARY)

View File

@@ -23,6 +23,8 @@ namespace PortabilityLayer
virtual HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) = 0; 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 uint64_t GetFreeMemoryCosmetic() const = 0; // Returns free memory in bytes, does not have to be accurate
virtual void Beep() const = 0; virtual void Beep() const = 0;
virtual bool IsTouchscreen() const = 0;
virtual bool IsUsingMouseAsTouch() const = 0;
static void SetInstance(HostSystemServices *instance); static void SetInstance(HostSystemServices *instance);
static HostSystemServices *GetInstance(); static HostSystemServices *GetInstance();