From 2f32c4f434e83f15c8ef466a3a6c9290bbf563fc Mon Sep 17 00:00:00 2001 From: elasota Date: Sun, 1 Nov 2020 17:43:15 -0500 Subject: [PATCH] Add touchscreen pause menu --- ApplicationResourcePatches/PICT/1300.bmp | Bin 0 -> 72682 bytes ApplicationResourcePatches/PICT/1301.bmp | Bin 0 -> 11130 bytes ApplicationResourcePatches/manifest.json | 2 + GpApp/Input.cpp | 275 ++++++++++++++++++++++- GpApp/Play.cpp | 13 +- 5 files changed, 285 insertions(+), 5 deletions(-) create mode 100644 ApplicationResourcePatches/PICT/1300.bmp create mode 100644 ApplicationResourcePatches/PICT/1301.bmp diff --git a/ApplicationResourcePatches/PICT/1300.bmp b/ApplicationResourcePatches/PICT/1300.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1eeec5b666016fbf44855dade79297ef00fe46fe GIT binary patch literal 72682 zcmeI5!EIbe5JdlSN!uqS-~=3p;gbPfoSpLVQ6VS-AD9CDY5CIJ{|i;yH4R}=Us#c| zUDKMb*E6eu0P6S8|NMH{-k-nr*Khml+y444*ROAHU-obIFaJ+@%r8&qxuW2Y9^1C33;1;fF*NTyHfYG+%xL*n7)3Kr zVuPhUg`1CFxOp7NemglB?rBvI5-Ll$g&WhNR5O`G`FvxDa2gX5Dowa?Oc)hqxJk5a z&o86Dp68x?zUA}n$J=j^N$%ayo=Ven1X5}8`BuH}j3~oRqHybws&h?9s5IeLz3+@D z!%d=a>yWB*O-QITxd&A5J0r?)lPLSGL#oa-A)(TQTlKy(q6{~Q!mUH9&NU&S(u7;} zzB8f>H;KZnL#oa-A)(TQTlKy(q6{~Qau4W`s&h?9s5IGc)%(tfGTbBzw+^W~*Mx*h z6K>V}&WJMHBnr0H;J;}I;84c z6A~&-xK-~vBg$}-DBL=v>Rb~NDowam?>i&PaFZz9I;84c6A~&-xK-~vBg$}-DEEL4 zsXEt$gi4eBR=w|xD8o&naO;q&b4^I7G~rgg?~EwJO`>q?kg9V{NT@X7R=w|xD8o&n zaO;q&b4^I7G`R;i&PaFZzetwXBLH6fwWgj@B#GolPPiNdWzs?Iebq0)p~^}aKr z3^$3wtwXBLH6fwWgj@B#GolPPiE7E=c?fw6>K##pAy<~8<>Ds~#^I)Ul zhPI>_8*IvO6WJhnxUt6t)J^v!T#T7%?g3~6i7_)9)Cbc&Iapf$J}I^xl7}1GMSLv# z4Rx6q8*IvO6WJhnxbX)DP)_$GSc;wKbZzzmfLYVEfu-2X&OHDfd}7Q_=e!f9dvdU} z+ylh6L-KGt-$P0y`wexO7#nQLa1+@edAKP@#;JC?Cr=l$fai2=3raY(Yr3}6g)AsK z_W*S8iLnKI&U#_GCkIQ*JwR+bBoDW<9i+XV{f4?sj14wrxQT3#JlwQH<3v5(lPAkq zLUX#dB}JSVHeK7vGM1E_djLB4#Mlx-$K5d9lY^z@9w4?Il84*z{!!n}enVX*#s-@* z+(b4=9&YNfaj2i}$-_k~VmV#gqB0IGo38C}5sM1WJpdhiVr&tkqkfp~$-&Zc4-nf9 z$;0hv_vr6szo9M@V}nf@ZXz2b4>$ebIG8crlLt#!Msm8gWrZA=HeK7n5|)*ldjLB4 z#Mm-Qw;eIvlY^z@9w4?Il84*v-nr+U>^Ib9Vr;M}!%bv^A9v1u*`TogCKRkB@x5 zL3`>M>p3O3Ectw^-gicv;~rJGbx75@9wJA;M(|H$*~w9p;H5`E9v&XV z`T4mxJ3A8>7Z>94@>1N~+=%=8d-3%2B;MZM1SP$_y%i@XC*tnzPQ1Llh^wnB@&5iU zPESw8^YgR#`1lZE7>eubYw`H_C|+M*g=w1f@1ewx;~4B?e|{(gpD#DhTr*m7##>mXqJ>sDftfMx;tl@_8y<5FK}*xlKd+u0{gK2o#`Hf>YpjCWj*^-u zRtBDc93d$UJk|0xC*tOj+%c4$^2PL?*^#7Yi16|4UW6uE8g4cq$ct9S#*SLep9gfw z2`VcA_=>_%M?WCU^+h|tUG{4=vmaFzl-w+k(4?C)jW5IO+(rgTTif!FY;E?mUS@DXt0|@E1S59NlwdPF=Wf5WfR7$ z>F!ErG^LRZ2Bw%nK{OGau%Uh$HX%dZpbNy~1rAq9^a*s0`W!jq+Goxz6BDOEL;~l{>1TfIs$)C96R2}c zLc%v4g7y@Z8@#LxqB7g_abl90E%=NF)!MWN>Dr*CAAttrnmsn7@XJ+~_;wJXEbJ`h zWK8S2<%VHsEeAw~R!beoPf8Tny@%6D?szN;n7l1e9WSjdVeUJbX9b29EvOtASMVkm zzVZ@E5$tAQ$t^W10NFrF;rnREwD^9i`~-sG?fmm3%BW8{KNx)^cBDzH-Z;1p!Xl zP)S*V18aH}-ubdFSzhSrUha@tW;KtKJ*oriPcK7viCz#%DhLFBecO5oknhwzn)3Ud|XthId F{{tw_h=2e9 literal 0 HcmV?d00001 diff --git a/ApplicationResourcePatches/manifest.json b/ApplicationResourcePatches/manifest.json index 16c863b..12c2ab4 100644 --- a/ApplicationResourcePatches/manifest.json +++ b/ApplicationResourcePatches/manifest.json @@ -9,6 +9,8 @@ "DITL/2004.json" : "ApplicationResourcePatches/DITL/2004.json", "DITL/2005.json" : "ApplicationResourcePatches/DITL/2005.json", "DITL/2006.json" : "ApplicationResourcePatches/DITL/2006.json", + "PICT/1300.bmp" : "ApplicationResourcePatches/PICT/1300.bmp", + "PICT/1301.bmp" : "ApplicationResourcePatches/PICT/1301.bmp", "PICT/1971.bmp" : "ApplicationResourcePatches/PICT/1971.bmp", "PICT/1972.bmp" : "ApplicationResourcePatches/PICT/1972.bmp", "PICT/1973.bmp" : "ApplicationResourcePatches/PICT/1973.bmp", diff --git a/GpApp/Input.cpp b/GpApp/Input.cpp index b54edc7..9f29452 100644 --- a/GpApp/Input.cpp +++ b/GpApp/Input.cpp @@ -7,13 +7,25 @@ #include "PLDialogs.h" #include "PLKeyEncoding.h" +#include "BitmapImage.h" #include "DialogManager.h" #include "Environ.h" #include "Externs.h" +#include "FontFamily.h" #include "InputManager.h" #include "MainWindow.h" +#include "PLStandardColors.h" +#include "PLTimeTaggedVOSEvent.h" #include "QDPixMap.h" #include "RectUtils.h" +#include "RenderedFont.h" +#include "GpRenderedFontMetrics.h" +#include "ResolveCachingColor.h" +#include "ResourceManager.h" +#include "Utilities.h" +#include "Vec2i.h" +#include "WindowDef.h" +#include "WindowManager.h" #define kNormalThrust 5 @@ -27,6 +39,7 @@ void LogDemoKey (char); void DoCommandKey (void); void DoPause (void); +void DoTouchScreenMenu (void); void DoBatteryEngaged (gliderPtr); void DoHeliumEngaged (gliderPtr); Boolean QuerySaveGame (void); @@ -39,7 +52,7 @@ Boolean isEscPauseKey, paused, batteryWasEngaged; extern long gameFrame; extern short otherPlayerEscaped; -extern Boolean quitting, playing, onePlayerLeft, twoPlayerGame, demoGoing; +extern Boolean quitting, playing, onePlayerLeft, twoPlayerGame, demoGoing, pendingTouchScreenMenu; extern touchScreenControlState touchScreen; extern macEnviron thisMac; @@ -80,6 +93,260 @@ void DoCommandKey (void) } } +//-------------------------------------------------------------- DrawTouchScreenMenu + +namespace TouchScreenMenuMetrics +{ + const int kTextLineSpacing = 42; + const int kTextLeftX = 36; + const int kTextFirstY = 34; + const int kTextSize = 18; + + const int kHighlightXOffset = 10; + const int kHighlightYOffset = 30; +} + +namespace TouchScreenMenuItems +{ + enum TouchScreenMenuItem + { + kResume, + kSave, + kQuit, + + kCount, + }; +} + +typedef TouchScreenMenuItems::TouchScreenMenuItem TouchScreenMenuItem_t; + + + +//-------------------------------------------------------------- IsTouchScreenMenuItemEnabled + +Boolean IsTouchScreenMenuItemEnabled(int index) +{ + if (index == TouchScreenMenuItems::kSave) + return !twoPlayerGame; + + return true; +} + +//-------------------------------------------------------------- DrawTouchScreenMenu + +void DrawTouchScreenMenu (DrawSurface *surface, const THandle &backgroundImage, const DrawSurface *highlightSurface, int selectedItemIndex) +{ + surface->DrawPicture(backgroundImage, (*backgroundImage)->GetRect()); + + const PLPasStr itemTexts[TouchScreenMenuItems::kCount] = + { + PSTR("Resume"), + PSTR("Save"), + PSTR("Quit"), + }; + + const int numItems = sizeof(itemTexts) / sizeof(itemTexts[0]); + + PortabilityLayer::RenderedFont *rfont = GetHandwritingFont(48, PortabilityLayer::FontFamilyFlag_None, true); + if (!rfont) + return; + + const int32_t fontAscent = rfont->GetMetrics().m_ascent; + const int32_t firstY = TouchScreenMenuMetrics::kTextFirstY + (fontAscent + TouchScreenMenuMetrics::kTextLineSpacing + 1) / 2; + + PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black()); + PortabilityLayer::ResolveCachingColor grayColor(PortabilityLayer::RGBAColor::Create(120, 120, 120, 255)); + + for (int i = 0; i < numItems; i++) + { + PortabilityLayer::ResolveCachingColor &selectedColor = IsTouchScreenMenuItemEnabled(i) ? blackColor : grayColor; + + surface->DrawString(Point::Create(TouchScreenMenuMetrics::kTextLeftX, firstY + i * TouchScreenMenuMetrics::kTextLineSpacing), itemTexts[i], selectedColor, rfont); + } + + if (selectedItemIndex >= 0) + { + BitMap *highlightBitmap = *highlightSurface->m_port.GetPixMap(); + Rect highlightRect = highlightBitmap->m_rect; + Rect highlightDestRect = highlightRect; + highlightDestRect += Point::Create(TouchScreenMenuMetrics::kHighlightXOffset, TouchScreenMenuMetrics::kHighlightYOffset + selectedItemIndex * TouchScreenMenuMetrics::kTextLineSpacing); + + CopyMask(highlightBitmap, highlightBitmap, *surface->m_port.GetPixMap(), &highlightRect, &highlightRect, &highlightDestRect); + } +} + +//-------------------------------------------------------------- DoTouchScreenMenu + +void DoTouchScreenMenu(void) +{ + static const int kTouchScreenMenuResource = 1300; + static const int kTouchScreenHighlightResource = 1301; + + THandle highlightH = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('PICT', kTouchScreenHighlightResource).StaticCast(); + BitmapImage *highlightImage = *highlightH; + + if (!highlightH) + return; + + DrawSurface *highlightSurface = nullptr; + Rect highlightRect = highlightImage->GetRect(); + if (CreateOffScreenGWorld(&highlightSurface, &highlightRect) != PLErrors::kNone) + { + highlightH.Dispose(); + return; + } + + highlightSurface->DrawPicture(highlightH, highlightRect); + highlightH.Dispose(); + + BitMap *highlightBitmap = *highlightSurface->m_port.GetPixMap(); + + THandle imageH = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('PICT', kTouchScreenMenuResource).StaticCast(); + + if (!imageH) + return; + + BitmapImage *image = *imageH; + Rect menuRect = image->GetRect(); + + const uint16_t width = image->GetRect().Width(); + const uint16_t height = image->GetRect().Height(); + + uint16_t wx = (thisMac.fullScreen.left + thisMac.fullScreen.right - width) / 2; + uint16_t wy = (thisMac.fullScreen.top + thisMac.fullScreen.bottom - height) / 2; + + PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(menuRect, PortabilityLayer::WindowStyleFlags::kBorderless, true, 0, 0, PSTR("")); + PortabilityLayer::WindowManager *wm = PortabilityLayer::WindowManager::GetInstance(); + + Window *window = wm->CreateWindow(wdef); + wm->PutWindowBehind(window, wm->GetPutInFrontSentinel()); + window->SetPosition(PortabilityLayer::Vec2i(wx, wy)); + + Window *exclWindow = window; + wm->SwapExclusiveWindow(exclWindow); + + DrawSurface *surface = window->GetDrawSurface(); + + DrawTouchScreenMenu(surface, imageH, highlightSurface, -1); + + PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black()); + PortabilityLayer::ResolveCachingColor grayColor(StdColors::Black()); + + int lockedItem = -1; + int highlightedItem = -1; + for (;;) + { + TimeTaggedVOSEvent evt; + if (WaitForEvent(&evt, 1)) + { + int newLockedItem = lockedItem; + int newHighlightedItem = highlightedItem; + if (evt.IsLMouseDownEvent()) + { + const Point mousePt = window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent); + if (!menuRect.Contains(mousePt)) + continue; + + newLockedItem = -1; + if (mousePt.v >= TouchScreenMenuMetrics::kTextFirstY) + { + int itemV = mousePt.v - TouchScreenMenuMetrics::kTextFirstY; + int itemIndex = itemV / TouchScreenMenuMetrics::kTextLineSpacing; + + if (itemIndex >= 0 && itemIndex < TouchScreenMenuItems::kCount) + { + newLockedItem = itemIndex; + newHighlightedItem = itemIndex; + } + } + } + else if (evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput) + { + const GpMouseInputEvent &mouseEvt = evt.m_vosEvent.m_event.m_mouseInputEvent; + if (mouseEvt.m_eventType == GpMouseEventTypes::kLeave) + { + newHighlightedItem = -1; + newLockedItem = -1; + } + else if (mouseEvt.m_eventType == GpMouseEventTypes::kMove || mouseEvt.m_eventType == GpMouseEventTypes::kUp) + { + const Point mousePt = window->MouseToLocal(mouseEvt); + newHighlightedItem = -1; + + if (menuRect.Contains(mousePt) && mousePt.v >= TouchScreenMenuMetrics::kTextFirstY) + { + int itemV = mousePt.v - TouchScreenMenuMetrics::kTextFirstY; + int itemIndex = itemV / TouchScreenMenuMetrics::kTextLineSpacing; + + if (itemIndex >= 0 && itemIndex < TouchScreenMenuItems::kCount) + { + if (itemIndex == lockedItem) + newHighlightedItem = itemIndex; + else + newHighlightedItem = -1; + } + } + + if (mouseEvt.m_eventType == GpMouseEventTypes::kUp) + { + if (newHighlightedItem >= 0) + { + highlightedItem = newHighlightedItem; + break; + } + else + { + newLockedItem = -1; + newHighlightedItem = -1; + } + } + } + } + + if (newLockedItem != lockedItem) + lockedItem = newLockedItem; + + if (newHighlightedItem != highlightedItem) + { + highlightedItem = newHighlightedItem; + DrawTouchScreenMenu(surface, imageH, highlightSurface, highlightedItem); + } + } + } + + wm->SwapExclusiveWindow(exclWindow); + + wm->DestroyWindow(window); + imageH.Dispose(); + DisposeGWorld(highlightSurface); + + if (highlightedItem < 0) + return; + + switch (highlightedItem) + { + case TouchScreenMenuItems::kQuit: + playing = false; + paused = false; + if ((!twoPlayerGame) && (!demoGoing)) + { + if (QuerySaveGame()) + SaveGame2(); // New save game. + } + break; + case TouchScreenMenuItems::kSave: + assert(!twoPlayerGame); + RefreshScoreboard(kSavingTitleMode); + SaveGame2(); // New save game. + HideCursor(); + CopyRectWorkToMain(&workSrcRect); + RefreshScoreboard(kNormalTitleMode); + break; + default: + break; + } +} + //-------------------------------------------------------------- DoPause void DoPause (void) @@ -310,6 +577,12 @@ void GetInput (gliderPtr thisGlider) DoCommandKey(); } + if (pendingTouchScreenMenu) + { + pendingTouchScreenMenu = false; + DoTouchScreenMenu(); + } + if (thisGlider->mode == kGliderBurning) { if (thisGlider->facing == kFaceLeft) diff --git a/GpApp/Play.cpp b/GpApp/Play.cpp index 3e66277..cd0f00a 100644 --- a/GpApp/Play.cpp +++ b/GpApp/Play.cpp @@ -56,6 +56,7 @@ long gameFrame; short batteryTotal, bandsTotal, foilTotal, mortals; Boolean playing, evenFrame, twoPlayerGame, showFoil, demoGoing; Boolean doBackground, playerSuicide, phoneBitSet, tvOn; +Boolean pendingTouchScreenMenu; touchScreenControlState touchScreen; @@ -406,6 +407,9 @@ void HandleTouchUp(touchScreenFingerID fingerID) touchScreenFingerState &fstate = touchScreen.fingers[i]; if (fstate.active && fstate.tfingerID == fingerID) { + if (fstate.capturingControl == TouchScreenCtrlIDs::Menu && touchScreen.controls[fstate.capturingControl].touchRect.Contains(fstate.point)) + pendingTouchScreenMenu = true; + fstate.active = false; fstate.tfingerID = touchScreenFingerID(); fstate.capturingControl = TouchScreenCtrlIDs::Invalid; @@ -566,7 +570,6 @@ void ResetTouchScreenControlBounds (void) if (!thisMac.isTouchscreen) return; - const Rect centerRoomRect = localRoomsDest[kCentralRoom]; int16_t touchScreenControlInterSpacing = 16; @@ -621,6 +624,8 @@ void InitTouchScreenControlState(void) (void)CreateOffScreenGWorld(&touchScreen.graphics[i], &resRect); LoadGraphic(touchScreen.graphics[i], resID); } + + pendingTouchScreenMenu = false; } //-------------------------------------------------------------- PlayGame @@ -633,9 +638,9 @@ void PlayGame (void) InitTouchScreenControlState(); - touchScreen.controls[TouchScreenCtrlIDs::Movement].isEnabled = true; - touchScreen.controls[TouchScreenCtrlIDs::Bands].isEnabled = true; - touchScreen.controls[TouchScreenCtrlIDs::BatteryHelium].isEnabled = true; + touchScreen.controls[TouchScreenCtrlIDs::Movement].isEnabled = (demoGoing == 0); + touchScreen.controls[TouchScreenCtrlIDs::Bands].isEnabled = (demoGoing == 0); + touchScreen.controls[TouchScreenCtrlIDs::BatteryHelium].isEnabled = (demoGoing == 0); touchScreen.controls[TouchScreenCtrlIDs::Menu].isEnabled = true; while ((playing) && (!quitting))