summaryrefslogtreecommitdiff
path: root/.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games
diff options
context:
space:
mode:
authorkrolyxon <me@krolyxon.com>2026-06-08 23:12:15 +0530
committerkrolyxon <me@krolyxon.com>2026-06-08 23:12:15 +0530
commit8a4d103196312b8a18afc0a2ba0fc13ff1a0b180 (patch)
treea92424ac65fbdb93702ea8c44a5c52c9fd66e28c /.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games
parent1d557527be495c59bbc07f194d903b1cec1780d3 (diff)
remove .pio
Diffstat (limited to '.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games')
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games/LittleRookChess/LittleRookChess.ino2347
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games/SpaceTrash/SpaceTrash.ino1857
2 files changed, 0 insertions, 4204 deletions
diff --git a/.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games/LittleRookChess/LittleRookChess.ino b/.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games/LittleRookChess/LittleRookChess.ino
deleted file mode 100644
index 3a4aca9..0000000
--- a/.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games/LittleRookChess/LittleRookChess.ino
+++ /dev/null
@@ -1,2347 +0,0 @@
-/*
-
- LittleRookChess.ino
-
- A Simple Chess Engine (ported from U8glib)
-
- Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
-
- Copyright (c) 2016, olikraus@gmail.com
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list
- of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice, this
- list of conditions and the following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Current Rule Limitation
- - no minor promotion, only "Queening" of the pawn
- - threefold repetition is not detected (same board situation appears three times)
- Note: Could be implemented, but requires tracking of the complete game
- - Fifty-move rule is not checked (no pawn move, no capture within last 50 moves)
-
- Words
- Ply a half move
-
- General Links
- http://chessprogramming.wikispaces.com/
-
- Arduino specific
- http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1260055596
-
- Prefixes
- chess_ Generic Chess Application Interface
- ce_ Chess engine, used internally, these function should not be called directly
- cu_ Chess utility function
- stack_ Internal function for stack handling
-
- Issues
- 10.01.2011
- - castling to the right does not move the rook
- --> done
- - castling to the left: King can only move two squares
- --> done
-
- 11.01.2011
- Next Steps:
- - replace stack_NextCurrentPos with cu_NextPos, cleanup code according to the loop variable
- --> done
- - Castling: Need to check for fields under attack
- --> done
-
- - Check for WIN / LOOSE situation, perhaps call ce_Eval() once on the top-level board setup
- just after the real move
- - cleanup cu_Move
- --> almost done
- - add some heuristics to the eval procedure
- - add right side menu
- --> done
- - clean up chess_ManualMove
- --> done
- - finish menu (consider is_game_end, undo move)
- - end condition: if KING is under attack and if KING can not move to a field which is under attack...
- then the game is lost. What will be returned by the Eval procedure? is it -INF?
- --> finished
-
- - reduce the use of variable color, all should be reduced to board_orientation and ply&1
-
- - chess_GetNextMarked shoud make use of cu_NextPos
- --> done
- - chess_ManualMove: again cleanup, solve draw issue (KING is not in check and no legal moves are available)
- --> done
- 22.01.2011
- - simplify eval_t ce_Eval(void)
- - position eval does not work, still moves side pawn :-(
- maybe because all pieces are considered
- --> done
-
- 17. June 2016
- U8g2/Arduboy Port
-*/
-
-#include <Arduino.h>
-#include <U8g2lib.h>
-
-#ifdef U8X8_HAVE_HW_SPI
-#include <SPI.h>
-#endif
-#ifdef U8X8_HAVE_HW_I2C
-#include <Wire.h>
-#endif
-
-
-/*
- U8glib Example Overview:
- Frame Buffer Examples: clearBuffer/sendBuffer. Fast, but may not work with all Arduino boards because of RAM consumption
- Page Buffer Examples: firstPage/nextPage. Less RAM usage, should work with all Arduino boards.
- U8x8 Text Only Example: No RAM usage, direct communication with display controller. No graphics, 8x8 Text only.
-
- This is a page buffer example.
-*/
-
-void chess_Init(u8g2_t *u8g, uint8_t body_color);
-
-#define ARDUBOY
-//#define PI_SHIELD
-
-#ifdef ARDUBOY
-/*=== ARDUBOY Production, Kickstarter Edition ===*/
-U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 12, /* dc=*/ 4, /* reset=*/ 6); // Arduboy (Production, Kickstarter Edition)
-void setup(void) {
- //u8g2.begin(/*Select=*/ A0, /*Right/Next=*/ 5, /*Left/Prev=*/ 9, /*Up=*/ 8, /*Down=*/ 10, /*Home/Cancel=*/ A1); // Arduboy DevKit
- u8g2.begin(/*Select=*/ 7, /*Right/Next=*/ A1, /*Left/Prev=*/ A2, /*Up=*/ A0, /*Down=*/ A3, /*Home/Cancel=*/ 8); // Arduboy 10 (Production)
- chess_Init(u8g2.getU8g2(), 1); /* assuming Arduboy OLED here, so make the body_color be 1 for the white OLED pixel */
-}
-#endif
-
-#ifdef PI_SHIELD
-/*=== Pax Instruments Shield ===*/
-U8G2_ST7567_PI_132X64_1_4W_HW_SPI u8g2(U8G2_R2, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8); // Pax Instruments Shield, LCD_BL=6
-void setup(void) {
- u8g2.begin(/*Select=*/ 4, /*Right/Next=*/ 5, /*Left/Prev=*/ A1, /*Up=*/ U8X8_PIN_NONE, /*Down=*/ U8X8_PIN_NONE, /*Home/Cancel=*/ A2); // Pax Instrument Shield
-
- /* U8g2 Project: Pax Instruments Shield: Enable Backlight */
- pinMode(6, OUTPUT);
- digitalWrite(6, 0);
-
- chess_Init(u8g2.getU8g2(), 0); /* assuming Arduboy OLED here, so make the body_color be 1 for the white OLED pixel */
-}
-#endif
-
-/* Ignore PROGMEM for now */
-#define CHESS_PROGMEM
-#define chess_pgm_read(p) (*(p))
-#define CHESS_PSTR(s) (s)
-#define u8g2_DrawStrP u8g2_DrawStr
-
-/* backward compatibility */
-#define u8g2_SetDefaultBackgroundColor(u8g2) \
- u8g2_SetDrawColor(u8g2, 0)
-#define u8g2_SetDefaultForegroundColor(u8g2) \
- u8g2_SetDrawColor(u8g2, 1)
-
-
-/* menu button definitions: mapped to the u8g2 menu events */
-
-#define CHESS_KEY_NONE 0
-#define CHESS_KEY_NEXT U8X8_MSG_GPIO_MENU_NEXT
-#define CHESS_KEY_PREV U8X8_MSG_GPIO_MENU_PREV
-#define CHESS_KEY_SELECT U8X8_MSG_GPIO_MENU_SELECT
-#define CHESS_KEY_BACK U8X8_MSG_GPIO_MENU_HOME
-
-
-/*
-SAN identifies each piece by a single upper case letter. The standard English
-values: pawn = "P", knight = "N", bishop = "B", rook = "R", queen = "Q", and
-king = "K".
-*/
-
-/* numbers for the various pieces */
-#define PIECE_NONE 0
-#define PIECE_PAWN 1
-#define PIECE_KNIGHT 2
-#define PIECE_BISHOP 3
-#define PIECE_ROOK 4
-#define PIECE_QUEEN 5
-#define PIECE_KING 6
-
-/* color definitions */
-#define COLOR_WHITE 0
-#define COLOR_BLACK 1
-
-/* a mask, which includes COLOR and PIECE number */
-#define COLOR_PIECE_MASK 0x01f
-
-#define CP_MARK_MASK 0x20
-
-#define ILLEGAL_POSITION 255
-
-/* This is the build in upper limit of the search stack */
-/* This value defines the amount of memory allocated for the search stack */
-/* The search depth of this chess engine can never exceed this value */
-#define STACK_MAX_SIZE 5
-
-/* chess half move stack: twice the number of undo's, a user can do */
-#define CHM_USER_SIZE 6
-
-/* the CHM_LIST_SIZE must be larger than the maximum search depth */
-/* the overall size of ste half move stack */
-#define CHM_LIST_SIZE (STACK_MAX_SIZE+CHM_USER_SIZE+2)
-
-typedef int16_t eval_t; /* a variable type to store results from the evaluation */
-//#define EVAL_T_LOST -32768
-#define EVAL_T_MIN -32767
-#define EVAL_T_MAX 32767
-//#define EVAL_T_WIN 32767
-
-/* for maintainance of our own stack: this is the definition of one element on the stack */
-struct _stack_element_struct
-{
- /* the current source position which is investigated */
- uint8_t current_pos;
- uint8_t current_cp;
- uint8_t current_color; /* COLOR_WHITE or COLOR_BLACK: must be predefines */
-
- /* the move which belongs to that value, both values are game positions */
- uint8_t best_from_pos;
- uint8_t best_to_pos;
- /* the best value, which has been dicovered so far */
- eval_t best_eval;
-};
-typedef struct _stack_element_struct stack_element_t;
-typedef struct _stack_element_struct *stack_element_p;
-
-/* chess half move history */
-struct _chm_struct
-{
- uint8_t main_cp; /* the main piece, which is moved */
- uint8_t main_src; /* the source position of the main piece */
- uint8_t main_dest; /* the destination of the main piece */
-
- uint8_t other_cp; /* another piece: the captured one, the ROOK in case of castling or PIECE_NONE */
- uint8_t other_src; /* the delete position of other_cp. Often identical to main_dest except for e.p. and castling */
- uint8_t other_dest; /* only used for castling: ROOK destination pos */
-
- /* the position of the last pawn, which did a double move forward */
- /* this is required to check en passant conditions */
- /* this array can be indexed by the color of the current player */
- /* this is the condition BEFORE the move was done */
- uint8_t pawn_dbl_move[2];
-
- /* flags for the movement of rook and king; required for castling */
- /* a 1 means: castling is (still) possible */
- /* a 0 means: castling not possible */
- /* bit 0 left side white */
- /* bit 1 right side white */
- /* bit 2 left side black */
- /* bit 3 right side black */
- /* this is the condition BEFORE the move was done */
- uint8_t castling_possible;
-};
-
-typedef struct _chm_struct chm_t;
-typedef struct _chm_struct *chm_p;
-
-/* little rook chess, main structure */
-struct _lrc_struct
-{
- /* half-move (ply) counter: Counts the number of half-moves so far. Starts with 0 */
- /* the lowest bit is used to derive the color of the current player */
- /* will be set to zero in chess_SetupBoard() */
- uint8_t ply_count;
-
- /* the half move stack position counter, counts the number of elements in chm_list */
- uint8_t chm_pos;
-
- /* each element contains a colored piece, empty fields have value 0 */
- /* the field with index 0 is black (lower left) */
- uint8_t board[64];
- /* the position of the last pawn, which did a double move forward */
- /* this is required to check en passant conditions */
- /* this array can be indexed by the color of the current player */
- uint8_t pawn_dbl_move[2];
-
- /* flags for the movement of rook and king; required for castling */
- /* a 1 means: castling is (still) possible */
- /* a 0 means: castling not possible */
- /* bit 0 left side white */
- /* bit 1 right side white */
- /* bit 2 left side black */
- /* bit 3 right side black */
- uint8_t castling_possible;
-
- /* board orientation */
- /* 0: white is below COLOR_WHITE */
- /* 1: black is below COLOR_BLACK */
- /* bascially, this can be used as a color */
- uint8_t orientation;
-
- /* exchange colors of the pieces */
- /* 0: white has an empty body, use this for bright background color */
- /* 1: black has an empty body, use this for dark backround color */
- uint8_t strike_out_color;
-
- /* 0, when the game is ongoing */
- /* 1, when the game is stopped (lost or draw) */
- uint8_t is_game_end;
- /* the color of the side which lost the game */
- /* this value is only valid, when is_game_end is not 0 */
- /* values 0 and 1 represent WHITE and BLACK, 2 means a draw */
- uint8_t lost_side_color;
-
-
-
- /* checks are executed in ce_LoopRecur */
- /* these checks will put some marks on the board */
- /* this will be used by the interface to find out */
- /* legal moves */
- uint8_t check_src_pos;
- uint8_t check_mode; /* CHECK_MODE_NONE, CHECK_MODE_MOVEABLE, CHECK_MODE_TARGET_MOVE */
-
-
- /* count of the attacking pieces, indexed by color */
- uint8_t find_piece_cnt[2];
-
- /* sum of the attacking pieces, indexed by color */
- uint8_t find_piece_weight[2];
-
- /* points to the current element of the search stack */
- /* this stack is NEVER empty. The value 0 points to the first element of the stack */
- /* actually "curr_depth" represent half-moves (plies) */
- uint8_t curr_depth;
- uint8_t max_depth;
- stack_element_p curr_element;
-
- /* allocated memory for the search stack */
- stack_element_t stack_memory[STACK_MAX_SIZE];
-
- /* the half move stack, used for move undo and depth search, size is stored in chm_pos */
- chm_t chm_list[CHM_LIST_SIZE];
-};
-typedef struct _lrc_struct lrc_t;
-
-#define CHECK_MODE_NONE 0
-#define CHECK_MODE_MOVEABLE 1
-#define CHECK_MODE_TARGET_MOVE 2
-
-
-
-/*==============================================================*/
-/* global variables */
-/*==============================================================*/
-
-lrc_t lrc_obj;
-u8g2_t *lrc_u8g; /* pointer to the C object of u8g2 lib, this is used by the chess engine */
-
-
-/*==============================================================*/
-/* forward declarations */
-/*==============================================================*/
-
-/*
- apply no inline to some of the functions:
- avr-gcc very often inlines functions, however not inline saves a lot of program memory!
- On the other hand there are some really short procedures which should be inlined (like cp_GetColor)
- These procedures are marked static to prevent the generation of the expanded procedure, which
- also saves space.
-*/
-
-uint8_t stack_Push(uint8_t color) U8G2_NOINLINE;
-void stack_Pop(void) U8G2_NOINLINE;
-void stack_InitCurrElement(void) U8G2_NOINLINE;
-void stack_Init(uint8_t max) U8G2_NOINLINE;
-void stack_SetMove(eval_t val, uint8_t to_pos) U8G2_NOINLINE;
-uint8_t cu_NextPos(uint8_t pos) U8G2_NOINLINE;
-static uint8_t cu_gpos2bpos(uint8_t gpos);
-static uint8_t cp_Construct(uint8_t color, uint8_t piece);
-static uint8_t cp_GetPiece(uint8_t cp);
-static uint8_t cp_GetColor(uint8_t cp);
-uint8_t cp_GetFromBoard(uint8_t pos) U8G2_NOINLINE;
-void cp_SetOnBoard(uint8_t pos, uint8_t cp) U8G2_NOINLINE;
-
-void cu_ClearBoard(void) U8G2_NOINLINE;
-void chess_SetupBoard(void) U8G2_NOINLINE;
-eval_t ce_Eval(void);
-
-void cu_ClearMoveHistory(void) U8G2_NOINLINE;
-void cu_ReduceHistoryByFullMove(void) U8G2_NOINLINE;
-void cu_UndoHalfMove(void) U8G2_NOINLINE;
-chm_p cu_PushHalfMove(void) U8G2_NOINLINE;
-
-
-void ce_CalculatePositionWeight(uint8_t pos);
-uint8_t ce_GetPositionAttackWeight(uint8_t pos, uint8_t color);
-
-void chess_Thinking(void);
-void ce_LoopPieces(void);
-
-
-/*==============================================================*/
-/* search stack */
-/*==============================================================*/
-
-/* get current element from stack */
-struct _stack_element_struct *stack_GetCurrElement(void)
-{
- return lrc_obj.curr_element;
-}
-
-uint8_t stack_Push(uint8_t color)
-{
- if ( lrc_obj.curr_depth == lrc_obj.max_depth )
- return 0;
- lrc_obj.curr_depth++;
- lrc_obj.curr_element = lrc_obj.stack_memory+lrc_obj.curr_depth;
-
- /* change view for the evaluation */
- color ^= 1;
- stack_GetCurrElement()->current_color = color;
-
- return 1;
-}
-
-void stack_Pop(void)
-{
- lrc_obj.curr_depth--;
- lrc_obj.curr_element = lrc_obj.stack_memory+lrc_obj.curr_depth;
-}
-
-/* reset the current element on the stack */
-void stack_InitCurrElement(void)
-{
- stack_element_p e = stack_GetCurrElement();
- e->best_eval = EVAL_T_MIN;
- e->best_from_pos = ILLEGAL_POSITION;
- e->best_to_pos = ILLEGAL_POSITION;
-}
-
-/* resets the search stack (and the check mode) */
-void stack_Init(uint8_t max)
-{
- lrc_obj.curr_depth = 0;
- lrc_obj.curr_element = lrc_obj.stack_memory;
- lrc_obj.max_depth = max;
- lrc_obj.check_mode = CHECK_MODE_NONE;
- stack_InitCurrElement();
- stack_GetCurrElement()->current_color = lrc_obj.ply_count;
- stack_GetCurrElement()->current_color &= 1;
-}
-
-/* assign evaluation value and store the move, if this is the best move */
-/* assumes, that current_pos contains the source position */
-void stack_SetMove(eval_t val, uint8_t to_pos)
-{
- stack_element_p e = stack_GetCurrElement();
- if ( e->best_eval < val )
- {
- e->best_eval = val;
- e->best_from_pos = e->current_pos;
- e->best_to_pos = to_pos;
- }
-}
-
-/*
- calculate next position on a 0x88 board
- loop is constructed in this way:
- i = 0;
- do
- {
- ...
- i = cu_NextPos(i);
- } while( i != 0 );
-
- next pos might be started with an illegal position like 255
-*/
-uint8_t cu_NextPos(uint8_t pos)
-{
- /* calculate next gpos */
- pos++;
- if ( ( pos & 0x08 ) != 0 )
- {
- pos+= 0x10;
- pos&= 0xf0;
- }
- if ( ( pos & 0x80 ) != 0 )
- pos = 0;
- return pos;
-}
-
-uint8_t cu_PrevPos(uint8_t pos)
-{
- /* calculate prev gpos */
- pos--;
- if ( ( pos & 0x80 ) != 0 )
- pos = 0x077;
- else if ( ( pos & 0x08 ) != 0 )
- {
- pos &= 0xf0;
- pos |= 0x07;
- }
- return pos;
-}
-
-
-/*==============================================================*/
-/* position transltion */
-/*==============================================================*/
-/*
- there are two positions
- 1. game position (gpos): BCD encoded x-y values
- 2. board position (bpos): a number between 0 and 63, only used to access the board.
-*/
-/*
- gpos: game position value
- returns: board position
- note: does not do any checks
-*/
-static uint8_t cu_gpos2bpos(uint8_t gpos)
-{
- uint8_t bpos = gpos;
- bpos &= 0xf0;
- bpos >>= 1;
- gpos &= 0x0f;
- bpos |= gpos;
- return bpos;
-}
-
-#define gpos_IsIllegal(gpos) ((gpos) & 0x088)
-
-
-/*==============================================================*/
-/* colored piece handling */
-/*==============================================================*/
-
-#define cp_IsMarked(cp) ((cp) & CP_MARK_MASK)
-
-
-/*
- piece: one of PIECE_xxx
- color: COLOR_WHITE or COLOR_BLACK
-
- returns: A colored piece
-*/
-static uint8_t cp_Construct(uint8_t color, uint8_t piece)
-{
- color <<= 4;
- color |= piece;
- return color;
-}
-
-/* inline is better than a macro */
-static uint8_t cp_GetPiece(uint8_t cp)
-{
- cp &= 0x0f;
- return cp;
-}
-
-/*
- we could use a macro:
- #define cp_GetColor(cp) (((cp) >> 4)&1)
- however, inlined functions are sometimes much better
-*/
-static uint8_t cp_GetColor(uint8_t cp)
-{
- cp >>= 4;
- cp &= 1;
- return cp;
-}
-
-/*
- pos: game position
- returns the colored piece at the given position
-*/
-uint8_t cp_GetFromBoard(uint8_t pos)
-{
- return lrc_obj.board[cu_gpos2bpos(pos)];
-}
-
-/*
- pos: game position
- cp: colored piece
-*/
-void cp_SetOnBoard(uint8_t pos, uint8_t cp)
-{
- /*printf("cp_SetOnBoard gpos:%02x cp:%02x\n", pos, cp);*/
- lrc_obj.board[cu_gpos2bpos(pos)] = cp;
-}
-
-/*==============================================================*/
-/* global board access */
-/*==============================================================*/
-
-void cu_ClearBoard(void)
-{
- uint8_t i;
- /* clear the board */
- for( i = 0; i < 64; i++ )
- lrc_obj.board[i] = PIECE_NONE;
-
- lrc_obj.ply_count = 0;
- lrc_obj.orientation = COLOR_WHITE;
-
- lrc_obj.pawn_dbl_move[0] = ILLEGAL_POSITION;
- lrc_obj.pawn_dbl_move[1] = ILLEGAL_POSITION;
-
- lrc_obj.castling_possible = 0x0f;
-
- lrc_obj.is_game_end = 0;
- lrc_obj.lost_side_color = 0;
-
- /* clear half move history */
- cu_ClearMoveHistory();
-
-}
-
-/*
- test setup
- white wins in one move
-*/
-void chess_SetupBoardTest01(void)
-{
- cu_ClearBoard();
- lrc_obj.board[7+7*8] = cp_Construct(COLOR_BLACK, PIECE_KING);
- lrc_obj.board[7+5*8] = cp_Construct(COLOR_WHITE, PIECE_PAWN);
- lrc_obj.board[3] = cp_Construct(COLOR_WHITE, PIECE_KING);
- lrc_obj.board[0+7*8] = cp_Construct(COLOR_BLACK, PIECE_ROOK);
- lrc_obj.board[6] = cp_Construct(COLOR_WHITE, PIECE_QUEEN);
-}
-
-/* setup the global board */
-void chess_SetupBoard(void)
-{
- uint8_t i;
- register uint8_t bp, wp;
-
- /* clear the board */
- cu_ClearBoard();
-
- /* precronstruct pawns */
- wp = cp_Construct(COLOR_WHITE, PIECE_PAWN);
- bp = cp_Construct(COLOR_BLACK, PIECE_PAWN);
-
- /* setup pawn */
- for( i = 0; i < 8; i++ )
- {
- lrc_obj.board[i+8] = wp;
- lrc_obj.board[i+6*8] = bp;
- }
-
- /* assign remaining pieces */
-
- lrc_obj.board[0] = cp_Construct(COLOR_WHITE, PIECE_ROOK);
- lrc_obj.board[1] = cp_Construct(COLOR_WHITE, PIECE_KNIGHT);
- lrc_obj.board[2] = cp_Construct(COLOR_WHITE, PIECE_BISHOP);
- lrc_obj.board[3] = cp_Construct(COLOR_WHITE, PIECE_QUEEN);
- lrc_obj.board[4] = cp_Construct(COLOR_WHITE, PIECE_KING);
- lrc_obj.board[5] = cp_Construct(COLOR_WHITE, PIECE_BISHOP);
- lrc_obj.board[6] = cp_Construct(COLOR_WHITE, PIECE_KNIGHT);
- lrc_obj.board[7] = cp_Construct(COLOR_WHITE, PIECE_ROOK);
-
- lrc_obj.board[0+7*8] = cp_Construct(COLOR_BLACK, PIECE_ROOK);
- lrc_obj.board[1+7*8] = cp_Construct(COLOR_BLACK, PIECE_KNIGHT);
- lrc_obj.board[2+7*8] = cp_Construct(COLOR_BLACK, PIECE_BISHOP);
- lrc_obj.board[3+7*8] = cp_Construct(COLOR_BLACK, PIECE_QUEEN);
- lrc_obj.board[4+7*8] = cp_Construct(COLOR_BLACK, PIECE_KING);
- lrc_obj.board[5+7*8] = cp_Construct(COLOR_BLACK, PIECE_BISHOP);
- lrc_obj.board[6+7*8] = cp_Construct(COLOR_BLACK, PIECE_KNIGHT);
- lrc_obj.board[7+7*8] = cp_Construct(COLOR_BLACK, PIECE_ROOK);
-
- //chess_SetupBoardTest01();
-
-}
-
-
-
-/*==============================================================*/
-/* checks */
-/*==============================================================*/
-
-/*
- checks if the position is somehow illegal
-*/
-uint8_t cu_IsIllegalPosition(uint8_t pos, uint8_t my_color)
-{
- uint8_t board_cp;
- /* check, if the position is offboard */
- if ( gpos_IsIllegal(pos) != 0 )
- return 1;
- /* get the piece from the board */
- board_cp = cp_GetFromBoard(pos);
- /* check if hit our own pieces */
- if ( board_cp != 0 )
- if ( cp_GetColor(board_cp) == my_color )
- return 1;
- /* all ok, we could go to this position */
- return 0;
-}
-
-/*==============================================================*/
-/* evaluation procedure */
-/*==============================================================*/
-
-/*
- basic idea is to return a value between EVAL_T_MIN and EVAL_T_MAX
-*/
-
-/*
- the weight table uses the PIECE number as index:
- #define PIECE_NONE 0
- #define PIECE_PAWN 1
- #define PIECE_KNIGHT 2
- #define PIECE_BISHOP 3
- #define PIECE_ROOK 4
- #define PIECE_QUEEN 5
- #define PIECE_KING 6
- the king itself is not counted
-*/
-uint8_t ce_piece_weight[] = { 0, 1, 3, 3, 5, 9, 0 };
-uint8_t ce_pos_weight[] = { 0, 1, 1, 2, 2, 1, 1, 0};
-/*
- evaluate the current situation on the global board
-*/
-eval_t ce_Eval(void)
-{
- uint8_t cp;
- uint8_t is_my_king_present = 0;
- uint8_t is_opposit_king_present = 0;
- eval_t material_my_color = 0;
- eval_t material_opposit_color = 0;
- eval_t position_my_color = 0;
- eval_t position_opposit_color = 0;
- eval_t result;
- uint8_t pos;
-
- pos = 0;
- do
- {
- /* get colored piece from the board */
- cp = cp_GetFromBoard(pos);
-
- if ( cp_GetPiece(cp) != PIECE_NONE )
- {
- if ( stack_GetCurrElement()->current_color == cp_GetColor(cp) )
- {
- /* this is our color */
- /* check if we found our king */
- if ( cp_GetPiece(cp) == PIECE_KING )
- is_my_king_present = 1;
- material_my_color += ce_piece_weight[cp_GetPiece(cp)];
- if ( cp_GetPiece(cp) == PIECE_PAWN || cp_GetPiece(cp) == PIECE_KNIGHT )
- {
- position_my_color += ce_pos_weight[pos&7]*ce_pos_weight[(pos>>4)&7];
- }
- }
- else
- {
- /* this is the opposit color */
- if ( cp_GetPiece(cp) == PIECE_KING )
- is_opposit_king_present = 1;
- material_opposit_color += ce_piece_weight[cp_GetPiece(cp)];
- if ( cp_GetPiece(cp) == PIECE_PAWN || cp_GetPiece(cp) == PIECE_KNIGHT )
- {
- position_opposit_color += ce_pos_weight[pos&7]*ce_pos_weight[(pos>>4)&7];
- }
- }
- }
- pos = cu_NextPos(pos);
- } while( pos != 0 );
-
-
- /* decide if we lost or won the game */
- if ( is_my_king_present == 0 )
- return EVAL_T_MIN; /*_LOST*/
- if ( is_opposit_king_present == 0 )
- return EVAL_T_MAX; /*_WIN*/
-
- /* here is the evaluation function */
-
- result = material_my_color - material_opposit_color;
- result <<= 3;
- result += position_my_color - position_opposit_color;
- return result;
-}
-
-/*==============================================================*/
-/* move backup and restore */
-/*==============================================================*/
-
-
-/* this procedure must be called to keep the size as low as possible */
-/* if the chm_list is large enough, it could hold the complete history */
-/* but for an embedded controler... it is deleted for every engine search */
-void cu_ClearMoveHistory(void)
-{
- lrc_obj.chm_pos = 0;
-}
-
-void cu_ReduceHistoryByFullMove(void)
-{
- uint8_t i;
- while( lrc_obj.chm_pos > CHM_USER_SIZE )
- {
- i = 0;
- for(;;)
- {
- if ( i+2 >= lrc_obj.chm_pos )
- break;
- lrc_obj.chm_list[i] = lrc_obj.chm_list[i+2];
- i++;
- }
- lrc_obj.chm_pos -= 2;
- }
-}
-
-void cu_UndoHalfMove(void)
-{
- chm_p chm;
-
- if ( lrc_obj.chm_pos == 0 )
- return;
-
- lrc_obj.chm_pos--;
-
- chm = lrc_obj.chm_list+lrc_obj.chm_pos;
-
- lrc_obj.pawn_dbl_move[0] = chm->pawn_dbl_move[0];
- lrc_obj.pawn_dbl_move[1] = chm->pawn_dbl_move[1];
- lrc_obj.castling_possible = chm->castling_possible;
-
- cp_SetOnBoard(chm->main_src, chm->main_cp);
- cp_SetOnBoard(chm->main_dest, PIECE_NONE);
-
- if ( chm->other_src != ILLEGAL_POSITION )
- cp_SetOnBoard(chm->other_src, chm->other_cp);
- if ( chm->other_dest != ILLEGAL_POSITION )
- cp_SetOnBoard(chm->other_dest, PIECE_NONE);
-
-}
-
-/*
- assumes, that the following members of the returned chm structure are filled
- uint8_t main_cp; the main piece, which is moved
- uint8_t main_src; the source position of the main piece
- uint8_t main_dest; the destination of the main piece
-
- uint8_t other_cp; another piece: the captured one, the ROOK in case of castling or PIECE_NONE
- uint8_t other_src; the delete position of other_cp. Often identical to main_dest except for e.p. and castling
- uint8_t other_dest; only used for castling: ROOK destination pos
-
-*/
-chm_p cu_PushHalfMove(void)
-{
- chm_p chm;
-
- chm = lrc_obj.chm_list+lrc_obj.chm_pos;
- if ( lrc_obj.chm_pos < CHM_LIST_SIZE-1)
- lrc_obj.chm_pos++;
-
- chm->pawn_dbl_move[0] = lrc_obj.pawn_dbl_move[0];
- chm->pawn_dbl_move[1] = lrc_obj.pawn_dbl_move[1];
- chm->castling_possible = lrc_obj.castling_possible;
- return chm;
-}
-
-
-char chess_piece_to_char[] = "NBRQK";
-
-/*
- simple moves on empty field: Ka1-b2
- capture moves: Ka1xb2
- castling: 0-0 or 0-0-0
-*/
-
-static void cu_add_pos(char *s, uint8_t pos) U8G2_NOINLINE;
-
-static void cu_add_pos(char *s, uint8_t pos)
-{
- *s = pos;
- *s &= 15;
- *s += 'a';
- s++;
- *s = pos;
- *s >>= 4;
- *s += '1';
-}
-
-const char *cu_GetHalfMoveStr(uint8_t idx)
-{
- chm_p chm;
- static char buf[7]; /*Ka1-b2*/
- char *p = buf;
- chm = lrc_obj.chm_list+idx;
-
- if ( cp_GetPiece(chm->main_cp) != PIECE_NONE )
- {
- if ( cp_GetPiece(chm->main_cp) > PIECE_PAWN )
- {
- *p++ = chess_piece_to_char[cp_GetPiece(chm->main_cp)-2];
- }
- cu_add_pos(p, chm->main_src);
- p+=2;
- if ( cp_GetPiece(chm->other_cp) == PIECE_NONE )
- *p++ = '-';
- else
- *p++ = 'x';
- cu_add_pos(p, chm->main_dest);
- p+=2;
- }
- *p = '\0';
- return buf;
-}
-
-
-
-
-
-/*==============================================================*/
-/* move */
-/*==============================================================*/
-
-/*
- Move a piece from source position to a destination on the board
- This function
- - does not perform any checking
- - however it processes "en passant" and casteling
- - backup the move and allow 1x undo
-
- 2011-02-05:
- - fill pawn_dbl_move[] for double pawn moves
- --> done
- - Implement casteling
- --> done
- - en passant
- --> done
- - pawn conversion/promotion
- --> done
- - half-move backup
- --> done
- - cleanup everything, minimize variables
- --> done
-*/
-
-void cu_Move(uint8_t src, uint8_t dest)
-{
- /* start backup structure */
- chm_p chm = cu_PushHalfMove();
-
- /* these are the values from the board at the positions, provided as arguments to this function */
- uint8_t cp_src, cp_dest;
-
- /* Maybe a second position is cleared and one additional location is set */
- uint8_t clr_pos2;
- uint8_t set_pos2;
- uint8_t set_cp2;
-
- /* get values from board */
- cp_src = cp_GetFromBoard(src);
- cp_dest = cp_GetFromBoard(dest);
-
- /* fill backup structure */
-
- chm->main_cp = cp_src;
- chm->main_src = src;
- chm->main_dest = dest;
-
- chm->other_cp = cp_dest; /* prepace capture backup */
- chm->other_src = dest;
- chm->other_dest = ILLEGAL_POSITION;
-
- /* setup results as far as possible with some suitable values */
-
- clr_pos2 = ILLEGAL_POSITION; /* for en passant and castling, two positions might be cleared */
- set_pos2 = ILLEGAL_POSITION; /* only used for castling */
- set_cp2 = PIECE_NONE; /* ROOK for castling */
-
- /* check for PAWN */
- if ( cp_GetPiece(cp_src) == PIECE_PAWN )
- {
-
- /* double step: is the distance 2 rows */
- if ( (src - dest == 32) || ( dest - src == 32 ) )
- {
- /* remember the destination position */
- lrc_obj.pawn_dbl_move[cp_GetColor(cp_src)] = dest;
- }
-
- /* check if the PAWN is able to promote */
- else if ( (dest>>4) == 0 || (dest>>4) == 7 )
- {
- /* do simple "queening" */
- cp_src &= ~PIECE_PAWN;
- cp_src |= PIECE_QUEEN;
- }
-
- /* is it en passant capture? */
- /* check for side move */
- else if ( ((src + dest) & 1) != 0 )
- {
- /* check, if target field is empty */
- if ( cp_GetPiece(cp_dest) == PIECE_NONE )
- {
- /* this is en passant */
- /* no further checking required, because legal moves are assumed here */
- /* however... the captured pawn position must be valid */
- clr_pos2 = lrc_obj.pawn_dbl_move[cp_GetColor(cp_src) ^ 1];
- chm->other_src = clr_pos2;
- chm->other_cp = cp_GetFromBoard(clr_pos2);
- }
- }
- }
-
- /* check for the KING */
- else if ( cp_GetPiece(cp_src) == PIECE_KING )
- {
- /* disallow castling, if the KING has moved */
- if ( cp_GetColor(cp_src) == COLOR_WHITE )
- {
- /* if white KING has moved, disallow castling for white */
- lrc_obj.castling_possible &= 0x0c;
- }
- else
- {
- /* if black KING has moved, disallow castling for black */
- lrc_obj.castling_possible &= 0x03;
- }
-
- /* has it been castling to the left? */
- if ( src - dest == 2 )
- {
- /* let the ROOK move to pos2 */
- set_pos2 = src-1;
- set_cp2 = cp_GetFromBoard(src-4);
-
- /* the ROOK must be cleared from the original position */
- clr_pos2 = src-4;
-
- chm->other_cp = set_cp2;
- chm->other_src = clr_pos2;
- chm->other_dest = set_pos2;
- }
-
- /* has it been castling to the right? */
- else if ( dest - src == 2 )
- {
- /* let the ROOK move to pos2 */
- set_pos2 = src+1;
- set_cp2 = cp_GetFromBoard(src+3);
-
- /* the ROOK must be cleared from the original position */
- clr_pos2 = src+3;
-
- chm->other_cp = set_cp2;
- chm->other_src = clr_pos2;
- chm->other_dest = set_pos2;
-
- }
-
- }
-
- /* check for the ROOK */
- else if ( cp_GetPiece(cp_src) == PIECE_ROOK )
- {
- /* disallow white left castling */
- if ( src == 0x00 )
- lrc_obj.castling_possible &= ~0x01;
- /* disallow white right castling */
- if ( src == 0x07 )
- lrc_obj.castling_possible &= ~0x02;
- /* disallow black left castling */
- if ( src == 0x70 )
- lrc_obj.castling_possible &= ~0x04;
- /* disallow black right castling */
- if ( src == 0x77 )
- lrc_obj.castling_possible &= ~0x08;
- }
-
-
- /* apply new board situation */
-
- cp_SetOnBoard(dest, cp_src);
-
- if ( set_pos2 != ILLEGAL_POSITION )
- cp_SetOnBoard(set_pos2, set_cp2);
-
- cp_SetOnBoard(src, PIECE_NONE);
-
- if ( clr_pos2 != ILLEGAL_POSITION )
- cp_SetOnBoard(clr_pos2, PIECE_NONE);
-
-
-}
-
-/*
- this subprocedure decides for evaluation of the current board situation or further (deeper) investigation
- Argument pos is the new target position if the current piece
-
-*/
-uint8_t ce_LoopRecur(uint8_t pos)
-{
- eval_t eval;
-
- /* 1. check if target position is occupied by the same player (my_color) */
- /* of if pos is somehow illegal or not valid */
- if ( cu_IsIllegalPosition(pos, stack_GetCurrElement()->current_color) != 0 )
- return 0;
-
- /* 2. move piece to the specified position, capture opponent piece if required */
- cu_Move(stack_GetCurrElement()->current_pos, pos);
-
-
- /* 3. */
- /* if depth reached: evaluate */
- /* else: go down next level */
- /* no eval if there had been any valid half-moves, so the default value (MIN) will be returned. */
- if ( stack_Push(stack_GetCurrElement()->current_color) == 0 )
- {
- eval = ce_Eval();
- }
- else
- {
- /* init the element, which has been pushed */
- stack_InitCurrElement();
- /* start over with ntext level */
- ce_LoopPieces();
- /* get the best move from opponents view, so invert the result */
- eval = -stack_GetCurrElement()->best_eval;
- stack_Pop();
- }
-
- /* 4. store result */
- stack_SetMove(eval, pos);
-
- /* 5. undo the move */
- cu_UndoHalfMove();
-
- /* 6. check special modes */
- /* the purpose of these checks is to mark special pieces and positions on the board */
- /* these marks can be checked by the user interface to highlight special positions */
- if ( lrc_obj.check_mode != 0 )
- {
- stack_element_p e = stack_GetCurrElement();
- if ( lrc_obj.check_mode == CHECK_MODE_MOVEABLE )
- {
- cp_SetOnBoard(e->current_pos, e->current_cp | CP_MARK_MASK );
- }
- else if ( lrc_obj.check_mode == CHECK_MODE_TARGET_MOVE )
- {
- if ( e->current_pos == lrc_obj.check_src_pos )
- {
- cp_SetOnBoard(pos, cp_GetFromBoard(pos) | CP_MARK_MASK );
- }
- }
- }
- return 1;
-}
-
-/*==============================================================*/
-/* move pieces which can move one or more steps into a direction */
-/*==============================================================*/
-
-/*
- subprocedure to generate various target positions for some pieces
- special cases are handled in the piece specific sub-procedure
-
- Arguments:
- d: a list of potential directions
- is_multi_step: if the piece can only do one step (zero for KING and KNIGHT)
-*/
-static const uint8_t ce_dir_offset_rook[] CHESS_PROGMEM = { 1, 16, (uint8_t)-16, (uint8_t)-1, 0 };
-static const uint8_t ce_dir_offset_bishop[] CHESS_PROGMEM = { 15, 17, (uint8_t)-17, (uint8_t)-15, 0 };
-static const uint8_t ce_dir_offset_queen[] CHESS_PROGMEM = { 1, 16, (uint8_t)-16, (uint8_t)-1, 15, 17, (uint8_t)-17, (uint8_t)-15, 0 };
-static const uint8_t ce_dir_offset_knight[] CHESS_PROGMEM = {14, (uint8_t)-14, 18, (uint8_t)-18, 31, (uint8_t)-31, 33, (uint8_t)-33, 0};
-
-void ce_LoopDirsSingleMultiStep(const uint8_t *d, uint8_t is_multi_step)
-{
- uint8_t loop_pos;
-
- /* with all directions */
- for(;;)
- {
- if ( chess_pgm_read(d) == 0 )
- break;
-
- /* start again from the initial position */
- loop_pos = stack_GetCurrElement()->current_pos;
-
- /* check direction */
- do
- {
- /* check next position into one direction */
- loop_pos += chess_pgm_read(d);
-
- /*
- go further to ce_LoopRecur()
- 0 will be returned if the target position is illegal or a piece of the own color
- this is used to stop walking into one direction
- */
- if ( ce_LoopRecur(loop_pos) == 0 )
- break;
-
- /* stop if we had hit another piece */
- if ( cp_GetPiece(cp_GetFromBoard(loop_pos)) != PIECE_NONE )
- break;
- } while( is_multi_step );
- d++;
- }
-}
-
-void ce_LoopRook(void)
-{
- ce_LoopDirsSingleMultiStep(ce_dir_offset_rook, 1);
-}
-
-void ce_LoopBishop(void)
-{
- ce_LoopDirsSingleMultiStep(ce_dir_offset_bishop, 1);
-}
-
-void ce_LoopQueen(void)
-{
- ce_LoopDirsSingleMultiStep(ce_dir_offset_queen, 1);
-}
-
-void ce_LoopKnight(void)
-{
- ce_LoopDirsSingleMultiStep(ce_dir_offset_knight, 0);
-}
-
-
-
-/*==============================================================*/
-/* move king */
-/*==============================================================*/
-
-uint8_t cu_IsKingCastling(uint8_t mask, int8_t direction, uint8_t cnt) U8G2_NOINLINE;
-
-/*
- checks, if the king can do castling
-
- Arguments:
- mask: the bit-mask for the global "castling possible" flag
- direction: left castling: -1, right castling 1
- cnt: number of fields to be checked: 3 or 2
-*/
-uint8_t cu_IsKingCastling(uint8_t mask, int8_t direction, uint8_t cnt)
-{
- uint8_t pos;
- uint8_t opponent_color;
-
- /* check if the current board state allows castling */
- if ( (lrc_obj.castling_possible & mask) == 0 )
- return 0; /* castling not allowed */
-
- /* get the position of the KING, could be white or black king */
- pos = stack_GetCurrElement()->current_pos;
-
- /* calculate the color of the opponent */
- opponent_color = 1;
- opponent_color -= stack_GetCurrElement()->current_color;
-
- /* if the KING itself is given check... */
- if ( ce_GetPositionAttackWeight(pos, opponent_color) > 0 )
- return 0;
-
-
- /* check if fields in the desired direction are emtpy */
- for(;;)
- {
- /* go to the next field */
- pos += direction;
- /* check for a piece */
- if ( cp_GetPiece(cp_GetFromBoard(pos)) != PIECE_NONE )
- return 0; /* castling not allowed */
-
- /* if some of the fields are under attack */
- if ( ce_GetPositionAttackWeight(pos, opponent_color) > 0 )
- return 0;
-
- cnt--;
- if ( cnt == 0 )
- break;
- }
- return 1; /* castling allowed */
-}
-
-void ce_LoopKing(void)
-{
- /*
- there is an interessting timing problem in this procedure
- it must be checked for castling first and as second step the normal
- KING movement. If we would first check for normal moves, than
- any marks might be overwritten by the ROOK in the case of castling.
- */
-
- /* castling (this must be done before checking normal moves (see above) */
- if ( stack_GetCurrElement()->current_color == COLOR_WHITE )
- {
- /* white left castling */
- if ( cu_IsKingCastling(1, -1, 3) != 0 )
- {
- /* check for attacked fields */
- ce_LoopRecur(stack_GetCurrElement()->current_pos-2);
- }
- /* white right castling */
- if ( cu_IsKingCastling(2, 1, 2) != 0 )
- {
- /* check for attacked fields */
- ce_LoopRecur(stack_GetCurrElement()->current_pos+2);
- }
- }
- else
- {
- /* black left castling */
- if ( cu_IsKingCastling(4, -1, 3) != 0 )
- {
- /* check for attacked fields */
- ce_LoopRecur(stack_GetCurrElement()->current_pos-2);
- }
- /* black right castling */
- if ( cu_IsKingCastling(8, 1, 2) != 0 )
- {
- /* check for attacked fields */
- ce_LoopRecur(stack_GetCurrElement()->current_pos+2);
- }
- }
-
- /* reuse queen directions */
- ce_LoopDirsSingleMultiStep(ce_dir_offset_queen, 0);
-}
-
-
-/*==============================================================*/
-/* move pawn */
-/*==============================================================*/
-
-/*
- doppelschritt: nur von der grundlinie aus, beide (!) felder vor dem bauern m�ssen frei sein
- en passant: nur unmittelbar nachdem ein doppelschritt ausgef�hrt wurde.
-*/
-void ce_LoopPawnSideCapture(uint8_t loop_pos)
-{
- if ( gpos_IsIllegal(loop_pos) == 0 )
- {
- /* get the piece from the board */
- /* if the field is NOT empty */
- if ( cp_GetPiece(cp_GetFromBoard(loop_pos)) != PIECE_NONE )
- {
- /* normal capture */
- ce_LoopRecur(loop_pos);
- /* TODO: check for pawn conversion/promotion */
- }
- else
- {
- /* check conditions for en passant capture */
- if ( stack_GetCurrElement()->current_color == COLOR_WHITE )
- {
- if ( lrc_obj.pawn_dbl_move[COLOR_BLACK]+16 == loop_pos )
- {
- ce_LoopRecur(loop_pos);
- /* note: pawn conversion/promotion can not occur */
- }
- }
- else
- {
- if ( lrc_obj.pawn_dbl_move[COLOR_WHITE] == loop_pos+16 )
- {
- ce_LoopRecur(loop_pos);
- /* note: pawn conversion/promotion can not occur */
- }
- }
- }
- }
-}
-
-void ce_LoopPawn(void)
-{
- uint8_t initial_pos = stack_GetCurrElement()->current_pos;
- uint8_t my_color = stack_GetCurrElement()->current_color;
-
- uint8_t loop_pos;
- uint8_t line;
-
- /* one step forward */
-
- loop_pos = initial_pos;
- line = initial_pos;
- line >>= 4;
- if ( my_color == COLOR_WHITE )
- loop_pos += 16;
- else
- loop_pos -= 16;
- if ( gpos_IsIllegal(loop_pos) == 0 )
- {
- /* if the field is empty */
- if ( cp_GetPiece(cp_GetFromBoard(loop_pos)) == PIECE_NONE )
- {
- /* TODO: check for and loop through piece conversion/promotion */
- ce_LoopRecur(loop_pos);
-
- /* second step forward */
-
- /* if pawn is on his starting line */
- if ( (my_color == COLOR_WHITE && line == 1) || (my_color == COLOR_BLACK && line == 6 ) )
- {
- /* the place before the pawn is not occupied, so we can do double moves, see above */
-
- if ( my_color == COLOR_WHITE )
- loop_pos += 16;
- else
- loop_pos -= 16;
- if ( cp_GetPiece(cp_GetFromBoard(loop_pos)) == PIECE_NONE )
- {
- /* this is a special case, other promotions of the pawn can not occur */
- ce_LoopRecur(loop_pos);
- }
- }
- }
- }
-
- /* capture */
-
- loop_pos = initial_pos;
- if ( my_color == COLOR_WHITE )
- loop_pos += 15;
- else
- loop_pos -= 15;
- ce_LoopPawnSideCapture(loop_pos);
-
-
- loop_pos = initial_pos;
- if ( my_color == COLOR_WHITE )
- loop_pos += 17;
- else
- loop_pos -= 17;
- ce_LoopPawnSideCapture(loop_pos);
-}
-
-/*==============================================================*/
-/* attacked */
-/*==============================================================*/
-
-/*
- from a starting position, search for a piece, that might jump to that postion.
- return:
- the two global variables
- lrc_obj.find_piece_weight[0];
- lrc_obj.find_piece_weight[1];
- will be increased by the weight of the attacked pieces of that color.
- it is usually required to reset these global variables to zero, before using
- this function.
-*/
-
-void ce_FindPieceByStep(uint8_t start_pos, uint8_t piece, const uint8_t *d, uint8_t is_multi_step)
-{
- uint8_t loop_pos, cp;
-
- /* with all directions */
- for(;;)
- {
- if ( chess_pgm_read(d) == 0 )
- break;
-
- /* start again from the initial position */
- loop_pos = start_pos;
-
- /* check direction */
- do
- {
- /* check next position into one direction */
- loop_pos += chess_pgm_read(d);
-
- /* check if the board boundary has been crossed */
- if ( (loop_pos & 0x088) != 0 )
- break;
-
- /* get the colored piece from the board */
- cp = cp_GetFromBoard(loop_pos);
-
- /* stop if we had hit another piece */
- if ( cp_GetPiece(cp) != PIECE_NONE )
- {
- /* if it is the piece we are looking for, then add the weight */
- if ( cp_GetPiece(cp) == piece )
- {
- lrc_obj.find_piece_weight[cp_GetColor(cp)] += ce_piece_weight[piece];
- lrc_obj.find_piece_cnt[cp_GetColor(cp)]++;
- }
- /* in any case, break out of the inner loop */
- break;
- }
- } while( is_multi_step );
- d++;
- }
-}
-
-void ce_FindPawnPiece(uint8_t dest_pos, uint8_t color)
-{
- uint8_t cp;
- /* check if the board boundary has been crossed */
- if ( (dest_pos & 0x088) == 0 )
- {
- /* get the colored piece from the board */
- cp = cp_GetFromBoard(dest_pos);
- /* only if there is a pawn of the matching color */
- if ( cp_GetPiece(cp) == PIECE_PAWN )
- {
- if ( cp_GetColor(cp) == color )
- {
- /* the weight of the PAWN */
- lrc_obj.find_piece_weight[color] += 1;
- lrc_obj.find_piece_cnt[color]++;
- }
- }
- }
-}
-
-
-/*
- find out, which pieces do attack a specified field
- used to
- - check if the KING can do castling
- - check if the KING must move
-
- may be used in the eval procedure ... once...
-
- the result is stored in the global array
- uint8_t lrc_obj.find_piece_weight[2];
- which is indexed with the color.
- lrc_obj.find_piece_weight[COLOR_WHITE] is the sum of all white pieces
- which can directly move to this field.
-
- example:
- if the black KING is at "pos" and lrc_obj.find_piece_weight[COLOR_WHITE] is not zero
- (after executing ce_CalculatePositionWeight(pos)) then the KING must be protected or moveed, because
- the KING was given check.
-*/
-
-void ce_CalculatePositionWeight(uint8_t pos)
-{
-
- lrc_obj.find_piece_weight[0] = 0;
- lrc_obj.find_piece_weight[1] = 0;
- lrc_obj.find_piece_cnt[0] = 0;
- lrc_obj.find_piece_cnt[1] = 0;
-
- if ( (pos & 0x088) != 0 )
- return;
-
- ce_FindPieceByStep(pos, PIECE_ROOK, ce_dir_offset_rook, 1);
- ce_FindPieceByStep(pos, PIECE_BISHOP, ce_dir_offset_bishop, 1);
- ce_FindPieceByStep(pos, PIECE_QUEEN, ce_dir_offset_queen, 1);
- ce_FindPieceByStep(pos, PIECE_KNIGHT, ce_dir_offset_knight, 0);
- ce_FindPieceByStep(pos, PIECE_KING, ce_dir_offset_queen, 0);
-
- ce_FindPawnPiece(pos+17, COLOR_BLACK);
- ce_FindPawnPiece(pos+15, COLOR_BLACK);
- ce_FindPawnPiece(pos-17, COLOR_WHITE);
- ce_FindPawnPiece(pos-15, COLOR_WHITE);
-}
-
-/*
- calculate the summed weight of pieces with specified color which can move to a specified position
-
- argument:
- pos: the position which should be analysed
- color: the color of those pieces which should be analysed
- e.g. if a black piece is at 'pos' and 'color' is white then this procedure returns the white atting count
-*/
-uint8_t ce_GetPositionAttackWeight(uint8_t pos, uint8_t color)
-{
- ce_CalculatePositionWeight(pos);
- return lrc_obj.find_piece_weight[color];
-}
-
-uint8_t ce_GetPositionAttackCount(uint8_t pos, uint8_t color)
-{
- ce_CalculatePositionWeight(pos);
- return lrc_obj.find_piece_cnt[color];
-}
-
-
-/*==============================================================*/
-/* depth search starts here: loop over all pieces of the current color on the board */
-/*==============================================================*/
-
-void ce_LoopPieces(void)
-{
- stack_element_p e = stack_GetCurrElement();
- /* start with lower left position (A1) */
- e->current_pos = 0;
- do
- {
- e->current_cp = cp_GetFromBoard(e->current_pos);
- /* check if the position on the board is empty */
- if ( e->current_cp != 0 )
- {
- /* only generate moves for the current color */
- if ( e->current_color == cp_GetColor(e->current_cp) )
- {
- chess_Thinking();
-
- /* find out which piece is used */
- switch(cp_GetPiece(e->current_cp))
- {
- case PIECE_NONE:
- break;
- case PIECE_PAWN:
- ce_LoopPawn();
- break;
- case PIECE_KNIGHT:
- ce_LoopKnight();
- break;
- case PIECE_BISHOP:
- ce_LoopBishop();
- break;
- case PIECE_ROOK:
- ce_LoopRook();
- break;
- case PIECE_QUEEN:
- ce_LoopQueen();
- break;
- case PIECE_KING:
- ce_LoopKing();
- break;
- }
- }
- }
- e->current_pos = cu_NextPos(e->current_pos);
- } while( e->current_pos != 0 );
-}
-
-/*==============================================================*/
-/* user interface */
-/*==============================================================*/
-
-/*
-eval_t chess_EvalCurrBoard(uint8_t color)
-{
- stack_Init(0);
- stack_GetCurrElement()->current_color = color;
- ce_LoopPieces();
- return stack_GetCurrElement()->best_eval;
-}
-*/
-
-/* clear any marks on the board */
-void chess_ClearMarks(void)
-{
- uint8_t i;
- for( i = 0; i < 64; i++ )
- lrc_obj.board[i] &= ~CP_MARK_MASK;
-}
-
-/*
- Mark all pieces which can do moves. This is done by setting flags on the global board
-*/
-void chess_MarkMovable(void)
-{
- stack_Init(0);
- //stack_GetCurrElement()->current_color = color;
- lrc_obj.check_mode = CHECK_MODE_MOVEABLE;
- ce_LoopPieces();
-}
-
-/*
- Checks, if the piece can move from src_pos to dest_pos
-
- src_pos: The game position of a piece on the chess board
-*/
-void chess_MarkTargetMoves(uint8_t src_pos)
-{
- stack_Init(0);
- stack_GetCurrElement()->current_color = cp_GetColor(cp_GetFromBoard(src_pos));
- lrc_obj.check_src_pos = src_pos;
- lrc_obj.check_mode = CHECK_MODE_TARGET_MOVE;
- ce_LoopPieces();
-}
-
-/*
- first call should start with 255
- this procedure will return 255 if
- - there are no marks at all
- - it has looped over all marks once
-*/
-uint8_t chess_GetNextMarked(uint8_t arg, uint8_t is_prev)
-{
- uint8_t i;
- uint8_t pos = arg;
- for(i = 0; i < 64; i++)
- {
- if ( is_prev != 0 )
- pos = cu_PrevPos(pos);
- else
- pos = cu_NextPos(pos);
- if ( arg != 255 && pos == 0 )
- return 255;
- if ( cp_IsMarked(cp_GetFromBoard(pos)) )
- return pos;
- }
- return 255;
-}
-
-
-/* make a manual move: this is a little bit more than cu_Move() */
-void chess_ManualMove(uint8_t src, uint8_t dest)
-{
- uint8_t cp;
-
- /* printf("chess_ManualMove %02x -> %02x\n", src, dest); */
-
- /* if all other things fail, this is the place where the game is to be decided: */
- /* ... if the KING is captured */
- cp = cp_GetFromBoard(dest);
- if ( cp_GetPiece(cp) == PIECE_KING )
- {
- lrc_obj.is_game_end = 1;
- lrc_obj.lost_side_color = cp_GetColor(cp);
- }
-
- /* clear ply history here, to avoid memory overflow */
- /* may be the last X moves can be kept here */
- cu_ReduceHistoryByFullMove();
- /* perform the move on the board */
- cu_Move(src, dest);
-
- /* update en passant double move positions: en passant position is removed after two half moves */
- lrc_obj.pawn_dbl_move[lrc_obj.ply_count&1] = ILLEGAL_POSITION;
-
- /* update the global half move counter */
- lrc_obj.ply_count++;
-
-
- /* make a small check about the end of the game */
- /* use at least depth 1, because we must know if the king can still move */
- /* this is: King moves at level 0 and will be captured at level 1 */
- /* so we check if the king can move and will not be captured at search level 1 */
-
- stack_Init(1);
- ce_LoopPieces();
-
- /* printf("chess_ManualMove/analysis best_from_pos %02x -> best_to_pos %02x\n", stack_GetCurrElement()->best_from_pos, stack_GetCurrElement()->best_to_pos); */
-
- /* analyse the eval result */
-
- /* check if the other player has any moves left */
- if ( stack_GetCurrElement()->best_from_pos == ILLEGAL_POSITION )
- {
- uint8_t color;
- /* conditions: */
- /* 1. no King, should never happen, opposite color has won */
- /* this is already checked above at the beginning if this procedure */
- /* 2. King is under attack, opposite color has won */
- /* 3. King is not under attack, game is a draw */
-
- uint8_t i = 0;
- color = lrc_obj.ply_count;
- color &= 1;
- do
- {
- cp = cp_GetFromBoard(i);
- /* look for the King */
- if ( cp_GetPiece(cp) == PIECE_KING )
- {
- if ( cp_GetColor(cp) == color )
- {
- /* check if KING is attacked */
- if ( ce_GetPositionAttackCount(i, color^1) != 0 )
- {
- /* KING is under attack (check) and can not move: Game is lost */
- lrc_obj.is_game_end = 1;
- lrc_obj.lost_side_color = color;
- }
- else
- {
- /* KING is NOT under attack (check) but can not move: Game is a draw */
- lrc_obj.is_game_end = 1;
- lrc_obj.lost_side_color = 2;
- }
- /* break out of the loop */
- break;
- }
- }
- i = cu_NextPos(i);
- } while( i != 0 );
- }
-}
-
-/* let the computer do a move */
-void chess_ComputerMove(uint8_t depth)
-{
- stack_Init(depth);
-
- //stack_GetCurrElement()->current_color = lrc_obj.ply_count;
- //stack_GetCurrElement()->current_color &= 1;
-
- cu_ReduceHistoryByFullMove();
- ce_LoopPieces();
-
- chess_ManualMove(stack_GetCurrElement()->best_from_pos, stack_GetCurrElement()->best_to_pos);
-}
-
-
-/*==============================================================*/
-/* unix code */
-/*==============================================================*/
-
-#ifdef UNIX_MAIN
-
-#else
-
-/*==============================================================*/
-/* display menu */
-/*==============================================================*/
-
-extern const uint8_t chess_pieces_body_bm[] CHESS_PROGMEM; // forward decl
-extern const uint8_t chess_black_pieces_bm[] CHESS_PROGMEM; // forward decl
-
-// uint8_t chess_key_code = 0; // obsolete, u8g2 does proper debouncing
-uint8_t chess_key_cmd = 0;
-#define CHESS_STATE_MENU 0
-#define CHESS_STATE_SELECT_START 1
-#define CHESS_STATE_SELECT_PIECE 2
-#define CHESS_STATE_SELECT_TARGET_POS 3
-#define CHESS_STATE_THINKING 4
-#define CHESS_STATE_GAME_END 5
-uint8_t chess_state = CHESS_STATE_MENU;
-uint8_t chess_source_pos = 255;
-uint8_t chess_target_pos = 255;
-
-#define MNU_FONT u8g2_font_5x8_tr
-#define MNU_ENTRY_HEIGHT 9
-
-const char *mnu_title = "Little Rook Chess";
-const char *mnu_list[] = { "New Game (White)", "New Game (Black)", "Undo Move", "Return" };
-uint8_t mnu_pos = 0;
-uint8_t mnu_max = 4;
-
-void mnu_DrawHome(uint8_t is_highlight)
-{
- uint8_t x = lrc_u8g->width - 35;
- uint8_t y = (lrc_u8g->height-1);
- uint8_t t;
-
- u8g2_SetFont(lrc_u8g, u8g2_font_5x7_tr);
- u8g2_SetDefaultForegroundColor(lrc_u8g);
- if ( chess_state == CHESS_STATE_THINKING )
- u8g2_DrawBitmap(lrc_u8g, x, y-8, 1, 8, chess_black_pieces_bm+24);
- else
- {
- t = u8g2_DrawStrP(lrc_u8g, x, y -1, CHESS_PSTR("Options"));
-
- if ( is_highlight )
- u8g2_DrawFrame(lrc_u8g, x-1, y - MNU_ENTRY_HEIGHT +1, t, MNU_ENTRY_HEIGHT);
- }
-}
-
-void mnu_DrawEntry(uint8_t y, const char *str, uint8_t is_clr_background, uint8_t is_highlight)
-{
- uint8_t t, x;
- u8g2_SetFont(lrc_u8g, MNU_FONT);
- t = u8g2_GetStrWidth(lrc_u8g, str);
- x = u8g2_GetDisplayWidth(lrc_u8g);
- x -= t;
- x >>= 1;
-
- if ( is_clr_background )
- {
- u8g2_SetDefaultBackgroundColor(lrc_u8g);
- u8g2_DrawBox(lrc_u8g, x-3, (lrc_u8g->height-1) - (y+MNU_ENTRY_HEIGHT-1+2), t+5, MNU_ENTRY_HEIGHT+4);
- }
-
- u8g2_SetDefaultForegroundColor(lrc_u8g);
- u8g2_DrawStr(lrc_u8g, x, (lrc_u8g->height-1) - y, str);
-
- if ( is_highlight )
- {
- u8g2_DrawFrame(lrc_u8g, 0, (lrc_u8g->height-1) - y -MNU_ENTRY_HEIGHT +1, u8g2_GetDisplayWidth(lrc_u8g), MNU_ENTRY_HEIGHT);
- }
-}
-
-void mnu_Draw(void)
-{
- uint8_t i;
- uint8_t t,y;
- /* calculate hight of the complete menu */
- y = mnu_max;
- y++; /* consider also some space for the title */
- y++; /* consider also some space for the title */
- y *= MNU_ENTRY_HEIGHT;
-
- /* calculate how much space will be left */
- t = u8g2_GetDisplayHeight(lrc_u8g);
- t -= y;
-
- /* topmost pos start half of that empty space from the top */
- t >>= 1;
- y = u8g2_GetDisplayHeight(lrc_u8g);
- y -= t;
-
- y -= MNU_ENTRY_HEIGHT;
- mnu_DrawEntry(y, mnu_title, 0, 0);
-
- y -= MNU_ENTRY_HEIGHT;
-
-
- u8g2_DrawBitmap(lrc_u8g, 0, 1, 1, 8, chess_black_pieces_bm+24);
- u8g2_DrawBitmap(lrc_u8g, 128-8, 1, 1, 8, chess_black_pieces_bm+24);
-
-
- for( i = 0; i < mnu_max; i++ )
- {
- y -= MNU_ENTRY_HEIGHT;
- mnu_DrawEntry(y, mnu_list[i], 0, i == mnu_pos);
- }
-}
-
-void mnu_Step(uint8_t key_cmd)
-{
- if ( key_cmd == CHESS_KEY_NEXT )
- {
- if ( mnu_pos+1 < mnu_max )
- mnu_pos++;
- }
- else if ( key_cmd == CHESS_KEY_PREV )
- {
- if ( mnu_pos > 0 )
- mnu_pos--;
- }
-}
-
-
-
-
-
-
-
-const uint8_t chess_pieces_body_bm[] CHESS_PROGMEM =
-{
- /* PAWN */ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /* 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x00, */
- /* KNIGHT */ 0x00, 0x00, 0x1c, 0x2c, 0x04, 0x04, 0x0e, 0x00,
- /* BISHOP */ 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x08, 0x00, 0x00, /* 0x00, 0x00, 0x08, 0x1c, 0x1c, 0x08, 0x00, 0x00, */
- /* ROOK */ 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x00,
- /* QUEEN */ 0x00, 0x00, 0x14, 0x1c, 0x08, 0x1c, 0x08, 0x00,
- /* KING */ 0x00, 0x00, 0x00, 0x08, 0x3e, 0x1c, 0x08, 0x00,
-};
-
-#ifdef NOT_REQUIRED
-/* white pieces are constructed by painting black pieces and cutting out the white area */
-const uint8_t chess_white_pieces_bm[] CHESS_PROGMEM =
-{
- /* PAWN */ 0x00, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0x1e, 0x00,
- /* KNIGHT */ 0x00, 0x1c, 0x22, 0x52, 0x6a, 0x0a, 0x11, 0x1f,
- /* BISHOP */ 0x00, 0x08, 0x14, 0x22, 0x22, 0x14, 0x08, 0x7f,
- /* ROOK */ 0x00, 0x55, 0x7f, 0x22, 0x22, 0x22, 0x22, 0x7f,
- /* QUEEN */ 0x00, 0x55, 0x2a, 0x22, 0x14, 0x22, 0x14, 0x7f,
- /* KING */ 0x08, 0x1c, 0x49, 0x77, 0x41, 0x22, 0x14, 0x7f,
-};
-#endif
-
-const uint8_t chess_black_pieces_bm[] CHESS_PROGMEM =
-{
- /* PAWN */ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x3c, 0x00, /* 0x00, 0x00, 0x0c, 0x1e, 0x1e, 0x0c, 0x1e, 0x00, */
- /* KNIGHT */ 0x00, 0x1c, 0x3e, 0x7e, 0x6e, 0x0e, 0x1f, 0x1f,
- /* BISHOP */ 0x00, 0x1c, 0x2e, 0x3e, 0x3e, 0x1c, 0x08, 0x7f, /*0x00, 0x08, 0x1c, 0x3e, 0x3e, 0x1c, 0x08, 0x7f,*/
- /* ROOK */ 0x00, 0x55, 0x7f, 0x3e, 0x3e, 0x3e, 0x3e, 0x7f,
- /* QUEEN */ 0x00, 0x55, 0x3e, 0x3e, 0x1c, 0x3e, 0x1c, 0x7f,
- /* KING -*/ 0x08, 0x1c, 0x49, 0x7f, 0x7f, 0x3e, 0x1c, 0x7f,
-};
-
-
-#if defined(DOGXL160_HW_GR)
-#define BOXSIZE 13
-#define BOXOFFSET 3
-#else
-#define BOXSIZE 8
-#define BOXOFFSET 1
-#endif
-
-u8g2_uint_t chess_low_edge;
-uint8_t chess_boxsize = 8;
-uint8_t chess_boxoffset = 1;
-
-
-void chess_DrawFrame(uint8_t pos, uint8_t is_bold)
-{
- u8g2_uint_t x0, y0;
-
- x0 = pos;
- x0 &= 15;
- if ( lrc_obj.orientation != COLOR_WHITE )
- x0 ^= 7;
-
- y0 = pos;
- y0>>= 4;
- if ( lrc_obj.orientation != COLOR_WHITE )
- y0 ^= 7;
-
- x0 *= chess_boxsize;
- y0 *= chess_boxsize;
-
- u8g2_SetDefaultForegroundColor(lrc_u8g);
- u8g2_DrawFrame(lrc_u8g, x0, chess_low_edge - y0 - chess_boxsize+1, chess_boxsize, chess_boxsize);
-
-
- if ( is_bold )
- {
- x0--;
- y0++;
-
- u8g2_DrawFrame(lrc_u8g, x0, chess_low_edge - y0 - chess_boxsize +1, chess_boxsize+2, chess_boxsize+2);
- }
-}
-
-
-void chess_DrawBoard(void)
-{
- uint8_t i, j, cp;
- const uint8_t *ptr; /* pointer into CHESS_PROGMEM */
-
- {
- uint8_t x_offset = 1;
- u8g2_SetDefaultForegroundColor(lrc_u8g);
- for( i = 0; i < 8*8; i+=8 )
- {
- for( j = 0; j < 8*8; j+=8 )
- {
- if ( ((i^j) & 8) == 0 )
- {
- if ( lrc_obj.orientation == COLOR_WHITE )
- {
- cp = lrc_obj.board[i+j/8];
- }
- else
- {
- cp = lrc_obj.board[(7-i/8)*8+7-j/8];
- }
- if ( cp_GetPiece(cp) == PIECE_NONE )
- {
- u8g2_DrawPixel(lrc_u8g, j+0+x_offset, chess_low_edge - i-0);
- u8g2_DrawPixel(lrc_u8g, j+0+x_offset, chess_low_edge - i-2);
- u8g2_DrawPixel(lrc_u8g, j+0+x_offset, chess_low_edge - i-4);
- u8g2_DrawPixel(lrc_u8g, j+0+x_offset, chess_low_edge - i-6);
- u8g2_DrawPixel(lrc_u8g, j+2+x_offset, chess_low_edge - i-0);
- u8g2_DrawPixel(lrc_u8g, j+2+x_offset, chess_low_edge - i-6);
- u8g2_DrawPixel(lrc_u8g, j+4+x_offset, chess_low_edge - i-0);
- u8g2_DrawPixel(lrc_u8g, j+4+x_offset, chess_low_edge - i-6);
- u8g2_DrawPixel(lrc_u8g, j+6+x_offset, chess_low_edge - i-0);
- u8g2_DrawPixel(lrc_u8g, j+6+x_offset, chess_low_edge - i-2);
- u8g2_DrawPixel(lrc_u8g, j+6+x_offset, chess_low_edge - i-4);
- u8g2_DrawPixel(lrc_u8g, j+6+x_offset, chess_low_edge - i-6);
- }
- }
- }
- }
- }
-
- for ( i = 0; i < 8; i++ )
- {
- for ( j = 0; j < 8; j++ )
- {
- /* get piece from global board */
- if ( lrc_obj.orientation == COLOR_WHITE )
- {
- cp = lrc_obj.board[i*8+j];
- }
- else
- {
- cp = lrc_obj.board[(7-i)*8+7-j];
- }
- if ( cp_GetPiece(cp) != PIECE_NONE )
- {
- ptr = chess_black_pieces_bm;
- ptr += (cp_GetPiece(cp)-1)*8;
-
- u8g2_SetDefaultForegroundColor(lrc_u8g);
- u8g2_DrawBitmap(lrc_u8g, j*chess_boxsize+chess_boxoffset-1, chess_low_edge - (i*chess_boxsize+chess_boxsize-chess_boxoffset), 1, 8, ptr);
-
- if ( cp_GetColor(cp) == lrc_obj.strike_out_color )
- {
- ptr = chess_pieces_body_bm;
- ptr += (cp_GetPiece(cp)-1)*8;
- u8g2_SetDefaultBackgroundColor(lrc_u8g);
- u8g2_DrawBitmap(lrc_u8g, j*chess_boxsize+chess_boxoffset-1, chess_low_edge - (i*chess_boxsize+chess_boxsize-chess_boxoffset), 1, 8, ptr);
- }
- }
- }
- }
- u8g2_SetDefaultForegroundColor(lrc_u8g);
-
- if ( (chess_source_pos & 0x88) == 0 )
- {
- chess_DrawFrame(chess_source_pos, 1);
- }
-
- if ( (chess_target_pos & 0x88) == 0 )
- {
- chess_DrawFrame(chess_target_pos, 0);
- }
-
-}
-
-
-void chess_Thinking(void)
-{
-}
-
-void chess_Init(u8g2_t *u8g, uint8_t body_color)
-{
- lrc_u8g = u8g;
-
- chess_low_edge = u8g2_GetDisplayHeight(lrc_u8g);
- chess_low_edge--;
- u8g2_SetBitmapMode(u8g, 1); // restore previous behaviour
-
- {
-
- chess_boxsize = 8;
- chess_boxoffset = 1;
- }
-
-
-
- lrc_obj.strike_out_color = body_color;
- chess_SetupBoard();
-}
-
-
-
-void chess_Draw(void)
-{
- if ( chess_state == CHESS_STATE_MENU )
- {
- if ( lrc_obj.ply_count == 0)
- mnu_max = 2;
- else
- mnu_max = 4;
- mnu_Draw();
- }
- else
- {
- chess_DrawBoard();
-
- {
- uint8_t i;
- uint8_t entries = lrc_obj.chm_pos;
- if ( entries > 4 )
- entries = 4;
-
- u8g2_SetFont(lrc_u8g, u8g2_font_5x7_tr);
- u8g2_SetDefaultForegroundColor(lrc_u8g);
- for( i = 0; i < entries; i++ )
- {
-
- u8g2_DrawStr(lrc_u8g, u8g2_GetDisplayWidth(lrc_u8g)-35, 8*(i+1), cu_GetHalfMoveStr(lrc_obj.chm_pos-entries+i));
-
- }
-
- }
-
- if ( chess_state == CHESS_STATE_SELECT_PIECE )
- mnu_DrawHome(chess_source_pos == 255);
- else if ( chess_state == CHESS_STATE_SELECT_TARGET_POS )
- mnu_DrawHome(chess_target_pos == 255);
- else
- mnu_DrawHome(0);
-
- if ( chess_state == CHESS_STATE_GAME_END )
- {
- switch( lrc_obj.lost_side_color )
- {
- case COLOR_WHITE:
- mnu_DrawEntry(u8g2_GetDisplayHeight(lrc_u8g) / 2-2, "Black wins", 1, 1);
- break;
- case COLOR_BLACK:
- mnu_DrawEntry(u8g2_GetDisplayHeight(lrc_u8g) / 2-2, "White wins", 1, 1);
- break;
- default:
- mnu_DrawEntry(u8g2_GetDisplayHeight(lrc_u8g) / 2-2, "Stalemate", 1, 1);
- break;
- }
- }
- }
-}
-
-
-void chess_Step(uint8_t keycode)
-{
- chess_key_cmd = keycode;
-
- /*
- if ( keycode == CHESS_KEY_NONE )
- {
- chess_key_cmd = chess_key_code;
- chess_key_code = CHESS_KEY_NONE;
- }
- else
- {
- chess_key_cmd = CHESS_KEY_NONE;
- chess_key_code = keycode;
- }
- */
- //chess_ComputerMove(2);
- switch(chess_state)
- {
- case CHESS_STATE_MENU:
- mnu_Step(chess_key_cmd);
- if ( chess_key_cmd == CHESS_KEY_SELECT )
- {
- if ( mnu_pos == 0 )
- {
- chess_SetupBoard();
- lrc_obj.orientation = 0;
- chess_state = CHESS_STATE_SELECT_START;
- }
- else if ( mnu_pos == 1 )
- {
- chess_SetupBoard();
- lrc_obj.orientation = 1;
- chess_state = CHESS_STATE_THINKING;
- }
- else if ( mnu_pos == 2 )
- {
- if ( lrc_obj.ply_count >= 2 )
- {
- cu_UndoHalfMove();
- cu_UndoHalfMove();
- lrc_obj.ply_count-=2;
- if ( lrc_obj.ply_count == 0 )
- mnu_pos = 0;
- }
- chess_state = CHESS_STATE_SELECT_START;
- }
- else if ( mnu_pos == 3 )
- {
- chess_state = CHESS_STATE_SELECT_START;
- }
- }
- break;
- case CHESS_STATE_SELECT_START:
- chess_ClearMarks();
- chess_MarkMovable();
- chess_source_pos = chess_GetNextMarked(255, 0);
- chess_target_pos = ILLEGAL_POSITION;
- chess_state = CHESS_STATE_SELECT_PIECE;
- break;
-
- case CHESS_STATE_SELECT_PIECE:
- if ( chess_key_cmd == CHESS_KEY_NEXT )
- {
- chess_source_pos = chess_GetNextMarked(chess_source_pos, lrc_obj.orientation);
- }
- else if ( chess_key_cmd == CHESS_KEY_PREV )
- {
- chess_source_pos = chess_GetNextMarked(chess_source_pos, 1-lrc_obj.orientation );
- }
- else if ( chess_key_cmd == CHESS_KEY_SELECT )
- {
- if ( chess_source_pos == 255 )
- {
- chess_state = CHESS_STATE_MENU;
- }
- else
- {
- chess_ClearMarks();
- chess_MarkTargetMoves(chess_source_pos);
- chess_target_pos = chess_GetNextMarked(255, 0);
- chess_state = CHESS_STATE_SELECT_TARGET_POS;
- }
- }
- break;
- case CHESS_STATE_SELECT_TARGET_POS:
- if ( chess_key_cmd == CHESS_KEY_NEXT )
- {
- chess_target_pos = chess_GetNextMarked(chess_target_pos, lrc_obj.orientation);
- if ( chess_target_pos == 255 )
- chess_target_pos = chess_GetNextMarked(chess_target_pos, lrc_obj.orientation);
- }
- else if ( chess_key_cmd == CHESS_KEY_PREV )
- {
- chess_target_pos = chess_GetNextMarked(chess_target_pos, 1-lrc_obj.orientation);
- if ( chess_target_pos == 255 )
- chess_target_pos = chess_GetNextMarked(chess_target_pos, 1-lrc_obj.orientation);
- }
- else if ( chess_key_cmd == CHESS_KEY_BACK )
- {
- chess_ClearMarks();
- chess_MarkMovable();
- chess_target_pos = ILLEGAL_POSITION;
- chess_state = CHESS_STATE_SELECT_PIECE;
- }
- else if ( chess_key_cmd == CHESS_KEY_SELECT )
- {
- chess_ManualMove(chess_source_pos, chess_target_pos);
- if ( lrc_obj.is_game_end != 0 )
- chess_state = CHESS_STATE_GAME_END;
- else
- chess_state = CHESS_STATE_THINKING;
- /* clear marks as some kind of feedback to the user... it simply looks better */
- chess_source_pos = ILLEGAL_POSITION;
- chess_target_pos = ILLEGAL_POSITION;
- chess_ClearMarks();
- }
- break;
- case CHESS_STATE_THINKING:
- chess_ComputerMove(2);
- if ( lrc_obj.is_game_end != 0 )
- chess_state = CHESS_STATE_GAME_END;
- else
- chess_state = CHESS_STATE_SELECT_START;
- //chess_state = CHESS_STATE_THINKING
- break;
- case CHESS_STATE_GAME_END:
- if ( chess_key_cmd != CHESS_KEY_NONE )
- {
- chess_state = CHESS_STATE_MENU;
- chess_SetupBoard();
- }
- break;
- }
-
-}
-
-#endif /* UNIX_MAIN */
-
-void loop(void) {
- static uint8_t keycode = 0;
-
- u8g2.firstPage();
- do {
- chess_Draw();
- if ( keycode == 0 )
- keycode = u8g2.getMenuEvent();
- } while ( u8g2.nextPage() );
-
- if ( keycode == 0 )
- keycode = u8g2.getMenuEvent();
-
- if ( keycode == U8X8_MSG_GPIO_MENU_DOWN )
- keycode = CHESS_KEY_NEXT;
- if ( keycode == U8X8_MSG_GPIO_MENU_UP )
- keycode = CHESS_KEY_PREV;
- //if ( keycode == U8X8_MSG_GPIO_MENU_HOME )
- // keycode = CHESS_KEY_SELECT;
-
- chess_Step(keycode);
- keycode = 0;
- delay(1);
-}
-
diff --git a/.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games/SpaceTrash/SpaceTrash.ino b/.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games/SpaceTrash/SpaceTrash.ino
deleted file mode 100644
index 621c70b..0000000
--- a/.pio/libdeps/esp32-s3-n16r8/U8g2/examples/games/SpaceTrash/SpaceTrash.ino
+++ /dev/null
@@ -1,1857 +0,0 @@
-/*
-
- SpaceTrash.ino
-
- Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
-
- Copyright (c) 2016, olikraus@gmail.com
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list
- of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice, this
- list of conditions and the following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*/
-
-#include <Arduino.h>
-#include <U8g2lib.h>
-
-#ifdef U8X8_HAVE_HW_SPI
-#include <SPI.h>
-#endif
-#ifdef U8X8_HAVE_HW_I2C
-#include <Wire.h>
-#endif
-
-// Please UNCOMMENT one of the contructor lines below
-// U8g2 Contructor List (Picture Loop Page Buffer)
-// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp
-// Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected
-//U8G2_NULL u8g2(U8G2_R0); // null device, a 8x8 pixel display which does nothing
-//U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 12, /* dc=*/ 4, /* reset=*/ 6); // Arduboy (Production, Kickstarter Edition)
-//U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1306_128X64_NONAME_1_3W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8);
-//U8G2_SSD1306_128X64_NONAME_1_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 8);
-//U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SSD1306_128X64_ALT0_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // same as the NONAME variant, but may solve the "every 2nd line skipped" problem
-//U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* reset=*/ 8);
-//U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
-//U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 16, /* data=*/ 17, /* reset=*/ U8X8_PIN_NONE); // ESP32 Thing, pure SW emulated I2C
-//U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 16, /* data=*/ 17); // ESP32 Thing, HW I2C with pin remapping
-//U8G2_SSD1306_128X64_NONAME_1_6800 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8);
-//U8G2_SSD1306_128X64_NONAME_1_8080 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8);
-//U8G2_SSD1306_128X64_VCOMH0_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but maximizes setContrast() range
-//U8G2_SSD1306_128X64_ALT0_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but may solve the "every 2nd line skipped" problem
-//U8G2_SSD1306_102X64_EA_OLEDS102_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but may solve the "every 2nd line skipped" problem
-//U8G2_SSD1312_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1312_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ 8);
-//U8G2_SSD1312_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8);
-//U8G2_SSD1312_120X28_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1312_120X28_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ 8);
-//U8G2_SSD1312_120X28_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8);
-//U8G2_SH1106_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SH1106_128X64_VCOMH0_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but maximizes setContrast() range
-//U8G2_SH1106_128X64_WINSTAR_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but uses updated SH1106 init sequence
-//U8G2_SH1106_128X32_VISIONOX_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SH1106_128X32_VISIONOX_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1106_72X40_WISE_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1107_64X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1107_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1107_128X128_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8);
-//U8G2_SH1107_128X80_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8);
-//U8G2_SH1107_PIMORONI_128X128_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8);
-//U8G2_SH1107_SEEED_128X128_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SH1107_SEEED_128X128_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SH1107_SEEED_96X96_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1107_HJR_OEL1M0201_96X96_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1107_TK078F288_80X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1108_128X160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_CH1120_128X160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1108_160X160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SH1122_256X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SH1122_256X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1306_128X32_UNIVISION_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 21, /* data=*/ 20, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather M0 Basic Proto + FeatherWing OLED
-//U8G2_SSD1306_128X32_UNIVISION_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather ESP8266/32u4 Boards + FeatherWing OLED
-//U8G2_SSD1306_128X32_UNIVISION_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // Adafruit ESP8266/32u4/ARM Boards + FeatherWing OLED
-//U8G2_SSD1306_128X32_UNIVISION_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA); // pin remapping with ESP8266 HW I2C
-//U8G2_SSD1306_128X32_WINSTAR_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA); // pin remapping with ESP8266 HW I2C
-//U8G2_SSD1306_64X48_ER_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // EastRising 0.66" OLED breakout board, Uno: A4=SDA, A5=SCL, 5V powered
-//U8G2_SSD1306_48X64_WINSTAR_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SSD1306_64X32_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SSD1306_64X32_1F_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SSD1306_96X16_ER_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // EastRising 0.69" OLED
-//U8G2_SSD1306_72X40_ER_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // EastRising 0.42" OLED
-//U8G2_SSD1306_96X40_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SSD1306_96X39_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SSD1322_240X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1322_TOPWIN_240X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1322_NHD_256X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1322_NHD_256X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1322_ZJY_256X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1322_ZJY_256X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1362_256X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1362_256X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1362_206X36_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1362_206X36_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1363_256X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1363_256X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
-//U8G2_SSD1322_NHD_128X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1322_NHD_128X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1325_NHD_128X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1325_NHD_128X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD0323_OS128064_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD0323_OS128064_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1326_ER_256X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // experimental driver for ER-OLED018-1
-//U8G2_SSD1327_SEEED_96X96_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // Seeedstudio Grove OLED 96x96
-//U8G2_SSD1327_SEEED_96X96_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // Seeedstudio Grove OLED 96x96
-//U8G2_SSD1327_EA_W128128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_EA_W128128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_EA_W128128_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 5, /* data=*/ 4, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_SSD1327_EA_W128128_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); /* Uno: A4=SDA, A5=SCL, add "u8g2.setBusClock(400000);" into setup() for speedup if possible */
-//U8G2_SSD1327_MIDAS_128X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_MIDAS_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_MIDAS_128X128_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); /* Uno: A4=SDA, A5=SCL, add "u8g2.setBusClock(400000);" into setup() for speedup if possible */
-//U8G2_SSD1327_ZJY_128X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_ZJY_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_ZJY_128X128_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); /* Uno: A4=SDA, A5=SCL, add "u8g2.setBusClock(400000);" into setup() for speedup if possible */
-//U8G2_SSD1327_WS_128X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_WS_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_VISIONOX_128X96_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1327_VISIONOX_128X96_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1329_128X96_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1329_128X96_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1329_96X96_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1329_96X96_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1329_96X96_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ A4, /* dc=*/ A2, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather 32u4 Basic Proto
-//U8G2_SSD1305_128X32_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1305_128X32_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1305_128X32_ADAFRUIT_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1305_128X32_ADAFRUIT_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1305_128X64_ADAFRUIT_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1305_128X64_ADAFRUIT_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1305_128X64_RAYSTAR_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1305_128X64_RAYSTAR_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1309_128X64_NONAME0_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1309_128X64_NONAME0_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1309_128X128_NONAME0_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1309_128X128_NONAME0_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1309_128X64_NONAME2_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1309_128X64_NONAME2_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1316_128X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1316_128X32_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1316_96X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1316_96X32_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1317_96X96_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // not tested, not confirmed
-//U8G2_SSD1317_96X96_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // not tested, not confirmed
-//U8G2_SSD1318_128X96_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1318_128X96_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1320_160X132_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1320_160X132_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1320_160X80_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1320_160X80_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1320_128X72_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1320_128X72_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_LD7032_60X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 9, /* dc=*/ 10, /* reset=*/ 8); // SW SPI Nano Board
-//U8G2_LD7032_60X32_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* reset=*/ U8X8_PIN_NONE); // NOT TESTED!
-//U8G2_LD7032_60X32_ALT_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 9, /* dc=*/ 10, /* reset=*/ 8); // SW SPI Nano Board
-//U8G2_LD7032_60X32_ALT_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* reset=*/ U8X8_PIN_NONE); // NOT TESTED!
-//U8G2_LD7032_128X36_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 9, /* dc=*/ 10, /* reset=*/ 8); // SW SPI Nano Board
-//U8G2_LD7032_128X36_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* reset=*/ U8X8_PIN_NONE); // NOT TESTED!
-//U8G2_UC1701_EA_DOGS102_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1701_EA_DOGS102_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_PCD8544_84X48_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Nokia 5110 Display
-//U8G2_PCD8544_84X48_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Nokia 5110 Display
-//U8G2_PCF8812_96X65_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Could be also PCF8814
-//U8G2_PCF8812_96X65_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Could be also PCF8814
-//U8G2_PCF8812_101X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Could be also PCF8814
-//U8G2_PCF8812_101X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Could be also PCF8814
-//U8G2_HX1230_96X68_1_3W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8);
-//U8G2_HX1230_96X68_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_KS0108_128X64_1 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low!
-//U8G2_KS0108_ERM19264_1 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ 16, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low!
-//U8G2_HD44102_100X64_1 u8g2(U8G2_R0, 4, 5, 6, 7, 8, 9, 10, 11, /*enable=*/ 2, /*dc=*/ 3, /*cs0=*/ A0, /*cs1=*/ A1, /*cs2=*/ A2, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low!
-//U8G2_T7932_150X32_1 u8g2(U8G2_R0, 4, 5, 6, 7, 8, 9, 10, 11, /*enable=*/ 2, /*dc=*/ 3, /*cs0=*/ A0, /*cs1=*/ A1, /*cs2=*/ A2, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low!
-//U8G2_ST7920_256X32_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ U8X8_PIN_NONE, /*dc=*/ 17, /*reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_256X32_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_192X32_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ U8X8_PIN_NONE, /*dc=*/ 17, /*reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_192X32_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_128X32_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ U8X8_PIN_NONE, /*dc=*/ 17, /*reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_128X32_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_144X32_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ U8X8_PIN_NONE, /*dc=*/ 17, /*reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_144X32_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_160X32_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ U8X8_PIN_NONE, /*dc=*/ 17, /*reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_160X32_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_128X64_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18 /* A4 */, /*cs=*/ U8X8_PIN_NONE, /*dc/rs=*/ 17 /* A3 */, /*reset=*/ 15 /* A1 */); // Remember to set R/W to 0
-//U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8);
-//U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 14, /* data=*/ 13, /* CS=*/ 15, /* reset=*/ 16); // Feather HUZZAH ESP8266, E=clock=14, RW=data=13, RS=CS
-//U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8);
-//U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, /* CS=*/ 15, /* reset=*/ 16); // Feather HUZZAH ESP8266, E=clock=14, RW=data=13, RS=CS
-//U8G2_ST7528_ERC16064_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7528_ERC16064_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7539_192X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7539_192X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_EA_DOGM128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_EA_DOGM128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_64128N_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_64128N_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_EA_DOGM132_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE); // DOGM132 Shield
-//U8G2_ST7565_EA_DOGM132_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE); // DOGM132 Shield
-//U8G2_ST7565_ZOLEN_128X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_ZOLEN_128X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_LM6059_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Adafruit ST7565 GLCD
-//U8G2_ST7565_LM6059_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Adafruit ST7565 GLCD
-//U8G2_ST7565_KS0713_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // KS0713 controller
-//U8G2_ST7565_KS0713_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // KS0713 controller
-//U8G2_ST7565_LX12864_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_LX12864_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_ERC12864_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_ERC12864_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_ERC12864_ALT_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // contrast improved version for ERC12864
-//U8G2_ST7565_ERC12864_ALT_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // contrast improved version for ERC12864
-//U8G2_ST7565_NHD_C12832_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_NHD_C12832_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_NHD_C12864_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_NHD_C12864_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_JLX12864_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7565_JLX12864_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_PI_132X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8); // Pax Instruments Shield, LCD_BL=6
-//U8G2_ST7567_PI_132X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8); // Pax Instruments Shield, LCD_BL=6
-//U8G2_ST7567_JLX12864_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_JLX12864_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_122X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_122X32_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_OS12864_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_OS12864_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_ENH_DG128064_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_ENH_DG128064_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_ENH_DG128064I_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_ENH_DG128064I_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_64X32_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7567_HEM6432_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_ST7567_ERC13232_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_ERC13232_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_96X65_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7567_96X65_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7571_128X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7571_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7571_128X96_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7571_128X96_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7571_G12896_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7571_G12896_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7302_122X250_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7305_122X250_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7305_200X200_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7305_168X384_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7305_300X400_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7586S_JLX384160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno: Enable U8g2 16 bit mode for this display
-//U8G2_ST7586S_ERC240160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7586S_YMC240160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7586S_JLX320160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno: Enable U8g2 16 bit mode for this display
-//U8G2_ST75160_JM16096_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75160_JM16096_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75161_JLX160160_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75161_JLX160160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX172104_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX172104_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX19296_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX19296_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX16080_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX16080_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX256128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_128X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_WO256X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_WO256X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 9, /* data=*/ 8, /* cs=*/ 7, /* dc=*/ 6, /* reset=*/ 5); // MKR Zero, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 6, /* reset=*/ 5); // MKR Zero, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256160_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256160M_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256160M_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256160_ALT_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX256160_ALT_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75256_JLX240160_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX240160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST75256_JLX25664_1_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8); // Due, 2nd I2C, enable U8g2 16 bit mode for this display
-//U8G2_ST75320_JLX320240_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_ST75320_JLX320240_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Uno, Enable U8g2 16 bit mode for this display
-//U8G2_NT7534_TG12864R_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_NT7534_TG12864R_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_ST7588_JLX12864_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ 5);
-//U8G2_ST7588_JLX12864_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ 5);
-//U8G2_IST3020_ERC19264_1_6800 u8g2(U8G2_R0, 44, 43, 42, 41, 40, 39, 38, 37, /*enable=*/ 28, /*cs=*/ 32, /*dc=*/ 30, /*reset=*/ 31); // Connect WR pin with GND
-//U8G2_IST3020_ERC19264_1_8080 u8g2(U8G2_R0, 44, 43, 42, 41, 40, 39, 38, 37, /*enable=*/ 29, /*cs=*/ 32, /*dc=*/ 30, /*reset=*/ 31); // Connect RD pin with 3.3V
-//U8G2_IST3020_ERC19264_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_IST3088_320X240_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_IST3088_320X240_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_IST7920_128X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Round display
-//U8G2_IST7920_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Round display
-//U8G2_LC7981_160X80_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
-//U8G2_LC7981_160X160_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
-//U8G2_LC7981_240X128_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
-//U8G2_LC7981_240X64_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
-//U8G2_LC7981_128X128_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
-//U8G2_SED1520_122X32_1 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*dc=*/ A0, /*e1=*/ A3, /*e2=*/ A2, /* reset=*/ A4); // Set R/W to low!
-//U8G2_T6963_240X128_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
-//U8G2_T6963_256X64_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
-//U8G2_T6963_160X80_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
-//U8G2_T6963_128X64_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
-//U8G2_T6963_128X64_ALT_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
-//U8G2_T6963_128X160_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
-//U8G2_SED1330_240X64_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect /RD = E with +5V, enable is /WR = RW, FG with GND, 14=Uno Pin A0
-//U8G2_SED1330_240X128_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect /RD = E with +5V, enable is /WR = RW, FG with GND, 14=Uno Pin A0
-//U8G2_SED1330_240X128_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // A0 is dc pin, /WR = RW = GND, enable is /RD = E
-//U8G2_SED1330_256X128_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect /RD = E with +5V, enable is /WR = RW, FG with GND, 14=Uno Pin A0, enable U8g2 16Bit Mode
-//U8G2_SED1330_256X128_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // A0 is dc pin, /WR = RW = GND, enable is /RD = E, enable U8g2 16Bit Mode
-//U8G2_SED1330_320X200_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect /RD = E with +5V, enable is /WR = RW, FG with GND, 14=Uno Pin A0, enable U8g2 16Bit Mode
-//U8G2_SED1330_320X200_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // A0 is dc pin, /WR = RW = GND, enable is /RD = E, enable U8g2 16Bit Mode
-//U8G2_RA8835_NHD_240X128_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect /RD = E with +5V, enable is /WR = RW, FG with GND, 14=Uno Pin A0
-//U8G2_RA8835_NHD_240X128_1_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // A0 is dc pin, /WR = RW = GND, enable is /RD = E
-//U8G2_UC1601_128X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1601_128X32_1_3W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8);
-//U8G2_UC1601_128X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1604_JLX19264_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1604_JLX19264_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1609_SLG19264_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1609_SLG19264_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1608_ERC24064_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due ERC24064-1 Test Setup
-//U8G2_UC1608_DEM240064_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due ERC24064-1 Test Setup
-//U8G2_UC1608_ERC240120_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1608_240X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due ERC24064-1 Test Setup
-//U8G2_UC1610_EA_DOGXL160_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_UC1610_EA_DOGXL160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE);
-//U8G2_UC1611_EA_DOGM240_1_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8); // Due, 2nd I2C, DOGM240 Test Board
-//U8G2_UC1611_EA_DOGM240_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due DOGXL240 Test Board
-//U8G2_UC1611_EA_DOGXL240_1_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8); // Due, 2nd I2C, DOGXL240 Test Board
-//U8G2_UC1611_EA_DOGXL240_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due DOGXL240 Test Board
-//U8G2_UC1611_EW50850_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 3, /*dc=*/ 16, /*reset=*/ 17); // 240x160, Connect RD/WR1 pin with 3.3V, CS is aktive high
-//U8G2_UC1611_CG160160_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 3, /*dc=*/ 16, /*reset=*/ 17); // Connect WR1 and CD1 pin with 3.3V, connect CS0 with cs, WR0 with enable, CD with dc
-//U8G2_UC1611_IDS4073_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8g2 16Bit Mode
-//U8G2_UC1611_IDS4073_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8g2 16Bit Mode
-//U8G2_UC1617_JLX128128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1617_JLX128128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1628_128X64_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 3, /*dc=*/ 16, /*reset=*/ 17); // UC1628 pin names: enable: /WR, dc: CD
-//U8G2_UC1628_128X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1628_128X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1628_256X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1628_256X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1628_256X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1628_256X32_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1638_192X96_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1638_192X96_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1638_192X96_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* reset=*/ 8); // u8g2 test board: I2C clock/data is same as SPI, I2C default address is 0x78
-//U8G2_UC1638_240X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1638_240X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1638_240X128_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* reset=*/ 8); // u8g2 test board: I2C clock/data is same as SPI, I2C default address is 0x78
-//U8G2_UC1698_160X160_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_UC1698_160X160_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_SSD1606_172X72_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // eInk/ePaper Display
-//U8G2_SSD1607_200X200_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // eInk/ePaper Display, original LUT from embedded artists
-//U8G2_SSD1607_GD_200X200_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Good Display
-//U8G2_SSD1607_WS_200X200_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Waveshare
-//U8G2_IL3820_296X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // WaveShare 2.9 inch eInk/ePaper Display, enable 16 bit mode for this display!
-//U8G2_IL3820_V2_296X128_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // ePaper Display, lesser flickering and faster speed, enable 16 bit mode for this display!
-//U8G2_LS013B7DH03_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ 8); // there is no DC line for this display
-//U8G2_LS027B7DH01_400X240_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ 8); // there is no DC line for this display, SPI Mode 2
-//U8G2_LS027B7DH01_M0_400X240_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ 8); // there is no DC line for this display, SPI Mode 0
-//U8G2_LS013B7DH05_144X168_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ 8); // there is no DC line for this display
-//U8G2_ST7511_AVD_320X240_1_8080 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable/WR=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); // Enable U8g2 16Bit Mode and connect RD pin with 3.3V/5V
-//U8G2_ST7511_640X320_1_8080 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable/WR=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); // Enable U8g2 16Bit Mode and connect RD pin with 3.3V/5V
-//U8G2_S1D15300_LM6023_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_S1D15300_LM6023_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_S1D15300_100X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_S1D15300_100X32_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_S1D15300_100X32I_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_S1D15300_100X32I_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_S1D15721_240X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_S1D15721_240X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_GU800_128X64_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_GU800_128X64_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_GU800_160X16_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_GU800_160X16_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
-//U8G2_GP1294AI_256X48_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/10, /* dc=*/U8X8_PIN_NONE, /* reset=*/8);
-
-
-
-
-// End of constructor list
-
-
-
-/* button setup for Arduboy Production */
-uint8_t pin_up = A0;
-uint8_t pin_down = A3;
-uint8_t pin_fire = 7;
-
-
-
-
-#define ST_FP 4
-
-/* object types */
-struct _st_ot_struct
-{
- /*
- missle and hit:
- bit 0: player missle and trash
- bit 1: trash, which might hit the player
- */
-
- uint8_t missle_mask; /* this object is a missle: it might destroy something if the target is_hit_fn says so */
- uint8_t hit_mask; /* if missle_mask & hit_mask is != 0 then the object can be destroyed */
- uint8_t points;
- uint8_t draw_fn;
- uint8_t move_fn;
- /* ST_MOVE_FN_NONE, ST_MOVE_FN_X_SLOW */
- uint8_t destroy_fn; /* object can be destroyed by a missle (e.g. a missle from the space ship) */
- /* ST_DESTROY_FN_NONE, ST_DESTROY_FN_SPLIT */
- uint8_t is_hit_fn; /* is hit procedure */
- /* ST_IS_HIT_FN_NONE, ST_IS_HIT_BBOX */
- uint8_t fire_fn;
- /* ST_FIRE_FN_NONE, ST_FIRE_FN_X_LEFT */
-
-};
-typedef struct _st_ot_struct st_ot;
-
-/*
- objects, which are visible at the play area
-*/
-struct _st_obj_struct
-{
- uint8_t ot; /* object type: zero means, object is not used */
- int8_t tmp; /* generic value, used by ST_MOVE_IMPLODE */
- /* absolute position */
- /* LCD pixel position is x>>ST_FP and y>>ST_FP */
- int16_t x, y;
- int8_t x0,y0,x1,y1; /* object outline in pixel, reference point is at 0,0 */
-};
-typedef struct _st_obj_struct st_obj;
-
-#define ST_DRAW_NONE 0
-#define ST_DRAW_BBOX 1
-#define ST_DRAW_TRASH1 2
-#define ST_DRAW_PLAYER1 3
-#define ST_DRAW_TRASH2 4
-#define ST_DRAW_PLAYER2 5
-#define ST_DRAW_PLAYER3 6
-#define ST_DRAW_GADGET 7
-#define ST_DRAW_BACKSLASH 8
-#define ST_DRAW_SLASH 9
-#define ST_DRAW_BIG_TRASH 10
-
-#define ST_MOVE_NONE 0
-#define ST_MOVE_X_SLOW 1
-#define ST_MOVE_PX_NORMAL 2
-#define ST_MOVE_PX_FAST 3
-#define ST_MOVE_PLAYER 4
-#define ST_MOVE_PY 5
-#define ST_MOVE_NY 6
-#define ST_MOVE_IMPLODE 7
-#define ST_MOVE_X_FAST 8
-#define ST_MOVE_WALL 9
-#define ST_MOVE_NXPY 10
-#define ST_MOVE_NXNY 11
-
-#define ST_IS_HIT_NONE 0
-#define ST_IS_HIT_BBOX 1
-#define ST_IS_HIT_WALL 2
-
-#define ST_DESTROY_NONE 0
-#define ST_DESTROY_DISAPPEAR 1
-#define ST_DESTROY_TO_DUST 2
-#define ST_DESTROY_GADGET 3
-#define ST_DESTROY_PLAYER 4
-#define ST_DESTROY_PLAYER_GADGETS 5
-#define ST_DESTROY_BIG_TRASH 6
-
-#define ST_FIRE_NONE 0
-#define ST_FIRE_PLAYER1 1
-#define ST_FIRE_PLAYER2 2
-#define ST_FIRE_PLAYER3 3
-
-#define ST_OT_WALL_SOLID 1
-#define ST_OT_BIG_TRASH 2
-#define ST_OT_MISSLE 3
-#define ST_OT_TRASH1 4
-#define ST_OT_PLAYER 5
-#define ST_OT_DUST_PY 6
-#define ST_OT_DUST_NY 7
-#define ST_OT_TRASH_IMPLODE 8
-#define ST_OT_TRASH2 9
-#define ST_OT_PLAYER2 10
-#define ST_OT_PLAYER3 11
-#define ST_OT_GADGET 12
-#define ST_OT_GADGET_IMPLODE 13
-#define ST_OT_DUST_NXPY 14
-#define ST_OT_DUST_NXNY 15
-
-
-/*================================================================*/
-/* graphics object */
-/*================================================================*/
-
-u8g2_t *st_u8g2;
-
-u8g2_uint_t u8g_height_minus_one;
-
-
-#define ST_AREA_HEIGHT (st_u8g2->height - 8)
-#define ST_AREA_WIDTH (st_u8g2->width)
-
-
-/*================================================================*/
-/* object types */
-/*================================================================*/
-
-
-const st_ot st_object_types[] U8X8_PROGMEM =
-{
- /* 0: empty object type */
- { 0, 0, 0, ST_DRAW_NONE, ST_MOVE_NONE, ST_DESTROY_DISAPPEAR, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* 1: wall, player will be destroyed */
- { 2, 1, 30, ST_DRAW_BBOX, ST_MOVE_WALL, ST_DESTROY_DISAPPEAR, ST_IS_HIT_WALL, ST_FIRE_NONE },
- /* ST_OT_BIG_TRASH (2) */
- { 2, 1, 0, ST_DRAW_BIG_TRASH, ST_MOVE_X_SLOW, ST_DESTROY_BIG_TRASH, ST_IS_HIT_BBOX, ST_FIRE_NONE },
- /* 3: simple space ship (player) missle */
- { 1, 0, 0, ST_DRAW_BBOX, ST_MOVE_PX_FAST, ST_DESTROY_DISAPPEAR, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_TRASH1 (4): trash */
- { 2, 1, 0, ST_DRAW_TRASH1, ST_MOVE_X_SLOW, ST_DESTROY_TO_DUST, ST_IS_HIT_BBOX, ST_FIRE_NONE },
- /* ST_OT_PLAYER (5): player space ship */
- { 0, 2, 0, ST_DRAW_PLAYER1, ST_MOVE_PLAYER, ST_DESTROY_PLAYER, ST_IS_HIT_BBOX, ST_FIRE_PLAYER1 },
- /* ST_OT_DUST_PY (6): Last part of trash */
- { 0, 0, 0, ST_DRAW_BBOX, ST_MOVE_PY, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_DUST_NY (7): Last part of trash */
- { 0, 0, 0, ST_DRAW_BBOX, ST_MOVE_NY, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_TRASH_IMPLODE (8): trash was hit */
- { 0, 0, 5, ST_DRAW_TRASH1, ST_MOVE_IMPLODE, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_TRASH2 (9): trash */
- { 2, 1, 0, ST_DRAW_TRASH2, ST_MOVE_X_SLOW, ST_DESTROY_TO_DUST, ST_IS_HIT_BBOX, ST_FIRE_NONE },
- /* ST_OT_PLAYER2 (10): player space ship+1x enhancement */
- { 0, 2, 0, ST_DRAW_PLAYER2, ST_MOVE_PLAYER, ST_DESTROY_PLAYER_GADGETS, ST_IS_HIT_BBOX, ST_FIRE_PLAYER2 },
- /* ST_OT_PLAYER3 (11): player space ship+2x enhancement */
- { 0, 2, 0, ST_DRAW_PLAYER3, ST_MOVE_PLAYER, ST_DESTROY_PLAYER_GADGETS, ST_IS_HIT_BBOX, ST_FIRE_PLAYER3 },
- /* ST_OT_GADGET (12): adds enhancements */
- { 0, 1, 0, ST_DRAW_GADGET, ST_MOVE_X_FAST, ST_DESTROY_GADGET, ST_IS_HIT_BBOX, ST_FIRE_NONE },
- /* ST_OT_GADGET_IMPLODE (13) */
- { 0, 0, 20, ST_DRAW_GADGET, ST_MOVE_IMPLODE, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_DUST_NXPY (14): Last part of trash */
- { 0, 0, 0, ST_DRAW_BACKSLASH, ST_MOVE_NXPY, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_DUST_NXNY (15): Last part of trash */
- { 0, 0, 0, ST_DRAW_SLASH, ST_MOVE_NXNY, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
-
-};
-
-/*================================================================*/
-/* list of all objects on the screen */
-/*================================================================*/
-
-/* use AVR RAMEND constant to derive the number of allowed objects */
-
-#if RAMEND < 0x300
-#define ST_OBJ_CNT 25
-#else
-//#define ST_OBJ_CNT 45
-#define ST_OBJ_CNT 60
-#endif
-
-st_obj st_objects[ST_OBJ_CNT];
-
-/*================================================================*/
-/* about players space ship*/
-/*================================================================*/
-
-/* player position */
-uint8_t st_player_pos;
-
-/* points */
-#define ST_POINTS_PER_LEVEL 25
-uint16_t st_player_points;
-uint16_t st_player_points_delayed;
-uint16_t st_highscore = 0;
-
-/*================================================================*/
-/* overall game state */
-/*================================================================*/
-
-#define ST_STATE_PREPARE 0
-#define ST_STATE_IPREPARE 1
-#define ST_STATE_GAME 2
-#define ST_STATE_END 3
-#define ST_STATE_IEND 4
-
-uint8_t st_state = ST_STATE_PREPARE;
-
-/*================================================================*/
-/* game difficulty */
-/*================================================================*/
-uint8_t st_difficulty = 1;
-#define ST_DIFF_VIS_LEN 30
-#define ST_DIFF_FP 5
-uint16_t st_to_diff_cnt = 0;
-
-/*================================================================*/
-/* bitmaps */
-/*================================================================*/
-
-const uint8_t st_bitmap_player1[] =
-{
- /* 01100000 */ 0x060,
- /* 11111000 */ 0x0f8,
- /* 01111110 */ 0x07e,
- /* 11111000 */ 0x0f8,
- /* 01100000 */ 0x060
-};
-
-const uint8_t st_bitmap_player2[] =
-{
- /* 01100000 */ 0x060,
- /* 01111100 */ 0x078,
- /* 01100000 */ 0x060,
- /* 11100000 */ 0x0e0,
- /* 11111000 */ 0x0f8,
- /* 01111110 */ 0x07e,
- /* 11111000 */ 0x0f8,
- /* 01100000 */ 0x060
-};
-
-const uint8_t st_bitmap_player3[] =
-{
- /* 01100000 */ 0x060,
- /* 01111100 */ 0x078,
- /* 01100000 */ 0x060,
- /* 11100000 */ 0x0e0,
- /* 11111000 */ 0x0f8,
- /* 01111110 */ 0x07e,
- /* 11111000 */ 0x0f8,
- /* 11100000 */ 0x0e0,
- /* 01100000 */ 0x060,
- /* 01111100 */ 0x078,
- /* 01100000 */ 0x060
- };
-
-const uint8_t st_bitmap_trash_5x5_1[] =
-{
- /* 01110000 */ 0x070,
- /* 11110000 */ 0x0f0,
- /* 11111000 */ 0x0f8,
- /* 01111000 */ 0x078,
- /* 00110000 */ 0x030,
-};
-
-const uint8_t st_bitmap_trash_5x5_2[] =
-{
- /* 00110000 */ 0x030,
- /* 11111000 */ 0x0f8,
- /* 11111000 */ 0x0f8,
- /* 11110000 */ 0x0f0,
- /* 01110000 */ 0x070,
-};
-
-const uint8_t st_bitmap_trash_7x7[] =
-{
- /* 00111000 */ 0x038,
- /* 01111100 */ 0x07c,
- /* 11111100 */ 0x0fc,
- /* 11111110 */ 0x0fe,
- /* 11111110 */ 0x0fe,
- /* 01111110 */ 0x07e,
- /* 01111000 */ 0x078,
-};
-
-const uint8_t st_bitmap_gadget[] =
-{
- /* 01110000 */ 0x070,
- /* 11011000 */ 0x0d8,
- /* 10001000 */ 0x088,
- /* 11011000 */ 0x0d8,
- /* 01110000 */ 0x070,
-};
-
-/*================================================================*/
-/* forward definitions */
-/*================================================================*/
-uint8_t st_rnd(void) U8X8_NOINLINE;
-static st_obj *st_GetObj(uint8_t objnr) U8X8_NOINLINE;
-uint8_t st_GetMissleMask(uint8_t objnr);
-uint8_t st_GetHitMask(uint8_t objnr);
-int8_t st_FindObj(uint8_t ot) U8X8_NOINLINE;
-void st_ClrObjs(void) U8X8_NOINLINE;
-int8_t st_NewObj(void) U8X8_NOINLINE;
-uint8_t st_CntObj(uint8_t ot);
-uint8_t st_CalcXY(st_obj *o) U8X8_NOINLINE;
-void st_SetXY(st_obj *o, uint8_t x, uint8_t y) U8X8_NOINLINE;
-
-void st_FireStep(uint8_t is_auto_fire, uint8_t is_fire) U8X8_NOINLINE;
-
-void st_InitTrash(uint8_t x, uint8_t y, int8_t dir);
-void st_NewGadget(uint8_t x, uint8_t y);
-void st_NewPlayerMissle(uint8_t x, uint8_t y) ;
-void st_NewTrashDust(uint8_t x, uint8_t y, int ot);
-void st_NewTrashDustAreaArgs(int16_t x, int16_t y, int ot);
-void st_SetupPlayer(uint8_t objnr, uint8_t ot);
-
-
-/*================================================================*/
-/* utility functions */
-/*================================================================*/
-
-char st_itoa_buf[12];
-char *st_itoa(unsigned long v)
-{
- volatile unsigned char i = 11;
- st_itoa_buf[11] = '\0';
- while( i > 0)
- {
- i--;
- st_itoa_buf[i] = (v % 10)+'0';
- v /= 10;
- if ( v == 0 )
- break;
- }
- return st_itoa_buf+i;
-}
-
-
-uint8_t st_rnd(void)
-{
- return rand();
-}
-
-/*
- for the specified index number, return the object
-*/
-static st_obj *st_GetObj(uint8_t objnr)
-{
- return st_objects+objnr;
-}
-
-
-/*
- check, if this is a missle-like object (that is, can this object destroy something else)
-*/
-uint8_t st_GetMissleMask(uint8_t objnr)
-{
- st_obj *o = st_GetObj(objnr);
- return u8x8_pgm_read(&(st_object_types[o->ot].missle_mask));
-}
-
-/*
- check, if this is a missle-like object (that is, can this object destroy something else)
-*/
-uint8_t st_GetHitMask(uint8_t objnr)
-{
- st_obj *o = st_GetObj(objnr);
- return u8x8_pgm_read(&(st_object_types[o->ot].hit_mask));
-}
-
-/*
- search an empty object
-*/
-int8_t st_FindObj(uint8_t ot)
-{
- int8_t i;
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == ot )
- return i;
- }
- return -1;
-}
-
-/*
- delete all objects
-*/
-
-void st_ClrObjs(void)
-{
- int8_t i;
- for( i = 0; i < ST_OBJ_CNT; i++ )
- st_objects[i].ot = 0;
-}
-
-/*
- search an empty object
-*/
-int8_t st_NewObj(void)
-{
- int8_t i;
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == 0 )
- return i;
- }
- return -1;
-}
-
-/*
- count number of objectes of the provided type
- st_CntObj(0) will return the number of empty objects, that means if
- st_CntObj(0) > 0 then st_NewObj() will return a valid index
-*/
-uint8_t st_CntObj(uint8_t ot)
-{
- uint8_t i;
- uint8_t cnt = 0;
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == ot )
- cnt++;
- }
- return cnt;
-}
-
-/*
- calculate the pixel coordinates of the reference point of an object
- return rhe x value
-*/
-uint8_t st_px_x, st_px_y; /* pixel within area */
-uint8_t st_CalcXY(st_obj *o)
-{
- //st_obj *o = st_GetObj(objnr);
- st_px_y = o->y>>ST_FP;
- st_px_x = o->x>>ST_FP;
- return st_px_x;
-}
-
-void st_SetXY(st_obj *o, uint8_t x, uint8_t y)
-{
- o->x = ((int16_t)x) << ST_FP;
- o->y = ((int16_t)y) << ST_FP;
-}
-
-/*
- calculate the object bounding box and place it into some global variables
-*/
-int16_t st_bbox_x0, st_bbox_y0, st_bbox_x1, st_bbox_y1;
-
-void st_CalcBBOX(uint8_t objnr)
-{
- st_obj *o = st_GetObj(objnr);
-
- st_bbox_x0 = (uint16_t)(o->x>>ST_FP);
- st_bbox_x1 = st_bbox_x0;
- st_bbox_x0 += o->x0;
- st_bbox_x1 += o->x1;
-
- st_bbox_y0 = (uint16_t)(o->y>>ST_FP);
- st_bbox_y1 = st_bbox_y0;
- st_bbox_y0 += o->y0;
- st_bbox_y1 += o->y1;
-}
-
-/*
- clip bbox with the view window. requires a call to st_CalcBBOX
- return 0, if the bbox is totally outside the window
-*/
-uint8_t st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1;
-uint8_t st_ClipBBOX(void)
-{
- if ( st_bbox_x0 >= ST_AREA_WIDTH )
- return 0;
- if ( st_bbox_x0 >= 0 )
- st_cbbox_x0 = (uint16_t)st_bbox_x0;
- else
- st_cbbox_x0 = 0;
-
- if ( st_bbox_x1 < 0 )
- return 0;
- if ( st_bbox_x1 < ST_AREA_WIDTH )
- st_cbbox_x1 = (uint16_t)st_bbox_x1;
- else
- st_cbbox_x1 = ST_AREA_WIDTH-1;
-
- if ( st_bbox_y0 >= ST_AREA_HEIGHT )
- return 0;
- if ( st_bbox_y0 >= 0 )
- st_cbbox_y0 = (uint16_t)st_bbox_y0;
- else
- st_cbbox_y0 = 0;
-
- if ( st_bbox_y1 < 0 )
- return 0;
- if ( st_bbox_y1 < ST_AREA_HEIGHT )
- st_cbbox_y1 = (uint16_t)st_bbox_y1;
- else
- st_cbbox_y1 = ST_AREA_HEIGHT-1;
-
- return 1;
-}
-
-
-/*================================================================*/
-/* universal member functions */
-/*================================================================*/
-
-
-uint8_t st_IsOut(uint8_t objnr)
-{
- st_CalcBBOX(objnr);
- if ( st_bbox_x0 >= ST_AREA_WIDTH )
- return 1;
- if ( st_bbox_x1 < 0 )
- return 1;
- if ( st_bbox_y0 >= ST_AREA_HEIGHT )
- return 1;
- if ( st_bbox_y1 < 0 )
- return 1;
- return 0;
-}
-
-void st_Disappear(uint8_t objnr)
-{
- st_obj *o = st_GetObj(objnr);
- st_player_points += u8x8_pgm_read(&(st_object_types[o->ot].points));
- o->ot = 0;
-}
-
-/*================================================================*/
-/* type dependent member functions */
-/*================================================================*/
-
-void st_Move(uint8_t objnr)
-{
- st_obj *o = st_GetObj(objnr);
- switch(u8x8_pgm_read(&(st_object_types[o->ot].move_fn)))
- {
- case ST_MOVE_NONE:
- break;
- case ST_MOVE_X_SLOW:
- o->x -= (1<<ST_FP)/8;
- o->x -= st_difficulty;
- o->y += (int16_t)o->tmp;
- if ( o->y >= ((ST_AREA_HEIGHT-1) << ST_FP) || o->y <= 0 )
- o->tmp = - o->tmp;
- break;
- case ST_MOVE_X_FAST:
- o->x -= (1<<ST_FP)/2;
- o->y += (int16_t)o->tmp;
- if ( o->y >= ((ST_AREA_HEIGHT-1) << ST_FP) || o->y <= 0 )
- o->tmp = - o->tmp;
- break;
- case ST_MOVE_PX_NORMAL:
- o->x += (1<<ST_FP)/4;
- break;
- case ST_MOVE_PX_FAST:
- o->x += (1<<ST_FP);
- break;
- case ST_MOVE_PLAYER:
- o->y = st_player_pos<<ST_FP;
- break;
- case ST_MOVE_PY:
- o->y += 3*ST_FP;
- break;
- case ST_MOVE_NY:
- o->y -= 3*ST_FP;
- break;
- case ST_MOVE_NXPY:
- o->y += 3*ST_FP;
- o->x -= 3*ST_FP;
- break;
- case ST_MOVE_NXNY:
- o->y -= 3*ST_FP;
- o->x -= 3*ST_FP;
- break;
- case ST_MOVE_IMPLODE:
- o->tmp++;
- if ( (o->tmp & 0x03) == 0 )
- {
- if ( o->x0 != o->x1 )
- o->x0++;
- else
- st_Disappear(objnr);
- }
- break;
- case ST_MOVE_WALL:
- o->x -= 1;
- o->x -= (st_difficulty>>1);
- break;
- }
-}
-
-void st_DrawBBOX(uint8_t objnr)
-{
- uint8_t y0, y1;
- /*st_obj *o = st_GetObj(objnr);*/
- st_CalcBBOX(objnr);
- if ( st_ClipBBOX() == 0 )
- return;
- /* st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1; */
-
-
- // w = st_cbbox_x1-st_cbbox_x0;
- // w++;
- // h = st_cbbox_y1-st_cbbox_y0;
- // h++;
-
-
- //dog_SetVLine(st_cbbox_x0, st_cbbox_y0, st_cbbox_y1);
- //dog_SetVLine(st_cbbox_x1, st_cbbox_y0, st_cbbox_y1);
- //dog_SetHLine(st_cbbox_x0, st_cbbox_x1, st_cbbox_y0);
- //dog_SetHLine(st_cbbox_x0, st_cbbox_x1, st_cbbox_y1);
-
- u8g2_SetDrawColor(st_u8g2, 1);
- y0 = u8g_height_minus_one - st_cbbox_y0;
- y1 = u8g_height_minus_one - st_cbbox_y1;
-
- u8g2_DrawFrame(st_u8g2, st_cbbox_x0, y1, st_cbbox_x1-st_cbbox_x0+1, y0-y1+1);
-
- //dog_SetBox(st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1);
-
- /*
- if ( o->ot == ST_OT_PLAYER )
- {
- dog_DrawStr(0, 26, font_4x6, st_itoa(st_cbbox_y0));
- dog_DrawStr(10, 26, font_4x6, st_itoa(st_cbbox_y1));
- }
- */
-}
-
-#ifdef FN_IS_NOT_IN_USE
-void st_DrawFilledBox(uint8_t objnr)
-{
- st_CalcBBOX(objnr);
- if ( st_ClipBBOX() == 0 )
- return;
- /* st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1; */
- dog_SetBox(st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1);
-}
-#endif
-
-void st_DrawBitmap(uint8_t objnr, const uint8_t * bm, uint8_t w, uint8_t h)
-{
- /* st_obj *o = st_GetObj(objnr); */
- st_CalcBBOX(objnr);
- /* result is here: int16_t st_bbox_x0, st_bbox_y0, st_bbox_x1, st_bbox_y1 */
- //dog_SetBitmapP(st_bbox_x0,st_bbox_y1,bm,w,h);
-
- u8g2_DrawBitmap(st_u8g2, st_bbox_x0, u8g_height_minus_one - st_bbox_y1, (w+7)/8, h, bm);
-
- }
-
-void st_DrawObj(uint8_t objnr)
-{
- st_obj *o = st_GetObj(objnr);
- switch(u8x8_pgm_read(&(st_object_types[o->ot].draw_fn)))
- {
- case ST_DRAW_NONE:
- break;
- case ST_DRAW_BBOX:
- st_DrawBBOX(objnr);
- break;
- case ST_DRAW_TRASH1:
- st_DrawBitmap(objnr, st_bitmap_trash_5x5_1,o->x1-o->x0+1, 5);
- break;
- case ST_DRAW_TRASH2:
- st_DrawBitmap(objnr, st_bitmap_trash_5x5_2,o->x1-o->x0+1, 5);
- break;
- case ST_DRAW_BIG_TRASH:
- st_DrawBitmap(objnr, st_bitmap_trash_7x7,o->x1-o->x0+1, 7);
- break;
- case ST_DRAW_PLAYER1:
- st_DrawBitmap(objnr, st_bitmap_player1,7,5);
- break;
- case ST_DRAW_PLAYER2:
- st_DrawBitmap(objnr, st_bitmap_player2,7,8);
- break;
- case ST_DRAW_PLAYER3:
- st_DrawBitmap(objnr, st_bitmap_player3,7,11);
- break;
- case ST_DRAW_GADGET:
- /* could use this proc, but... */
- /* st_DrawBitmap(objnr, st_bitmap_gadget,o->x1-o->x0+1, 5); */
- /* ... this one looks also funny. */
- st_DrawBitmap(objnr, st_bitmap_gadget,5,5);
- break;
- case ST_DRAW_BACKSLASH:
- {
- uint8_t x;
- uint8_t y;
- x = st_CalcXY(o);
- y = st_px_y;
-
-
- // dog_SetPixel(x,y);
- // x++; y--;
- // dog_SetPixel(x,y);
- // x++; y--;
- // dog_SetPixel(x,y);
-
- u8g2_SetDrawColor(st_u8g2, 1);
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- x++; y--;
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- x++; y--;
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- }
- break;
- case ST_DRAW_SLASH:
- {
- uint8_t x;
- uint8_t y;
- x = st_CalcXY(o);
- y = st_px_y;
-
- // dog_SetPixel(x,y);
- // x++; y++;
- // dog_SetPixel(x,y);
- // x++; y++;
- // dog_SetPixel(x,y);
-
- u8g2_SetDrawColor(st_u8g2, 1);
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- x++; y++;
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- x++; y++;
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- }
- break;
- }
-}
-
-uint8_t st_IsHitBBOX(uint8_t objnr, uint8_t x, uint8_t y)
-{
- st_CalcBBOX(objnr);
- if ( st_ClipBBOX() == 0 )
- return 0; /* obj is outside (not visible) */
- if ( x < st_cbbox_x0 )
- return 0;
- if ( x > st_cbbox_x1 )
- return 0;
- if ( y < st_cbbox_y0 )
- return 0;
- if ( y > st_cbbox_y1 )
- return 0;
- return 1;
-}
-
-void st_Destroy(uint8_t objnr)
-{
- int8_t nr;
- st_obj *o = st_GetObj(objnr);
- switch(u8x8_pgm_read(&(st_object_types[o->ot].destroy_fn)))
- {
- case ST_DESTROY_NONE: /* only usefull for missels or walls which stay alife */
- break;
- case ST_DESTROY_DISAPPEAR: /* this should be the default operation */
- st_Disappear(objnr);
- break;
- case ST_DESTROY_GADGET:
- nr = st_FindObj(ST_OT_PLAYER2);
- if ( nr >= 0 )
- st_SetupPlayer(nr, ST_OT_PLAYER3);
- else
- {
- nr = st_FindObj(ST_OT_PLAYER);
- if ( nr >= 0 )
- st_SetupPlayer(nr, ST_OT_PLAYER2);
- }
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_PY);
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_NY);
- o->ot = ST_OT_GADGET_IMPLODE;
- o->tmp = 0;
- break;
- case ST_DESTROY_TO_DUST:
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_PY);
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_NY);
- o->ot = ST_OT_TRASH_IMPLODE;
- o->tmp = 0;
- break;
- case ST_DESTROY_BIG_TRASH:
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_PY);
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_NY);
- st_InitTrash((o->x>>ST_FP)-1, (o->y>>ST_FP)+3, 2+(st_rnd()&3));
- st_InitTrash((o->x>>ST_FP)-2, (o->y>>ST_FP)-3, -2-(st_rnd()&3));
- st_Disappear(objnr);
- break;
- case ST_DESTROY_PLAYER:
- st_Disappear(objnr);
- st_state = ST_STATE_END;
- o->tmp = 0;
- break;
- case ST_DESTROY_PLAYER_GADGETS:
- /* o->ot = ST_OT_PLAYER; */
- st_SetupPlayer(objnr, ST_OT_PLAYER);
- break;
- }
-}
-
-/*
- check if the target (objnr) has been hit.
- st_IsHit() must also destroy the target.
- return value:
- 0: do not destroy the missle
- 1: destroy the missle
-*/
-uint8_t st_IsHit(uint8_t objnr, uint8_t x, uint8_t y, uint8_t missle_mask)
-{
- uint8_t hit_mask = st_GetHitMask(objnr);
- st_obj *o;
-
- if ( (hit_mask & missle_mask) == 0 )
- return 0;
-
- o = st_GetObj(objnr);
-
- switch(u8x8_pgm_read(&(st_object_types[o->ot].is_hit_fn)))
- {
- case ST_IS_HIT_NONE:
- break;
- case ST_IS_HIT_BBOX:
- if ( st_IsHitBBOX(objnr, x, y) != 0 )
- {
- st_Destroy(objnr);
- return 1;
- }
- break;
- case ST_IS_HIT_WALL:
- if ( st_IsHitBBOX(objnr, x, y) != 0 )
- {
- o->x0++;
- if ( o->x0 < o->x1 )
- {
- st_NewTrashDust(x, y, ST_OT_DUST_NXPY);
- st_NewTrashDust(x, y, ST_OT_DUST_NXNY);
- }
- else
- {
- st_Destroy(objnr);
- st_NewTrashDust(x, y, ST_OT_DUST_NXPY);
- st_NewTrashDust(x, y, ST_OT_DUST_NXNY);
- st_NewTrashDust(x, y, ST_OT_DUST_NY);
- st_NewTrashDust(x, y, ST_OT_DUST_PY);
- }
- return 1;
- }
- break;
- }
- return 0;
-}
-
-
-
-/* update all fire counters */
-uint8_t st_fire_player = 0;
-uint8_t st_fire_period = 51;
-uint8_t st_manual_fire_delay = 20;
-uint8_t st_is_fire_last_value = 0;
-
-/*
- is_auto_fire == 1
- is_fire will be ignored, autofire enabled
- is_auto_fire == 0
- a transition from 1 to 0 on the is_fire variable will issue a missle
-*/
-void st_FireStep(uint8_t is_auto_fire, uint8_t is_fire)
-{
- if ( is_auto_fire != 0 )
- {
- st_fire_player++;
- if ( st_fire_player >= st_fire_period )
- st_fire_player = 0;
- }
- else
- {
- if ( st_fire_player < st_manual_fire_delay )
- {
- st_fire_player++;
- }
- else
- {
- if ( st_is_fire_last_value == 0 )
- if ( is_fire != 0 )
- st_fire_player = 0;
- }
- st_is_fire_last_value = is_fire;
- }
-}
-
-void st_Fire(uint8_t objnr)
-{
- st_obj *o = st_GetObj(objnr);
- uint8_t x;
- uint8_t y;
-
- switch(u8x8_pgm_read(&(st_object_types[o->ot].fire_fn)))
- {
- case ST_FIRE_NONE:
- break;
- case ST_FIRE_PLAYER1:
- if ( st_fire_player == 0 )
- {
- /* create missle at st_px_x and st_px_y */
- x = st_CalcXY(o);
- y = st_px_y;
- st_NewPlayerMissle(x , y );
- }
- break;
- case ST_FIRE_PLAYER2:
- if ( st_fire_player == 0 )
- {
- /* create missle at st_px_x and st_px_y */
- x = st_CalcXY(o);
- y = st_px_y;
- st_NewPlayerMissle(x , y );
- st_NewPlayerMissle(x , y+4 );
- }
- break;
- case ST_FIRE_PLAYER3:
- if ( st_fire_player == 0 )
- {
- /* create missle at st_px_x and st_px_y */
- x = st_CalcXY(o);
- y = st_px_y;
- st_NewPlayerMissle(x , y );
- st_NewPlayerMissle(x , y+4 );
- st_NewPlayerMissle(x , y-4 );
- }
- break;
- }
-}
-
-/*================================================================*/
-/* object init functions */
-/*================================================================*/
-
-/*
- x,y are pixel coordinats within the play arey
-*/
-void st_NewGadget(uint8_t x, uint8_t y)
-{
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- st_SetXY(o, x, y);
- o->ot = ST_OT_GADGET;
- o->tmp = 8;
- //o->x = (x)<<ST_FP;
- //o->y = (y)<<ST_FP;
- o->x0 = -3;
- o->x1 = 1;
- o->y0 = -2;
- o->y1 = 2;
-}
-
-/*
- x,y are pixel coordinats within the play arey
- dir: direction
- 0: random
- != 0 --> assigned
-*/
-void st_InitTrash(uint8_t x, uint8_t y, int8_t dir)
-{
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- if ( (st_rnd() & 1) == 0 )
- o->ot = ST_OT_TRASH1;
- else
- o->ot = ST_OT_TRASH2;
- if ( dir == 0 )
- {
- o->tmp = 0;
- if ( st_rnd() & 1 )
- {
- if ( st_rnd() & 1 )
- o->tmp++;
- else
- o->tmp--;
- }
- }
- else
- {
- o->tmp = dir;
- }
- st_SetXY(o, x, y);
- //o->x = (x)<<ST_FP;
- //o->y = (y)<<ST_FP;
- o->x0 = -3;
- o->x1 = 1;
- o->y0 = -2;
- o->y1 = 2;
- if ( st_difficulty >= 5 )
- {
- if ( (st_rnd() & 3) == 0 )
- {
- o->ot = ST_OT_BIG_TRASH;
- o->y0--;
- o->y1++;
- o->x0--;
- o->x1++;
- }
- }
-}
-
-/*
- x,y are pixel coordinats within the play arey
-*/
-void st_NewTrashDust(uint8_t x, uint8_t y, int ot)
-{
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- o->ot = ot;
- st_SetXY(o, x, y);
- //o->x = (x)<<ST_FP;
- //o->y = (y)<<ST_FP;
- o->x0 = 0;
- o->x1 = 0;
- o->y0 = -2;
- o->y1 = 2;
-}
-
-void st_NewTrashDustAreaArgs(int16_t x, int16_t y, int ot)
-{
- st_NewTrashDust(x>>ST_FP, y>>ST_FP, ot);
-}
-
-
-void st_NewWall(void)
-{
- st_obj *o;
- int8_t objnr = st_NewObj();
- int8_t h;
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- o->ot = ST_OT_WALL_SOLID;
- h = st_rnd();
- h &= 63;
- h = (int8_t)(((int16_t)h*(int16_t)(ST_AREA_HEIGHT/4))>>6);
- h += ST_AREA_HEIGHT/6;
-
- o->x0 = 0;
- o->x1 = 5;
- o->x = (ST_AREA_WIDTH-1)<<ST_FP;
-
- if ( (st_rnd() & 1) == 0 )
- {
- o->y = (ST_AREA_HEIGHT-1)<<ST_FP;
-
- o->y0 = -h;
- o->y1 = 0;
- }
- else
- {
- o->y = (0)<<ST_FP;
- o->y0 = 0;
- o->y1 = h;
- }
-}
-
-void st_NewPlayerMissle(uint8_t x, uint8_t y)
-{
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- o->ot = ST_OT_MISSLE;
- st_SetXY(o, x, y);
- //o->x = x<<ST_FP;
- //o->y = y<<ST_FP;
- o->x0 = -4;
- o->x1 = 1;
- o->y0 = 0;
- o->y1 = 0;
-}
-
-void st_SetupPlayer(uint8_t objnr, uint8_t ot)
-{
- st_obj *o = st_GetObj(objnr);
- switch(ot)
- {
- case ST_OT_PLAYER:
- o->ot = ot;
- o->y0 = -2;
- o->y1 = 2;
- break;
- case ST_OT_PLAYER2:
- o->ot = ot;
- o->y0 = -2;
- o->y1 = 5;
- break;
- case ST_OT_PLAYER3:
- o->ot = ot;
- o->y0 = -5;
- o->y1 = 5;
- break;
- }
-}
-
-void st_NewPlayer(void)
-{
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- o->x = 6<<ST_FP;
- o->y = (ST_AREA_HEIGHT/2)<<ST_FP;
- o->x0 = -6;
- o->x1 = 0;
- st_SetupPlayer(objnr, ST_OT_PLAYER);
-}
-
-/*================================================================*/
-/* trash creation */
-/*================================================================*/
-
-void st_InitDeltaWall(void)
-{
- uint8_t i;
- uint8_t cnt = 0;
- uint8_t max_x = 0;
- uint8_t max_l;
-
- uint8_t min_dist_for_new = 40;
- uint8_t my_difficulty = st_difficulty;
-
- if ( st_difficulty >= 2 )
- {
-
- max_l = ST_AREA_WIDTH;
- max_l -= min_dist_for_new;
-
- if ( my_difficulty > 30 )
- my_difficulty = 30;
- min_dist_for_new -= my_difficulty;
-
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == ST_OT_WALL_SOLID )
- {
- cnt++;
- if ( max_x < (st_objects[i].x>>ST_FP) )
- max_x = (st_objects[i].x>>ST_FP);
- }
- }
- /* if ( cnt < upper_trash_limit ) */
- if ( max_x < max_l )
- {
- st_NewWall();
- }
- }
-}
-
-
-void st_InitDeltaTrash(void)
-{
- uint8_t i;
- uint8_t cnt = 0;
- uint8_t max_x = 0;
- uint8_t max_l;
-
- uint8_t upper_trash_limit = ST_OBJ_CNT-7;
- uint8_t min_dist_for_new = 20;
- uint8_t my_difficulty = st_difficulty;
-
- if ( my_difficulty > 14 )
- my_difficulty = 14;
- min_dist_for_new -= my_difficulty;
-
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == ST_OT_TRASH1 || st_objects[i].ot == ST_OT_TRASH2 || st_objects[i].ot == ST_OT_GADGET || st_objects[i].ot == ST_OT_BIG_TRASH )
- {
- cnt++;
- if ( max_x < (st_objects[i].x>>ST_FP) )
- max_x = (st_objects[i].x>>ST_FP);
- }
- }
-
- max_l = ST_AREA_WIDTH;
- max_l -= min_dist_for_new;
-
- if ( cnt < upper_trash_limit )
- if ( max_x < max_l )
- {
- if ( (st_difficulty >= 3) && ((st_rnd() & 7) == 0) )
- st_NewGadget(ST_AREA_WIDTH-1, rand() & (ST_AREA_HEIGHT-1));
- else
- st_InitTrash(ST_AREA_WIDTH-1, rand() & (ST_AREA_HEIGHT-1),0 );
- }
-}
-
-void st_InitDelta(void)
-{
- st_InitDeltaTrash();
- st_InitDeltaWall();
- /*
-
- uint8_t cnt;
- cnt = st_CntObj(2);
- if ( cnt == 0 )
- st_InitBrick1();
- */
-}
-
-/*================================================================*/
-/* API: game draw procedure */
-/*================================================================*/
-
-void st_DrawInGame(uint8_t fps)
-{
- uint8_t i;
- /* draw all objects */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- st_DrawObj(i);
-
- //dog_ClrBox(0, ST_AREA_HEIGHT, st_u8g2->width-1, ST_AREA_HEIGHT+3);
-
- u8g2_SetDrawColor(st_u8g2, 0);
- u8g2_DrawBox(st_u8g2, 0, u8g_height_minus_one - ST_AREA_HEIGHT-3, st_u8g2->width, 4);
-
- u8g2_SetDrawColor(st_u8g2, 1);
- u8g2_DrawHLine(st_u8g2, 0, u8g_height_minus_one - ST_AREA_HEIGHT+1, ST_AREA_WIDTH);
- u8g2_DrawHLine(st_u8g2, 0, u8g_height_minus_one, ST_AREA_WIDTH);
- u8g2_SetFont(st_u8g2, u8g_font_4x6r);
- u8g2_DrawStr(st_u8g2, 0, u8g_height_minus_one - ST_AREA_HEIGHT, st_itoa(st_difficulty));
- u8g2_DrawHLine(st_u8g2, 10, u8g_height_minus_one - ST_AREA_HEIGHT-3, (st_to_diff_cnt>>ST_DIFF_FP)+1);
- u8g2_DrawVLine(st_u8g2, 10, u8g_height_minus_one - ST_AREA_HEIGHT-4, 3);
- u8g2_DrawVLine(st_u8g2, 10+ST_DIFF_VIS_LEN, u8g_height_minus_one - ST_AREA_HEIGHT-4, 3);
-
-
- /* player points */
- u8g2_DrawStr(st_u8g2, ST_AREA_WIDTH-5*4-2, u8g_height_minus_one - ST_AREA_HEIGHT, st_itoa(st_player_points_delayed));
-
-
- /* FPS output */
- if ( fps > 0 )
- {
- //i = dog_DrawStr(ST_AREA_WIDTH-5*4-2-7*4, ST_AREA_HEIGHT, font_4x6, "FPS:");
- i = u8g2_DrawStr(st_u8g2, ST_AREA_WIDTH-5*4-2-7*4, u8g_height_minus_one - ST_AREA_HEIGHT, "FPS:");
-
- //dog_DrawStr(ST_AREA_WIDTH-5*4-2-7*4+i, ST_AREA_HEIGHT, font_4x6, st_itoa(fps));
- u8g2_DrawStr(st_u8g2, ST_AREA_WIDTH-5*4-2-7*4+i, u8g_height_minus_one - ST_AREA_HEIGHT, st_itoa(fps));
- }
- /*dog_DrawStr(60+i, ST_AREA_HEIGHT, font_4x6, st_itoa(st_CntObj(0)));*/
-}
-
-void st_Draw(uint8_t fps)
-{
- switch(st_state)
- {
- case ST_STATE_PREPARE:
- case ST_STATE_IPREPARE:
- //dog_DrawStr(0, (st_u8g2->height-6)/2, font_4x6, "SpaceTrash");
- u8g2_SetFont(st_u8g2, u8g_font_4x6r);
- u8g2_SetDrawColor(st_u8g2, 1);
- //dog_DrawStrP(0, (st_u8g2->height-6)/2, font_4x6, DOG_PSTR("SpaceTrash"));
- u8g2_DrawStr(st_u8g2, 0, u8g_height_minus_one - (st_u8g2->height-6)/2, "SpaceTrash");
- //dog_SetHLine(st_u8g2->width-st_to_diff_cnt-10, st_u8g2->width-st_to_diff_cnt, (st_u8g2->height-6)/2-1);
- u8g2_DrawHLine(st_u8g2, st_u8g2->width-st_to_diff_cnt-10, u8g_height_minus_one - (st_u8g2->height-6)/2+1, 11);
- break;
- case ST_STATE_GAME:
- st_DrawInGame(fps);
- break;
- case ST_STATE_END:
- case ST_STATE_IEND:
- u8g2_SetFont(st_u8g2, u8g_font_4x6r);
- u8g2_SetDrawColor(st_u8g2, 1);
- //dog_DrawStr(0, (st_u8g2->height-6)/2, font_4x6, "Game Over");
- //dog_DrawStrP(0, (st_u8g2->height-6)/2, font_4x6, DOG_PSTR("Game Over"));
- u8g2_DrawStr(st_u8g2, 0, u8g_height_minus_one - (st_u8g2->height-6)/2, "Game Over");
- //dog_DrawStr(50, (st_u8g2->height-6)/2, font_4x6, st_itoa(st_player_points));
- u8g2_DrawStr(st_u8g2, 50, u8g_height_minus_one - (st_u8g2->height-6)/2, st_itoa(st_player_points));
- //dog_DrawStr(75, (st_u8g2->height-6)/2, font_4x6, st_itoa(st_highscore));
- u8g2_DrawStr(st_u8g2, 75, u8g_height_minus_one - (st_u8g2->height-6)/2, st_itoa(st_highscore));
- //dog_SetHLine(st_to_diff_cnt, st_to_diff_cnt+10, (st_u8g2->height-6)/2-1);
- u8g2_DrawHLine(st_u8g2, st_to_diff_cnt, u8g_height_minus_one - (st_u8g2->height-6)/2+1, 11);
- break;
- }
-}
-
-void st_SetupInGame(void)
-{
- st_player_points = 0;
- st_player_points_delayed = 0;
- st_difficulty = 1;
- st_to_diff_cnt = 0;
- st_ClrObjs();
- st_NewPlayer();
- /* st_InitBrick1(); */
-}
-
-
-/*================================================================*/
-/* API: game setup */
-/*================================================================*/
-
-void st_Setup(u8g2_t *u8g)
-{
- st_u8g2 = u8g;
- u8g2_SetBitmapMode(u8g, 1);
- u8g_height_minus_one = u8g->height;
- u8g_height_minus_one--;
-}
-
-/*================================================================*/
-/* API: game step execution */
-/*================================================================*/
-
-/*
- player_pos: 0..255
-*/
-void st_StepInGame(uint8_t player_pos, uint8_t is_auto_fire, uint8_t is_fire)
-{
- uint8_t i, j;
- uint8_t missle_mask;
-
- /* rescale player pos */
- //st_player_pos = ((uint16_t)player_pos * (uint16_t)ST_AREA_HEIGHT)/256;
- if ( player_pos < 64 )
- st_player_pos = 0;
- else if ( player_pos >= 192 )
- st_player_pos = ST_AREA_HEIGHT-2-1;
- else
- st_player_pos = ((uint16_t)((player_pos-64)) * (uint16_t)(ST_AREA_HEIGHT-2))/128;
- st_player_pos+=1;
- /* move all objects */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- st_Move(i);
-
- /* check for objects which left the play area */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- if ( st_objects[i].ot != 0 )
- if ( st_IsOut(i) != 0 )
- st_Disappear(i);
-
- /* missle and destruction handling */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- missle_mask = st_GetMissleMask(i);
- if ( missle_mask != 0 ) /* should we apply missle handling? */
- if ( st_CalcXY(st_objects+i) != 0 ) /* yes: calculate pixel reference point (st_px_x, st_px_y) */
- for( j = 0; j < ST_OBJ_CNT; j++ ) /* has any other object been hit? */
- if ( i != j ) /* except missle itself... */
- if ( st_IsHit(j, st_px_x, st_px_y, missle_mask) != 0 ) /* let the member function decide */
- { /* let the member function destroy the object if required */
- st_Destroy(i);
- }
- }
-
- /* handle fire counter */
- st_FireStep(is_auto_fire, is_fire);
-
- /* fire */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- st_Fire(i);
-
- /* create new objects */
- st_InitDelta();
-
- /* increase difficulty */
-
- st_to_diff_cnt++;
- if ( st_to_diff_cnt == (ST_DIFF_VIS_LEN<<ST_DIFF_FP) )
- {
- st_to_diff_cnt = 0;
- st_difficulty++;
- st_player_points += ST_POINTS_PER_LEVEL;
- }
-
- /* update visible player points */
- if ( st_player_points_delayed < st_player_points )
- st_player_points_delayed++;
-}
-
-void st_Step(uint8_t player_pos, uint8_t is_auto_fire, uint8_t is_fire)
-{
- switch(st_state)
- {
- case ST_STATE_PREPARE:
- st_to_diff_cnt = st_u8g2->width-10; /* reuse st_to_diff_cnt */
- st_state = ST_STATE_IPREPARE;
- break;
- case ST_STATE_IPREPARE:
- st_to_diff_cnt--;
- if ( st_to_diff_cnt == 0 )
- {
- st_state = ST_STATE_GAME;
- st_SetupInGame();
- }
- break;
- case ST_STATE_GAME:
- st_StepInGame(player_pos, is_auto_fire, is_fire);
- break;
- case ST_STATE_END:
- st_to_diff_cnt = st_u8g2->width-10; /* reuse st_to_diff_cnt */
- if ( st_highscore < st_player_points)
- st_highscore = st_player_points;
- st_state = ST_STATE_IEND;
- break;
- case ST_STATE_IEND:
- st_to_diff_cnt--;
- if ( st_to_diff_cnt == 0 )
- st_state = ST_STATE_PREPARE;
- break;
- }
-}
-
-
-
-void setup(void) {
- u8g2.begin();
-}
-
-uint8_t a;
-uint8_t b;
-uint8_t y = 128;
-
-void loop(void) {
-
- u8g2.setFont(u8g2_font_6x10_tr);
- u8g2.setFontDirection(0);
- u8g2.setFontRefHeightAll();
-
- st_Setup(u8g2.getU8g2());
- for(;;)
- {
- st_Step(y, /* is_auto_fire */ 0, /* is_fire */ digitalRead(pin_fire));
- u8g2.firstPage();
- do
- {
- st_Draw(0);
- } while( u8g2.nextPage() );
-
- if ( digitalRead(pin_down) ) {
- y++;
- }
-
- if ( digitalRead(pin_up) ) {
- y--;
- }
- }
-}
-
-