|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define USE_ILI
- #include <ILI9341_t3n.h>
- byte SPEED = 2;
-
-
-
-
-
- #define BONUS_INACTIVE_TIME 600
- #define BONUS_ACTIVE_TIME 300
-
- #define START_LIFES 2
- #define START_LEVEL 1
-
- byte MAXLIFES = 5;
- byte LIFES = START_LIFES;
- byte GAMEWIN = 0;
- byte GAMEOVER = 0;
- byte DEMO = 1;
- byte LEVEL = START_LEVEL;
- byte ACTUALBONUS = 0;
- byte ACTIVEBONUS = 0;
- byte GAMEPAUSED = 0;
-
- byte PACMANFALLBACK = 0;
-
-
-
-
-
-
- #include <USBHost_t36.h>
- USBHost myusb;
- USBHub hub1(myusb);
- USBHIDParser hid1(myusb);
- JoystickController joystick1(myusb);
-
-
- BluetoothController bluet(myusb);
- USBDriver *drivers[] = {&hub1, &joystick1, &bluet, &hid1};
- #define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
- const char * driver_names[CNT_DEVICES] = {"Hub1", "JOY1D", "Bluet", "HID1"};
-
- bool driver_active[CNT_DEVICES] = {false, false, false, false};
-
-
- USBHIDInput *hiddrivers[] = {&joystick1};
-
- bool hid_driver_active[CNT_DEVICES] = {false, false, false};
- bool show_changed_only = false;
- bool show_raw_data = false;
- bool show_changed_data = false;
- uint32_t buttons;
- int psAxis[64];
- bool first_joystick_message = true;
- uint8_t last_bdaddr[6] = {0, 0, 0, 0, 0, 0};
-
-
-
-
- #include <SPI.h>
-
-
-
- #if defined(__MK66FX1M0__)
- #define TFT_RST 8
- #define TFT_DC 9
- #define TFT_CS 10
- #elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
-
-
-
-
- #define TFT_RST 23
- #define TFT_DC 10
- #define TFT_CS 9
- #else
- #error "This example App will only work with Teensy 3.6 or Teensy 4."
- #endif
- ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);
-
-
-
-
- boolean but_START = false;
- boolean but_SELECT = false;
- boolean but_A = false;
- boolean but_B = false;
- boolean but_UP = false;
- boolean but_DOWN = false;
- boolean but_LEFT = false;
- boolean but_RIGHT = false;
-
- void ClearKeys() {
- but_START = false;
- but_SELECT = false;
- but_A = false;
- but_B = false;
- but_UP = false;
- but_DOWN = false;
- but_LEFT = false;
- but_RIGHT = false;
- }
-
- void KeyPadLoop() {
- buttons = joystick1.getButtons();
-
- Serial.println(buttons);
- switch (joystick1.joystickType()) {
- case JoystickController::UNKNOWN:
- case JoystickController::PS4:
- {
- if (buttons == 168 ) {
- ClearKeys();
- but_START = true;
- delay(300);
- }
- if (buttons == 328 ) {
- ClearKeys();
- but_SELECT = true;
- delay(300);
- } else but_SELECT = false;
- if (buttons == 262152 ) {
- ClearKeys();
- but_A = true;
- } else but_A = false;
- if (buttons == 262152) {
- ClearKeys();
- but_B = true;
- } else but_B = false;
- if (buttons == 0) {
- ClearKeys();
- but_UP = true;
- }
- if (buttons == 4) {
- ClearKeys();
- but_DOWN = true;
- }
- if (buttons == 6) {
- ClearKeys();
- but_LEFT = true;
- }
- if (buttons == 2) {
- ClearKeys();
- but_RIGHT = true;
- }
- }
- break;
- case JoystickController::PS3:
- {
- if (buttons == 8 ) {
- ClearKeys();
- but_START = true;
- delay(300);
- }
- if (buttons == 1 ) {
- ClearKeys();
- but_SELECT = true;
- delay(300);
- } else but_SELECT = false;
- if (buttons == 32768 ) {
- ClearKeys();
- but_A = true;
- } else but_A = false;
- if (buttons == 8192) {
- ClearKeys();
- but_B = true;
- } else but_B = false;
- if (buttons == 16) {
- ClearKeys();
- but_UP = true;
- }
- if (buttons == 64) {
- ClearKeys();
- but_DOWN = true;
- }
- if (buttons == 128) {
- ClearKeys();
- but_LEFT = true;
- }
- if (buttons == 32) {
- ClearKeys();
- but_RIGHT = true;
- }
- }
- break;
- default:
- break;
- }
-
- yield();
- }
-
-
-
-
-
- #include "PacmanTiles.h"
-
- enum GameState {
- ReadyState,
- PlayState,
- DeadGhostState,
- DeadPlayerState,
- EndLevelState
- };
-
- enum SpriteState
- {
- PenState,
- RunState,
- FrightenedState,
- DeadNumberState,
- DeadEyesState,
- AteDotState,
- DeadPacmanState
- };
-
- enum {
- MStopped = 0,
- MRight = 1,
- MDown = 2,
- MLeft = 3,
- MUp = 4,
- };
-
- #define ushort uint16_t
- #define C16(_rr,_gg,_bb) (((ushort)(((_rr & 0xE0)) | ((_gg & 0xE0) >> 3) | ((_bb & 0xC0) >> 6)) <<8 ))
-
-
- uint16_t _paletteW[] =
- {
- C16(0, 0, 0),
- C16(255, 0, 0),
- C16(222, 151, 81),
- C16(255, 0, 255),
-
- C16(0, 0, 0),
- C16(0, 255, 255),
- C16(71, 84, 255),
- C16(255, 184, 81),
-
- C16(0, 0, 0),
- C16(255, 255, 0),
- C16(0, 0, 0),
- C16(33, 33, 255),
-
- C16(0, 255, 0),
- C16(71, 84, 174),
- C16(255, 184, 174),
- C16(222, 222, 255),
- };
-
- #define BINKY 0
- #define PINKY 1
- #define INKY 2
- #define CLYDE 3
- #define PACMAN 4
- #define BONUS 5
-
- const byte _initSprites[] =
- {
- BINKY, 14, 17 - 3, 31, MLeft,
- PINKY, 14 - 2, 17, 79, MLeft,
- INKY, 14, 17, 137, MLeft,
- CLYDE, 14 + 2, 17, 203, MRight,
- PACMAN, 14, 17 + 9, 0, MLeft,
- BONUS, 14, 17 + 3, 0, MLeft,
- };
-
-
- const byte _palette2[] =
- {
- 0, 11, 1, 15,
- 0, 11, 3, 15,
- 0, 11, 5, 15,
- 0, 11, 7, 15,
- 0, 11, 9, 9,
- 0, 11, 15, 15,
- 0, 11, 0, 15,
-
- 0, 1, 15, 2,
- 0, 1, 15, 12,
- 0, 7, 2, 12,
- 0, 9, 15, 0,
-
- 0, 15, 1, 2,
- 0, 12, 15, 5,
- 0, 11, 9, 1,
- 0, 5, 15, 15,
-
- };
-
- const byte _paletteIcon2[] =
- {
- 0, 9, 9, 9,
-
- 0, 2, 15, 1,
- 0, 12, 15, 1,
- 0, 12, 2, 7,
- 0, 0, 15, 9,
-
- 0, 2, 15, 1,
- 0, 12, 15, 5,
- 0, 1, 9, 11,
- 0, 5, 15, 15,
- };
-
- #define PACMANICON 1
- #define BONUSICON 2
-
- #define FRIGHTENEDPALETTE 5
- #define DEADEYESPALETTE 6
-
- #define BONUSPALETTE 7
-
- #define FPS 60
- #define CHASE 0
- #define SCATTER 1
-
- #define DOT 7
- #define PILL 14
- #define PENGATE 0x1B
-
- const byte _opposite[] = { MStopped, MLeft, MUp, MRight, MDown };
- #define OppositeDirection(_x) pgm_read_byte(_opposite + _x)
-
- const byte _scatterChase[] = { 7, 20, 7, 20, 5, 20, 5, 0 };
- const byte _scatterTargets[] = { 2, 0, 25, 0, 0, 35, 27, 35 };
- const char _pinkyTargetOffset[] = { 4, 0, 0, 4, (char)-4, 0, (char)-4, 4 };
-
- #define FRIGHTENEDGHOSTSPRITE 0
- #define GHOSTSPRITE 2
- #define NUMBERSPRITE 10
- #define PACMANSPRITE 14
-
- const byte _pacLeftAnim[] = { 5, 6, 5, 4 };
- const byte _pacRightAnim[] = { 2, 0, 2, 4 };
- const byte _pacVAnim[] = { 4, 3, 1, 3 };
-
- word _BonusInactiveTimmer = BONUS_INACTIVE_TIME;
- word _BonusActiveTimmer = 0;
-
-
-
-
-
- class Sprite
- {
- public:
- int16_t _x, _y;
- int16_t lastx, lasty;
- byte cx, cy;
- byte tx, ty;
-
- SpriteState state;
- byte pentimer;
-
- byte who;
- byte _speed;
- byte dir;
- byte phase;
-
-
- byte palette2;
- byte bits;
- signed char sy;
-
- void Init(const byte* s)
- {
- who = pgm_read_byte(s++);
- cx = pgm_read_byte(s++);
- cy = pgm_read_byte(s++);
- pentimer = pgm_read_byte(s++);
- dir = pgm_read_byte(s);
- _x = lastx = (int16_t)cx * 8 - 4;
- _y = lasty = (int16_t)cy * 8;
- state = PenState;
- _speed = 0;
- Target(random(20), random(20));
- }
-
-
- void Target(byte x, byte y)
- {
- tx = x;
- ty = y;
- }
-
- int16_t Distance(byte x, byte y)
- {
- int16_t dx = cx - x;
- int16_t dy = cy - y;
- return dx * dx + dy * dy;
- }
-
-
- void SetupDraw(GameState gameState, byte deadGhostIndex)
- {
- sy = 1;
- palette2 = who;
- byte p = phase >> 3;
-
- if (who == BONUS) {
-
- bits = 21 + ACTUALBONUS;
- palette2 = BONUSPALETTE + ACTUALBONUS;
- return;
- }
-
- if (who != PACMAN)
- {
- bits = GHOSTSPRITE + ((dir - 1) << 1) + (p & 1);
- switch (state)
- {
- case FrightenedState:
- bits = FRIGHTENEDGHOSTSPRITE + (p & 1);
- palette2 = FRIGHTENEDPALETTE;
- break;
- case DeadNumberState:
- palette2 = FRIGHTENEDPALETTE;
- bits = NUMBERSPRITE + deadGhostIndex;
- break;
- case DeadEyesState:
- palette2 = DEADEYESPALETTE;
- break;
- default:
- ;
- }
- return;
- }
-
-
- byte f = (phase >> 1) & 3;
- if (dir == MLeft)
- f = pgm_read_byte(_pacLeftAnim + f);
- else if (dir == MRight)
- f = pgm_read_byte(_pacRightAnim + f);
- else
- f = pgm_read_byte(_pacVAnim + f);
- if (dir == MUp)
- sy = -1;
- bits = f + PACMANSPRITE;
- }
-
-
- void Draw8(int16_t x, int16_t y, byte* tile)
- {
- int16_t px = x - (_x - 4);
- if (px <= -8 || px >= 16) return;
- int16_t py = y - (_y - 4);
- if (py <= -8 || py >= 16) return;
-
-
- int16_t lines = py + 8;
- if (lines > 16)
- lines = 16;
- if (py < 0)
- {
- tile -= py * 8;
- py = 0;
- }
- lines -= py;
-
-
- byte right = 16 - px;
- if (right > 8)
- right = 8;
- byte left = 0;
- if (px < 0)
- {
- left = -px;
- px = 0;
- }
-
-
- signed char dy = sy;
- if (dy < 0)
- py = 15 - py;
- byte* data = (byte*)(pacman16x16 + bits * 64);
- data += py << 2;
- dy <<= 2;
- data += px >> 2;
- px &= 3;
-
- const byte* palette = _palette2 + (palette2 << 2);
- while (lines)
- {
- const byte *src = data;
- byte d = pgm_read_byte(src++);
- d >>= px << 1;
- byte sx = 4 - px;
- byte x = left;
- do
- {
- byte p = d & 3;
- if (p)
- {
- p = pgm_read_byte(palette + p);
- if (p)
- tile[x] = p;
- }
- d >>= 2;
- if (!--sx)
- {
- d = pgm_read_byte(src++);
- sx = 4;
- }
- } while (++x < right);
-
- tile += 8;
- data += dy;
- lines--;
- }
- }
- };
-
-
-
-
-
-
- class Playfield
- {
-
- Sprite _sprites[5];
-
- Sprite _BonusSprite;
-
- byte _dotMap[(32 / 4) * (36 - 6)];
-
- GameState _state;
- long _score;
- long _hiscore;
- long _lifescore;
- signed char _scoreStr[8];
- signed char _hiscoreStr[8];
- byte _icons[14];
-
- ushort _stateTimer;
- ushort _frightenedTimer;
- byte _frightenedCount;
- byte _scIndex;
- ushort _scTimer;
-
- bool _inited;
- byte* _dirty;
- public:
- Playfield() : _inited(false)
- {
-
- byte * p = (byte*)_paletteW;
- for (int16_t i = 0; i < 16; i++)
- {
- ushort w = _paletteW[i];
- *p++ = w >> 8;
- *p++ = w;
- }
- }
-
-
- void DrawBG2(byte cx, byte cy, byte* tile)
- {
- byte index = 0;
- signed char b = 0;
-
- index = _icons[cx >> 1];
- if (index == 0)
- {
- memset(tile, 0, 64);
- return;
- }
- index--;
- index <<= 2;
-
- b = (1 - (cx & 1)) + ((cy & 1) << 1);
-
- const byte* bg = pacman8x8x2 + ((b + index) << 4);
- const byte* palette = _paletteIcon2 + index;
-
-
- byte x = 16;
- while (x--)
- {
- byte bits = (signed char)pgm_read_byte(bg++);
- byte i = 4;
- while (i--)
- {
- tile[i] = pgm_read_byte(palette + (bits & 3));
- bits >>= 2;
- }
- tile += 4;
- }
- }
-
- byte GetTile(int16_t cx, int16_t ty)
- {
-
- if (_state != ReadyState && ty == 20 && cx > 10 && cx < 17) return (0);
-
- if (LEVEL % 5 == 1) return pgm_read_byte(playMap1 + ty * 28 + cx);
- if (LEVEL % 5 == 2) return pgm_read_byte(playMap2 + ty * 28 + cx);
- if (LEVEL % 5 == 3) return pgm_read_byte(playMap3 + ty * 28 + cx);
- if (LEVEL % 5 == 4) return pgm_read_byte(playMap4 + ty * 28 + cx);
- if (LEVEL % 5 == 0) return pgm_read_byte(playMap5 + ty * 28 + cx);
- return 0;
- }
-
-
- void DrawBG(byte cx, byte cy, byte* tile)
- {
- if (cy >= 34)
- {
- DrawBG2(cx, cy, tile);
- return;
- }
-
- byte c = 11;
- if (LEVEL % 8 == 1) c = 11;
- if (LEVEL % 8 == 2) c = 12;
- if (LEVEL % 8 == 3) c = 1;
- if (LEVEL % 8 == 4) c = 9;
- if (LEVEL % 8 == 5) c = 2;
- if (LEVEL % 8 == 6) c = 5;
- if (LEVEL % 8 == 7) c = 3;
- if (LEVEL % 8 == 0) c = 15;
-
- byte b = GetTile(cx, cy);
- const byte* bg;
-
-
- memset(tile, 0, 64);
- if (cy == 20 && cx >= 11 && cx < 17)
- {
- if (DEMO == 1 && ACTIVEBONUS == 1) return;
-
- if ((_state != ReadyState && GAMEPAUSED != 1 && DEMO != 1) || ACTIVEBONUS == 1) b = 0;
- else if (DEMO == 1 && cx == 11) b = 0;
- else if (DEMO == 1 && cx == 12) b = 'D';
- else if (DEMO == 1 && cx == 13) b = 'E';
- else if (DEMO == 1 && cx == 14) b = 'M';
- else if (DEMO == 1 && cx == 15) b = 'O';
- else if (DEMO == 1 && cx == 16) b = 0;
- else if (GAMEPAUSED == 1 && cx == 11) b = 'P';
- else if (GAMEPAUSED == 1 && cx == 12) b = 'A';
- else if (GAMEPAUSED == 1 && cx == 13) b = 'U';
- else if (GAMEPAUSED == 1 && cx == 14) b = 'S';
- else if (GAMEPAUSED == 1 && cx == 15) b = 'E';
- else if (GAMEPAUSED == 1 && cx == 16) b = 'D';
- }
- else if (cy == 1)
- {
- if (cx < 7)
- b = _scoreStr[cx];
- else if (cx >= 10 && cx < 17)
- b = _hiscoreStr[cx - 10];
- } else {
- if (b == DOT || b == PILL)
- {
- if (!GetDot(cx, cy))
- return;
- c = 14;
- }
- if (b == PENGATE)
- c = 14;
- }
-
- bg = playTiles + (b << 3);
- if (b >= '0')
- c = 15;
-
- for (byte y = 0; y < 8; y++)
- {
- signed char bits = (signed char)pgm_read_byte(bg++);
- byte x = 0;
- while (bits)
- {
- if (bits < 0)
- tile[x] = c;
- bits <<= 1;
- x++;
- }
- tile += 8;
- }
- }
-
-
- void Draw(uint16_t x, uint16_t y, bool sprites)
- {
-
- byte tile[8 * 8];
-
-
- if (y == 20 && x >= 11 && x < 17 && DEMO == 1 && ACTIVEBONUS == 1) return;
- DrawBG(x, y, tile);
-
-
- x <<= 3;
- y <<= 3;
- if (sprites)
- {
- for (byte i = 0; i < 5; i++)
- _sprites[i].Draw8(x, y, tile);
-
-
- if (ACTIVEBONUS) _BonusSprite.Draw8(x, y, tile);
-
- }
-
-
- #if 0
- for (byte i = 0; i < 5; i++)
- {
- Sprite* s = _sprites + i;
- if (s->cx == (x >> 3) && s->cy == (y >> 3))
- {
- memset(tile, 0, 8);
- for (byte j = 1; j < 7; j++)
- tile[j * 8] = tile[j * 8 + 7] = 0;
- memset(tile + 56, 0, 8);
- }
- }
- #endif
-
- x += (240 - 224) / 2;
- y += (320 - 288) / 2;
-
-
-
-
-
-
- #ifdef USE_ILI
- drawIndexedmap(tile, x, y, 8, 8);
- #endif
-
- #ifdef USE_VGA
- byte n = tile[0];
- for (byte tmpY = 0; tmpY < 8; tmpY++) {
-
- word width = 1;
-
- for (byte tmpX = 0; tmpX < 8; tmpX++) {
-
- n = tile[++i];
-
- word next_color = (word)_paletteW[n];
-
- if (x + tmpX > 224 + (240 - 224) / 2) {
- break;
- }
-
- if (tmpX == 7 && width == 1 ) {
- VGA.drawPixel(x + tmpX, y + tmpY, color);
- color = next_color;
- width = 0;
- }
- else if (tmpX == 7 && width > 1 ) {
- VGA.drawHLine( y + tmpY, x + tmpX - width + 1, x + tmpX + 1, color);
- color = next_color;
- width = 0;
- }
- else if (color != next_color && width == 1) {
- VGA.drawPixel(x + tmpX, y + tmpY, color);
- color = next_color;
- width = 0;
- }
- else if (color != next_color && width > 1) {
- VGA.drawHLine( y + tmpY, x + tmpX - width + 1, x + tmpX + 1, color);
- color = next_color;
- width = 0;
- }
- width++;
-
- }
- }
- #endif
-
- }
-
- boolean updateMap [36][28];
-
-
- void Mark(int16_t x, int16_t y, byte* m)
- {
- x -= 4;
- y -= 4;
-
- updateMap[(y >> 3)][(x >> 3)] = true;
- updateMap[(y >> 3)][(x >> 3) + 1] = true;
- updateMap[(y >> 3)][(x >> 3) + 2] = true;
- updateMap[(y >> 3) + 1][(x >> 3)] = true;
- updateMap[(y >> 3) + 1][(x >> 3) + 1] = true;
- updateMap[(y >> 3) + 1][(x >> 3) + 2] = true;
- updateMap[(y >> 3) + 2][(x >> 3)] = true;
- updateMap[(y >> 3) + 2][(x >> 3) + 1] = true;
- updateMap[(y >> 3) + 2][(x >> 3) + 2] = true;
-
- }
-
- void DrawAllBG()
- {
- for (byte y = 0; y < 36; y++)
- for (byte x = 0; x < 28; x++) {
- Draw(x, y, false);
- }
- }
-
-
- void DrawAll()
- {
- byte* m = _dirty;
-
-
- for (byte i = 0; i < 5; i++)
- {
- Sprite* s = _sprites + i;
- Mark(s->lastx, s->lasty, m);
- Mark(s->_x, s->_y, m);
-
- }
-
-
- Sprite* _s = &_BonusSprite;
- Mark(_s->lastx, _s->lasty, m);
- Mark(_s->_x, _s->_y, m);
-
-
-
- for (byte i = 0; i < 5; i++)
- _sprites[i].SetupDraw(_state, _frightenedCount - 1);
-
- _BonusSprite.SetupDraw(_state, _frightenedCount - 1);
-
-
- for (byte tmpY = 0; tmpY < 36; tmpY++) {
- for (byte tmpX = 0; tmpX < 28; tmpX++) {
- if (updateMap[tmpY][tmpX] == true) Draw(tmpX, tmpY, true);
- updateMap[tmpY][tmpX] = false;
- }
-
- }
- }
-
-
- int16_t Chase(Sprite* s, int16_t cx, int16_t cy)
- {
- while (cx < 0)
- cx += 28;
- while (cx >= 28)
- cx -= 28;
-
- byte t = GetTile(cx, cy);
- if (!(t == 0 || t == DOT || t == PILL || t == PENGATE))
- return 0x7FFF;
-
- if (t == PENGATE)
- {
- if (s->who == PACMAN)
- return 0x7FFF;
- if (!(InPen(s->cx, s->cy) || s->state == DeadEyesState))
- return 0x7FFF;
- }
-
- int16_t dx = s->tx - cx;
- int16_t dy = s->ty - cy;
- return (dx * dx + dy * dy);
-
- }
-
- void UpdateTimers()
- {
-
- if (_scIndex < 8)
- {
- if (_scTimer-- == 0)
- {
- byte duration = pgm_read_byte(_scatterChase + _scIndex++);
- _scTimer = duration * FPS;
- }
- }
-
-
- if (ACTIVEBONUS == 0 && _BonusInactiveTimmer-- == 0) {
- _BonusActiveTimmer = BONUS_ACTIVE_TIME;
- ACTIVEBONUS = 1;
- }
- if (ACTIVEBONUS == 1 && _BonusActiveTimmer-- == 0) {
- _BonusInactiveTimmer = BONUS_INACTIVE_TIME;
- ACTIVEBONUS = 0;
- }
-
-
-
- if (_frightenedTimer && !--_frightenedTimer)
- {
- for (byte i = 0; i < 4; i++)
- {
- Sprite* s = _sprites + i;
- if (s->state == FrightenedState)
- {
- s->state = RunState;
- s->dir = OppositeDirection(s->dir);
- }
- }
- }
- }
-
-
- void PacmanAI()
- {
- Sprite* pacman;
- pacman = _sprites + PACMAN;
-
-
-
- Sprite* frightenedGhost = NULL;
- Sprite* closestAttackingGhost = NULL;
- Sprite* DeadEyesStateGhost = NULL;
- int16_t dist = 0x7FFF;
- int16_t closestfrightenedDist = 0x7FFF;
- int16_t closestAttackingDist = 0x7FFF;
- for (byte i = 0; i < 4; i++)
- {
- Sprite* s = _sprites + i;
- int16_t d = s->Distance(pacman->cx, pacman->cy);
- if (d < dist)
- {
-
- dist = d;
- if (s->state == FrightenedState ) {
- frightenedGhost = s;
- closestfrightenedDist = d;
- }
- else {
- closestAttackingGhost = s;
- closestAttackingDist = d;
- }
-
-
- if ( s->state == DeadEyesState ) DeadEyesStateGhost = s;
-
- }
- }
-
- PACMANFALLBACK = 0;
-
- if (DEMO == 1 && !DeadEyesStateGhost && frightenedGhost )
- {
- pacman->Target(frightenedGhost->cx, frightenedGhost->cy);
- return;
- }
-
-
-
-
- if (DEMO == 1 && !DeadEyesStateGhost && dist <= 32 && closestAttackingDist < closestfrightenedDist )
- {
- if (dist <= 16) {
- pacman->Target( pacman->cx * 2 - closestAttackingGhost->cx, pacman->cy * 2 - closestAttackingGhost->cy);
- PACMANFALLBACK = 1;
- } else {
- pacman->Target( pacman->cx * 2 - closestAttackingGhost->cx, pacman->cy * 2 - closestAttackingGhost->cy);
- }
- return;
- }
-
- if (ACTIVEBONUS == 1) {
- pacman->Target(13, 20);
- return;
- }
-
-
-
- if (GetDot(1, 6))
- pacman->Target(1, 6);
- else if (GetDot(26, 6))
- pacman->Target(26, 6);
- else if (GetDot(1, 26))
- pacman->Target(1, 26);
- else if (GetDot(26, 26))
- pacman->Target(26, 26);
- else
- {
-
- int16_t dist = 0x7FFF;
- for (byte y = 4; y < 32; y++)
- {
- for (byte x = 1; x < 26; x++)
- {
- if (GetDot(x, y))
- {
- int16_t d = pacman->Distance(x, y);
- if (d < dist)
- {
- dist = d;
- pacman->Target(x, y);
- }
- }
- }
- }
-
- if (dist == 0x7FFF) {
- GAMEWIN = 1;
- }
-
- }
- }
-
- void Scatter(Sprite* s)
- {
- const byte* st = _scatterTargets + (s->who << 1);
- s->Target(pgm_read_byte(st), pgm_read_byte(st + 1));
- }
-
- void UpdateTargets()
- {
- if (_state == ReadyState)
- return;
- PacmanAI();
- Sprite* pacman = _sprites + PACMAN;
-
-
- bool scatter = _scIndex & 1;
- for (byte i = 0; i < 4; i++)
- {
- Sprite* s = _sprites + i;
-
-
- if (s->state == DeadEyesState)
- {
- if (s->cx == 14 && s->cy == 17)
- {
- s->state = PenState;
- s->pentimer = 80;
- }
- else
- s->Target(14, 17);
- continue;
- }
-
-
- if (s->pentimer)
- {
- if (--s->pentimer)
- continue;
- s->state = RunState;
- }
-
- if (InPen(s->cx, s->cy))
- {
- s->Target(14, 14 - 2);
- } else {
- if (scatter || s->state == FrightenedState)
- Scatter(s);
- else
- {
-
- signed char tx = pacman->cx;
- signed char ty = pacman->cy;
- switch (s->who)
- {
- case PINKY:
- {
- const char* pto = _pinkyTargetOffset + ((pacman->dir - 1) << 1);
- tx += pgm_read_byte(pto);
- ty += pgm_read_byte(pto + 1);
- }
- break;
- case INKY:
- {
- const char* pto = _pinkyTargetOffset + ((pacman->dir - 1) << 1);
- Sprite* binky = _sprites + BINKY;
- tx += pgm_read_byte(pto) >> 1;
- ty += pgm_read_byte(pto + 1) >> 1;
- tx += tx - binky->cx;
- ty += ty - binky->cy;
- }
- break;
- case CLYDE:
- {
- if (s->Distance(pacman->cx, pacman->cy) < 64)
- {
- const byte* st = _scatterTargets + CLYDE * 2;
- tx = pgm_read_byte(st);
- ty = pgm_read_byte(st + 1);
- }
- }
- break;
- }
- s->Target(tx, ty);
- }
- }
- }
- }
-
-
- byte ChooseDir(int16_t dir, Sprite* s)
- {
- int16_t choice[4];
- choice[0] = Chase(s, s->cx, s->cy - 1);
- choice[1] = Chase(s, s->cx - 1, s->cy);
- choice[2] = Chase(s, s->cx, s->cy + 1);
- choice[3] = Chase(s, s->cx + 1, s->cy);
-
-
- if (DEMO == 0 && s->who == PACMAN && choice[0] < 0x7FFF && but_UP) dir = MUp;
- else if (DEMO == 0 && s->who == PACMAN && choice[1] < 0x7FFF && but_LEFT) dir = MLeft;
- else if (DEMO == 0 && s->who == PACMAN && choice[2] < 0x7FFF && but_DOWN) dir = MDown;
- else if (DEMO == 0 && s->who == PACMAN && choice[3] < 0x7FFF && but_RIGHT) dir = MRight;
-
- else if (DEMO == 0 && choice[0] < 0x7FFF && s->who == PACMAN && dir == MUp) dir = MUp;
- else if (DEMO == 0 && choice[1] < 0x7FFF && s->who == PACMAN && dir == MLeft) dir = MLeft;
- else if (DEMO == 0 && choice[2] < 0x7FFF && s->who == PACMAN && dir == MDown) dir = MDown;
- else if (DEMO == 0 && choice[3] < 0x7FFF && s->who == PACMAN && dir == MRight) dir = MRight;
- else if ((DEMO == 0 && s->who != PACMAN) || DEMO == 1 ) {
-
-
-
- int16_t dist = choice[4 - dir];
- byte opposite = OppositeDirection(dir);
- for (byte i = 0; i < 4; i++)
- {
- byte d = 4 - i;
- if ((d != opposite && choice[i] < dist) || (s->who == PACMAN && PACMANFALLBACK && choice[i] < dist))
- {
- if (s->who == PACMAN && PACMANFALLBACK) PACMANFALLBACK = 0;
- dist = choice[i];
- dir = d;
- }
-
- }
-
- } else {
- dir = MStopped;
- }
-
- return dir;
- }
-
- bool InPen(byte cx, byte cy)
- {
- if (cx <= 10 || cx >= 18) return false;
- if (cy <= 14 || cy >= 18) return false;
- return true;
- }
-
- byte GetSpeed(Sprite* s)
- {
- if (s->who == PACMAN)
- return _frightenedTimer ? 90 : 80;
- if (s->state == FrightenedState)
- return 40;
- if (s->state == DeadEyesState)
- return 100;
- if (s->cy == 17 && (s->cx <= 5 || s->cx > 20))
- return 40;
- return 75;
- }
-
- void PackmanDied() {
-
- if (LIFES <= 0) {
- GAMEOVER = 1;
- LEVEL = START_LEVEL;
- LIFES = START_LIFES;
- DEMO = 1;
- Init();
- } else {
- LIFES--;
-
- _inited = true;
- _state = ReadyState;
- _stateTimer = FPS / 2;
- _frightenedCount = 0;
- _frightenedTimer = 0;
-
- const byte* s = _initSprites;
- for (int16_t i = 0; i < 5; i++)
- _sprites[i].Init(s + i * 5);
-
- _scIndex = 0;
- _scTimer = 1;
-
- memset(_icons, 0, sizeof(_icons));
-
-
- _BonusSprite.Init(s + 5 * 5);
- _BonusInactiveTimmer = BONUS_INACTIVE_TIME;
- _BonusActiveTimmer = 0;
-
- for (byte i = 0; i < ACTUALBONUS; i++) {
- _icons[13 - i] = BONUSICON + i;
- }
-
- for (byte i = 0; i < LIFES; i++) {
- _icons[0 + i] = PACMANICON;
- }
-
-
- for (byte y = 34; y < 36; y++)
- for (byte x = 0; x < 28; x++) {
- Draw(x, y, false);
- }
-
- DrawAllBG();
- }
- }
-
-
- void MoveAll()
- {
- UpdateTimers();
- UpdateTargets();
-
-
-
- if (_stateTimer)
- {
- if (--_stateTimer <= 0)
- {
- switch (_state)
- {
- case ReadyState:
- _state = PlayState;
- _dirty[20 * 4 + 1] |= 0x1F;
- _dirty[20 * 4 + 2] |= 0x80;
-
- for (byte tmpX = 11; tmpX < 17; tmpX++) Draw(tmpX, 20, false);
-
- break;
- case DeadGhostState:
- _state = PlayState;
- for (byte i = 0; i < 4; i++)
- {
- Sprite* s = _sprites + i;
- if (s->state == DeadNumberState)
- s->state = DeadEyesState;
- }
- break;
- default:
- ;
- }
- } else {
- if (_state == ReadyState)
- return;
- }
- }
-
- for (byte i = 0; i < 5; i++)
- {
- Sprite* s = _sprites + i;
-
-
- if (_state == DeadGhostState && s->state != DeadEyesState)
- continue;
-
-
- s->_speed += GetSpeed(s);
- if (s->_speed < 100)
- continue;
- s->_speed -= 100;
-
- s->lastx = s->_x;
- s->lasty = s->_y;
- s->phase++;
-
- int16_t x = s->_x;
- int16_t y = s->_y;
-
-
- if ((x & 0x7) == 0 && (y & 0x7) == 0)
- s->dir = ChooseDir(s->dir, s);
-
-
- switch (s->dir)
- {
- case MLeft: x -= SPEED; break;
- case MRight: x += SPEED; break;
- case MUp: y -= SPEED; break;
- case MDown: y += SPEED; break;
- case MStopped: break;
- }
-
-
- while (x < 0)
- x += 224;
- while (x >= 224)
- x -= 224;
-
- s->_x = x;
- s->_y = y;
- s->cx = (x + 4) >> 3;
- s->cy = (y + 4) >> 3;
-
- if (s->who == PACMAN)
- EatDot(s->cx, s->cy);
- }
-
-
- Sprite* pacman = _sprites + PACMAN;
-
-
- Sprite* _s = &_BonusSprite;
- if (ACTIVEBONUS == 1 && _s->cx == pacman->cx && _s->cy == pacman->cy)
- {
- Score(ACTUALBONUS * 50);
- ACTUALBONUS++;
- if (ACTUALBONUS > 7) {
- ACTUALBONUS = 0;
- if (LIFES < MAXLIFES) LIFES++;
-
-
- memset(_icons, 0, sizeof(_icons));
-
- for (byte i = 0; i < LIFES; i++) {
- _icons[0 + i] = PACMANICON;
- }
-
- }
-
- for (byte i = 0; i < ACTUALBONUS; i++) {
- _icons[13 - i] = BONUSICON + i;
- }
-
-
- for (byte y = 34; y < 36; y++)
- for (byte x = 0; x < 28; x++) {
- Draw(x, y, false);
- }
-
- ACTIVEBONUS = 0;
- _BonusInactiveTimmer = BONUS_INACTIVE_TIME;
- }
-
- for (byte i = 0; i < 4; i++)
- {
- Sprite* s = _sprites + i;
-
- if (s->_x + SPEED >= pacman->_x && s->_x - SPEED <= pacman->_x && s->_y + SPEED >= pacman->_y && s->_y - SPEED <= pacman->_y)
-
-
-
- {
- if (s->state == FrightenedState)
- {
- s->state = DeadNumberState;
- _frightenedCount++;
- _state = DeadGhostState;
- _stateTimer = 10;
- Score((1 << _frightenedCount) * 100);
- }
- else {
- if (s->state == DeadNumberState || s->state == FrightenedState || s->state == DeadEyesState) {
- } else {
- PackmanDied();
- }
- }
- }
- }
- }
-
-
- void Mark(int16_t pos)
- {
- for (byte tmp = 0; tmp < 28; tmp++)
- updateMap[1][tmp] = true;
-
- }
-
- void SetScoreChar(byte i, signed char c)
- {
- if (_scoreStr[i] == c)
- return;
- _scoreStr[i] = c;
- Mark(i + 32);
-
-
- }
-
- void SetHiScoreChar(byte i, signed char c)
- {
- if (_hiscoreStr[i] == c)
- return;
- _hiscoreStr[i] = c;
-
- Mark(i + 32 + 10);
- }
-
- void Score(int16_t delta)
- {
- char str[8];
- _score += delta;
- if (DEMO == 0 && _score > _hiscore) _hiscore = _score;
-
- if (_score > _lifescore && _score % 10000 > 0) {
- _lifescore = (_score / 10000 + 1) * 10000;
-
- LIFES++;
-
- for (byte i = 0; i < LIFES; i++) {
- _icons[0 + i] = PACMANICON;
- }
-
-
- for (byte y = 34; y < 36; y++)
- for (byte x = 0; x < 28; x++) {
- Draw(x, y, false);
- }
- _score = _score + 100;
- }
-
- sprintf(str, "%ld", _score);
- byte i = 7 - strlen(str);
- byte j = 0;
- while (i < 7)
- SetScoreChar(i++, str[j++]);
- sprintf(str, "%ld", _hiscore);
- i = 7 - strlen(str);
- j = 0;
- while (i < 7)
- SetHiScoreChar(i++, str[j++]);
- }
-
- bool GetDot(byte cx, byte cy)
- {
- return _dotMap[(cy - 3) * 4 + (cx >> 3)] & (0x80 >> (cx & 7));
- }
-
- void EatDot(byte cx, byte cy)
- {
- if (!GetDot(cx, cy))
- return;
- byte mask = 0x80 >> (cx & 7);
- _dotMap[(cy - 3) * 4 + (cx >> 3)] &= ~mask;
-
- byte t = GetTile(cx, cy);
- if (t == PILL)
- {
- _frightenedTimer = 10 * FPS;
- _frightenedCount = 0;
- for (byte i = 0; i < 4; i++)
- {
- Sprite* s = _sprites + i;
- if (s->state == RunState)
- {
- s->state = FrightenedState;
- s->dir = OppositeDirection(s->dir);
- }
- }
- Score(50);
- }
- else
- Score(10);
- }
-
- void Init()
- {
- if (GAMEWIN == 1) {
- GAMEWIN = 0;
- } else {
- LEVEL = START_LEVEL;
- LIFES = START_LIFES;
- ACTUALBONUS = 0;
- ACTIVEBONUS = 0;
-
- _score = 0;
- _lifescore = 10000;
-
- memset(_scoreStr, 0, sizeof(_scoreStr));
- _scoreStr[5] = _scoreStr[6] = '0';
- }
-
-
- _inited = true;
- _state = ReadyState;
- _stateTimer = FPS / 2;
- _frightenedCount = 0;
- _frightenedTimer = 0;
-
- const byte* s = _initSprites;
- for (int16_t i = 0; i < 5; i++)
- _sprites[i].Init(s + i * 5);
-
-
- _BonusSprite.Init(s + 5 * 5);
- _BonusInactiveTimmer = BONUS_INACTIVE_TIME;
- _BonusActiveTimmer = 0;
-
- _scIndex = 0;
- _scTimer = 1;
-
- memset(_icons, 0, sizeof(_icons));
-
-
- for (byte i = 0; i < ACTUALBONUS; i++) {
- _icons[13 - i] = BONUSICON + i;
- }
-
-
- for (byte i = 0; i < LIFES; i++) {
- _icons[0 + i] = PACMANICON;
- }
-
-
- for (byte y = 34; y < 36; y++)
- for (byte x = 0; x < 28; x++) {
- Draw(x, y, false);
- }
-
-
- memset(_dotMap, 0, sizeof(_dotMap));
- byte* map = _dotMap;
- for (byte y = 3; y < 36 - 3; y++)
- {
- for (byte x = 0; x < 28; x++)
- {
- byte t = GetTile(x, y);
- if (t == 7 || t == 14)
- {
- byte s = x & 7;
- map[x >> 3] |= (0x80 >> s);
- }
- }
- map += 4;
- }
- DrawAllBG();
- }
-
- void Step()
- {
-
- if (GAMEWIN == 1) {
- LEVEL++;
- Init();
- }
-
-
- if (but_START && DEMO == 1 && GAMEPAUSED == 0) {
- but_START = false;
- DEMO = 0;
- Init();
- } else if (but_START && DEMO == 0 && GAMEPAUSED == 0) {
- but_START = false;
- GAMEPAUSED = 1;
- }
-
- if (GAMEPAUSED && but_START && DEMO == 0) {
- but_START = false;
- GAMEPAUSED = 0;
- for (byte tmpX = 11; tmpX < 17; tmpX++) Draw(tmpX, 20, false);
- }
-
-
- if (but_SELECT) {
- DEMO = 0;
- Init();
- } else if (!_inited) {
- DEMO = 1;
- Init();
- }
-
-
- byte m[(32 / 8) * 36];
- memset(m, 0, sizeof(m));
- _dirty = m;
-
-
- if (!GAMEPAUSED) MoveAll();
-
- if ((ACTIVEBONUS == 0 && DEMO == 1) || GAMEPAUSED == 1 ) for (byte tmpX = 11; tmpX < 17; tmpX++) Draw(tmpX, 20, false);
-
- DrawAll();
- }
- };
-
-
-
-
-
- #define BLACK 0x0000
-
- void setup() {
-
- randomSeed(analogRead(0));
-
-
- Serial1.begin(2000000);
- Serial.begin(9600);
-
- Serial.println("\n\nUSB Host Testing");
- Serial.println(sizeof(USBHub), DEC);
- myusb.begin();
- delay(500);
-
-
- #ifdef USE_ILI
-
- if (TFT_RST < 255) {
- pinMode(TFT_RST, OUTPUT);
- digitalWrite(TFT_RST, HIGH);
- delay(5);
- digitalWrite(TFT_RST, LOW);
- delay(20);
- digitalWrite(TFT_RST, HIGH);
- delay(150);
- }
-
- tft.begin();
- delay(100);
- tft.setRotation(2);
- delay(100);
- tft.fillScreen(BLACK);
- tft.setTextColor(ILI9341_YELLOW);
- tft.setTextSize(2);
- tft.println("Waiting for Joystick to connect...");
- #endif
-
-
-
- }
-
-
-
-
-
- Playfield _game;
-
- void loop() {
- if (joystick1.available()) {
- if (first_joystick_message) {
- tft.fillScreen(BLACK);
- Serial.printf("*** First Joystick message %x:%x ***\n",
- joystick1.idVendor(), joystick1.idProduct());
- first_joystick_message = false;
-
- const uint8_t *psz = joystick1.manufacturer();
- if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
- psz = joystick1.product();
- if (psz && *psz) Serial.printf(" product: %s\n", psz);
- psz = joystick1.serialNumber();
- if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
-
-
- joystick1.axisChangeNotifyMask(0xFFFFFl);
- }
-
- for (uint8_t i = 0; i < 64; i++) {
- psAxis[i] = joystick1.getAxis(i);
- }
-
- KeyPadLoop();
-
- _game.Step();
- yield();
- }
-
- }
-
-
-
- #define __C16(_rr,_gg,_bb) ((uint16_t)(((_rr & 0xF8) << 8) | ((_gg & 0xFC) << 3) | ((_bb & 0xF8) >> 3)))
-
-
- uint16_t __paletteW[] =
- {
- __C16(0,0,0),
- __C16(255,0,0),
- __C16(222,151,81),
- __C16(255,128,255),
-
- __C16(0,0,0),
- __C16(0,255,255),
- __C16(71,84,255),
- __C16(255,184,81),
-
- __C16(0,0,0),
- __C16(255,255,0),
- __C16(0,0,0),
- __C16(33,33,255),
-
- __C16(0,255,0),
- __C16(71,84,174),
- __C16(255,184,174),
- __C16(222,222,255),
- };
-
- void drawIndexedmap(const uint8_t *indexmap, int16_t x, int16_t y, uint16_t w, uint16_t h) {
-
- byte i = 0;
- word color = (word)__paletteW[indexmap[0]];
-
- for (byte tmpY = 0; tmpY < 8; tmpY++) {
-
- byte width = 1;
-
- for (byte tmpX = 0; tmpX < 8; tmpX++) {
- word next_color = (word)__paletteW[indexmap[++i]];
-
- if ((color != next_color && width >= 1) || tmpX == 7 ) {
-
-
- tft.drawFastHLine(x + tmpX - width + 1, y + tmpY, width, color);
- color = next_color;
- width = 0;
- }
- width++;
- }
- }
- }
|