diff --git a/slangin.ino b/slangin.ino index 88255a8..89fbbd4 100644 --- a/slangin.ino +++ b/slangin.ino @@ -79,15 +79,17 @@ int sCurrentDay; int sDrugPrices[6]; int sRandomEvent; int sCurrentDrug; -long sCurrentQty; -long sQtyMax; +unsigned long sCurrentQty; +unsigned long sQtyMax; +unsigned long sLastDebounce = 0; +short sDebounceCount = 0; /****************/ /* player state */ /****************/ -long pMoney; -long pLoanAmount; -long pSavingsAmount; +unsigned long pMoney; +unsigned long pLoanAmount; +unsigned long pSavingsAmount; GameLocation pLocation; int pGuns; int pCapacity; @@ -121,7 +123,10 @@ void loop() { arduboy.pollButtons(); - // draw screen if needed + /******************/ + /* SCREEN DRAWING */ + /******************/ + if (!screenInitialized) { arduboy.clear(); menuSelected = 0; @@ -132,7 +137,7 @@ void loop() { menu[0] = F("New Game"); menuLength = 1; menuSmall = false; - menuCols = true; + menuCols = false; drawMenu(menuSmall, menuCols, menuLength, menu); drawMenuIndicator(menuSelected, menuSmall, menuCols, menuLength, menu, false); break; @@ -225,21 +230,28 @@ void loop() { dialog[0] += lookupDrug(sCurrentDrug); dialog[1] = F(""); dialog[2] = F(""); - dialog[3] = F("Cost"); + dialog[3] = sGameState == STATE_BUY_QTY_INPUT ? F("Costs") : F("Price"); dialog[4] = F("You have"); dialogLength = 5; dialogSmall = true; drawDialog(); drawMoney(dialog[0].length() * 5 + 15, 10, sDrugPrices[sCurrentDrug]); - drawMoney(35, 37, sCurrentQty * sDrugPrices[sCurrentDrug]); - drawMoney(55, 46, pMoney); + if (sGameState == STATE_BUY_QTY_INPUT) drawMoney(55, 46, pMoney); + else { + font4x6.setCursor(55, 46); + font4x6.print(pInventory[sCurrentDrug]); + } + drawQtyInputTotal(); drawQtySelector(F("Qty")); break; } screenInitialized = true; } - // handle user input + /******************/ + /* INPUT HANDLING */ + /******************/ + // menu screens switch (sGameState) { case STATE_TITLE: @@ -312,26 +324,50 @@ void loop() { } case STATE_INVENTORY: case STATE_INFO_DIALOG: - checkBackedOut(); + checkBackedOut(true); break; case STATE_SELL_QTY_INPUT: case STATE_BUY_QTY_INPUT: - checkBackedOut(); - if (arduboy.pressed(UP_BUTTON)) { - screenInitialized = false; - sCurrentQty++; - } else if (arduboy.pressed(RIGHT_BUTTON)) { - screenInitialized = false; - sCurrentQty += 10; - } else if (arduboy.pressed(DOWN_BUTTON)) { - screenInitialized = false; - sCurrentQty--; - } else if (arduboy.pressed(LEFT_BUTTON)) { - screenInitialized = false; - sCurrentQty -= 10; + if (!checkBackedOut(false)) { + if (arduboy.justPressed(A_BUTTON)) { + if (sGameState == STATE_SELL_QTY_INPUT) { + pInventory[sCurrentDrug] -= sCurrentQty; + pMoney += sCurrentQty * sDrugPrices[sCurrentDrug]; + } else { + pInventory[sCurrentDrug] += sCurrentQty; + pMoney -= sCurrentQty * sDrugPrices[sCurrentDrug]; + } + screenInitialized = false; + sGameState = sPreviousGameState; + } else { + unsigned long currentMillis = millis(); + if (currentMillis - sLastDebounce > (sDebounceCount < 2 ? 300 : 100)) { + if (sDebounceCount < 2) sDebounceCount++; + if (arduboy.pressed(UP_BUTTON)) { + sLastDebounce = currentMillis; + if (sCurrentQty <= sQtyMax - 1) sCurrentQty++; + drawQtyInputTotal(); + } else if (arduboy.pressed(RIGHT_BUTTON)) { + sLastDebounce = currentMillis; + if (sCurrentQty <= sQtyMax - 10) sCurrentQty += 10; + else sCurrentQty = sQtyMax; + drawQtyInputTotal(); + } else if (arduboy.pressed(DOWN_BUTTON)) { + sLastDebounce = currentMillis; + if (sCurrentQty > 0) sCurrentQty--; + drawQtyInputTotal(); + } else if (arduboy.pressed(LEFT_BUTTON)) { + sLastDebounce = currentMillis; + if (sCurrentQty > 10) sCurrentQty -= 10; + else sCurrentQty = 0; + drawQtyInputTotal(); + } else { + sLastDebounce = 0; + sDebounceCount = 0; + } + } + } } - if (sCurrentQty > sQtyMax) sCurrentQty = sQtyMax; - if (sCurrentQty < 0) sCurrentQty = 0; break; } @@ -343,14 +379,15 @@ void loop() { /***********************/ void drawStatusBar() { if (sGameState == STATE_INVENTORY) { - const int chars = numberChars(pCapacity); + const int remaining = playerCapacityRemaining(); + const int chars = numberChars(remaining); const int x = 128 - ((chars + 9) * 4); font3x5.setCursor(1, 0); font3x5.print("Guns "); font3x5.print(pGuns); font3x5.setCursor(x, 0); font3x5.print("Capacity "); - font3x5.print(pCapacity); + font3x5.print(remaining); } else { const int chars = numberChars(pMoney); const int x = 128 - (chars * 4); @@ -401,7 +438,7 @@ void buildDrugMenu(int extra[6]) { menuSmall = col1Max + col2Max > 22; } -int numberChars(long num) { +int numberChars(unsigned long num) { int length = 1; while (num /= 10) length++; return length; @@ -422,7 +459,7 @@ void drawDialog() { } } -void drawMoney(const int x, const int y, const long amount) { +void drawMoney(const int x, const int y, const unsigned long amount) { Sprites::drawOverwrite(x, y + 2, spriteDollar, 0); font4x6.setCursor(x + 6, y); font4x6.print(amount); @@ -433,7 +470,19 @@ void drawQtySelector(String label) { font4x6.print(label); const int labelLength = label.length() * 5; arduboy.drawRect(labelLength + 15, 22, 103 - labelLength, 12, WHITE); - font4x6.setCursor(labelLength + 19, 24); - font4x6.print(sCurrentQty); + drawQtySelectorAmount(label); Sprites::drawOverwrite(111, 24, spriteAdjust, 0); } + +void drawQtySelectorAmount(String label) { + const int labelLength = label.length() * 5; + arduboy.fillRect(labelLength + 16, 23, 95 - labelLength, 10, BLACK); + font4x6.setCursor(labelLength + 19, 24); + font4x6.print(sCurrentQty); +} + +void drawQtyInputTotal() { + arduboy.fillRect(40, 37, 91, 7, BLACK); + drawMoney(40, 37, sCurrentQty * sDrugPrices[sCurrentDrug]); + drawQtySelectorAmount(F("Qty")); +} diff --git a/states.ino b/states.ino index 7e50527..50fc0f1 100644 --- a/states.ino +++ b/states.ino @@ -77,13 +77,14 @@ void handleMenuAction() { case STATE_JET_MENU: break; - case STATE_BUY_MENU: + case STATE_BUY_MENU: { + int remaining = playerCapacityRemaining(); sPreviousGameState = STATE_BUY_MENU; sCurrentDrug = menuSelected; - if (pCapacity <= 0) { + if (remaining <= 0) { dialog[0] = F("Oops!"); dialog[1] = F(""); - dialog[2] = F("You can't carry any"); + dialog[2] = F("You can't carry"); dialog[3] = F("more "); dialog[3] += lookupDrug(sCurrentDrug); dialog[3] += F("!"); @@ -104,8 +105,10 @@ void handleMenuAction() { sGameState = STATE_BUY_QTY_INPUT; sCurrentQty = 0; sQtyMax = floor(pMoney / (float)sDrugPrices[sCurrentDrug]); + if (remaining < sQtyMax) sQtyMax = remaining; } break; + } case STATE_SELL_MENU: sPreviousGameState = STATE_SELL_MENU; sCurrentDrug = menuSelected; @@ -130,11 +133,20 @@ void handleMenuAction() { } } -bool checkBackedOut() { - if (arduboy.justPressed(B_BUTTON)) { +bool checkBackedOut(const bool eitherButton) { + if (arduboy.justPressed(B_BUTTON) || + (eitherButton && arduboy.justPressed(A_BUTTON))) { screenInitialized = false; sGameState = sPreviousGameState; return true; } return false; } + +int playerCapacityRemaining() { + int qty = 0; + for (int i = 0; i < 6; i++) { + qty += pInventory[i]; + } + return pCapacity - qty; +}