// ----------------------------------------
// MORPION GAME ---------------------------
// ----------------------------------------
#include "stdlib.h"
#include "avr/io.h"
#include "avr/pgmspace.h"
// ----------------------------------------
// BITMAPS.CPP ----------------------------
// ----------------------------------------
const uint8_t BMP_CPU_RNDALT[16] PROGMEM = {
0x02, 0x06, 0x08, 0x00, 0x00, 0x08, 0x06, 0x02, 0x06, 0x02, 0x00, 0x08, 0x08, 0x00, 0x02, 0x06
};
const uint8_t BMP_LINE_CHECK[8] PROGMEM = {
0x18, 0x42, 0x81, 0x24, 0xE0, 0x07, 0x29, 0x94
};
const uint8_t BMP_CPU_CHECK_MIDDLE[36] PROGMEM = {
0x81, 0x5A, 0x24, 0x5A, 0x50, 0x80, 0x48, 0x20, 0x0A, 0x01, 0x12, 0x04, 0x41, 0x20, 0x44, 0x80, 0x88, 0x20, 0x0C, 0x01,
0x22, 0x01, 0x82, 0x04, 0x30, 0x80, 0x11, 0x04, 0x80, 0x01, 0x20, 0x04, 0x04, 0x20, 0x01, 0x80
};
const uint8_t BMP_POLICE[42] PROGMEM= {
0x04, 0x01, 0xF8, 0x88, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE8, 0xA8, 0xB8, 0x00, 0x88, 0xA8, 0xF8, 0x00, 0x38, 0x20,
0xF8, 0x00, 0xB8, 0xA8, 0xE8, 0x00, 0xF8, 0xA8, 0xE8, 0x00, 0x08, 0xE8, 0x18, 0x00, 0xF8, 0xA8, 0xF8, 0x00, 0xB8, 0xA8,
0xF8, 0x00
};
const uint8_t BMP_PLATEAU_UP[256] PROGMEM = {
0xFE, 0x01, 0xFC, 0xFE, 0xFE, 0xFE, 0x06, 0xD6, 0xC6, 0xFE, 0x06, 0x7E, 0x7E, 0xF6, 0xEE, 0x1E, 0xE6, 0xFE, 0xFE, 0xFE,
0x76, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFC, 0x01, 0xFE, 0x00, 0x00, 0xFE, 0x01, 0xFC, 0xFE, 0xFE, 0xFE, 0x06, 0x76, 0x76, 0xFE, 0x06, 0xD6, 0xC6, 0xFE, 0x06,
0x7E, 0x06, 0xFE, 0xFE, 0xFE, 0x76, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0x01, 0xFE, 0x03, 0x04, 0x09, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B,
0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B,
0x2B, 0x1B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B,
0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x19, 0x0C, 0x07, 0x00, 0x00, 0x03, 0x04, 0x09, 0x1B, 0x2B, 0x1B, 0x2B,
0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B,
0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x1B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B,
0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x2B, 0x3B, 0x19, 0x0C, 0x07
};
const uint8_t BMP_PLATEAU[768] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE0, 0x60,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xB0, 0x70, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x70, 0xB0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0x78,
0x7C, 0x5E, 0x4F, 0x47, 0x43, 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0x40, 0xE0, 0x5C, 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0x40, 0x43, 0x5C, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41,
0x43, 0x47, 0x4F, 0x5E, 0x7C, 0x78, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0x78,
0x3C, 0x1E, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x38, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1E,
0x3C, 0x78, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0x78,
0x3C, 0x1E, 0x0F, 0x07, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x82, 0x72, 0x0E, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x03, 0x0E, 0x72, 0x82, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xE0,
0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xE0, 0xF0, 0xF8,
0xFC, 0x9E, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1C, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1C, 0xE0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x9E, 0xFC, 0xF8, 0xF0, 0xE0, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3F, 0x42, 0xFC, 0x85, 0xF9, 0xEB, 0xAB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
0xEB, 0xEB, 0xEB, 0xEB, 0xE3, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
0xEB, 0xEB, 0xEB, 0xEB, 0xE3, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xAB,
0xEB, 0xF9, 0x85, 0xFC, 0x42, 0x3F, 0x00, 0x00
};
const uint8_t BMP_UP_POS[3] PROGMEM = {
0x24, 0x38, 0x4B
};
const uint8_t BMP_MIDDLE_POS[3] PROGMEM = {
0x19, 0x34, 0x4E
};
const uint8_t BMP_DOWN_POS[3] PROGMEM = {
0x0B, 0x2F, 0x52
};
const uint8_t BMP_UP[324] PROGMEM = {
0x00, 0xC0, 0xE0, 0x60, 0x30, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0x30, 0x30, 0x00, 0x00, 0x45,
0x4E, 0x4F, 0x5F, 0x5F, 0x5D, 0x59, 0x58, 0x58, 0x58, 0x58, 0x5D, 0x4F, 0x4F, 0x47, 0x47, 0x00, 0x00, 0x30, 0x30, 0x30,
0x30, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x46, 0x4F, 0x4F, 0x4F, 0x5D,
0x59, 0x58, 0x58, 0x58, 0x59, 0x5D, 0x4F, 0x4F, 0x4F, 0x46, 0x00, 0x00, 0x00, 0x30, 0x30, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0,
0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0x30, 0x60, 0xE0, 0xC0, 0x00, 0x00, 0x47, 0x47, 0x4F, 0x4F, 0x5D, 0x58, 0x58, 0x58, 0x58,
0x59, 0x5D, 0x5F, 0x5F, 0x4F, 0x4E, 0x45, 0x00, 0xC0, 0xC0, 0xE0, 0x60, 0x30, 0xB0, 0xB0, 0xB0, 0x30, 0x30, 0x30, 0x30,
0x30, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0x53, 0x59, 0x58, 0x48, 0x4C, 0x4C, 0x45, 0x47, 0x47, 0x47, 0x47, 0x4F, 0x5F, 0x5D,
0x59, 0x59, 0x40, 0x60, 0x70, 0x30, 0xB0, 0xB0, 0xB0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xB0, 0xB0, 0xB0, 0x30,
0x70, 0x00, 0x50, 0x58, 0x58, 0x5D, 0x4D, 0x4F, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4F, 0x4D, 0x5D, 0x58, 0x58, 0x50, 0x00,
0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0x30, 0x30, 0x30, 0x30, 0x30, 0xB0, 0xB0, 0xB0, 0x30, 0x60, 0xE0, 0xC0, 0xC0, 0x60, 0x40,
0x59, 0x59, 0x5D, 0x5F, 0x4F, 0x47, 0x47, 0x47, 0x47, 0x45, 0x4C, 0x4C, 0x48, 0x58, 0x59, 0x53, 0xC0, 0xC0, 0xE0, 0x60,
0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x53, 0x49, 0x54, 0x4A, 0x55, 0x4A,
0x55, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x45, 0x60, 0x70, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30,
0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0x70, 0x00, 0x48, 0x55, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55,
0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55, 0x48, 0x00, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30, 0xB0, 0x30,
0xB0, 0x30, 0x60, 0xE0, 0xC0, 0xC0, 0x60, 0x45, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55, 0x4A, 0x55,
0x4A, 0x54, 0x49, 0x53
};
const uint8_t BMP_MIDDLE[234] PROGMEM = {
0x00, 0x00, 0x00, 0x13, 0x3D, 0x7C, 0x7C, 0x7E, 0xFE, 0xE6, 0xE7, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0x63, 0x77, 0x7F,
0x7E, 0x3E, 0x3E, 0x1C, 0x08, 0x00, 0x00, 0x38, 0x3C, 0x7C, 0x7E, 0x7E, 0xFE, 0xE6, 0xE7, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3,
0xC3, 0xE3, 0xE7, 0xE6, 0xFE, 0x7E, 0x7E, 0x7C, 0x3C, 0x38, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x3E, 0x3E, 0x7E, 0x7F, 0x77,
0x63, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE7, 0xE6, 0xFE, 0x7E, 0x7C, 0x7C, 0x3D, 0x13, 0x00, 0x00, 0x00, 0x9E, 0xCF,
0xC7, 0xE3, 0x61, 0x60, 0x71, 0x33, 0x33, 0x37, 0x3F, 0x1E, 0x1E, 0x1E, 0x3C, 0x3C, 0x7E, 0x7E, 0xF6, 0xF6, 0xE3, 0xE3,
0xE3, 0xC3, 0x01, 0xC1, 0x87, 0xC0, 0xC0, 0xE1, 0xE3, 0xE3, 0x73, 0x77, 0x36, 0x3E, 0x3E, 0x1C, 0x1C, 0x1C, 0x3E, 0x3E,
0x36, 0x77, 0x73, 0xE3, 0xE3, 0xE1, 0xC0, 0xC0, 0x87, 0x00, 0xC1, 0x01, 0xC3, 0xE3, 0xE3, 0xE3, 0xF6, 0xF6, 0x7E, 0x7E,
0x3C, 0x3C, 0x1E, 0x1E, 0x1E, 0x3F, 0x37, 0x33, 0x33, 0x71, 0x60, 0x61, 0xE3, 0xC7, 0xCF, 0x9E, 0x9E, 0x4F, 0xA7, 0x53,
0xA9, 0x54, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
0x0A, 0xC1, 0x87, 0x50, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x50, 0x87, 0x00, 0xC1, 0x0A, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x54, 0xA9, 0x53, 0xA7, 0x4F, 0x9E
};
const uint8_t BMP_DOWN[648] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x78, 0x3C, 0x9E, 0xCE, 0xC6, 0xE2, 0xE2, 0xE2, 0xF2, 0x72, 0x72, 0x72, 0x3A, 0x3A, 0x3A, 0x3A,
0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x7A, 0xFA, 0xF2, 0xF2, 0xF2, 0xE2, 0xE2, 0xC2, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x0F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x7F, 0x7C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x38, 0x38, 0x3C,
0x3C, 0x3C, 0x3E, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x61, 0x00, 0x00, 0x00, 0x8E, 0xC2, 0xE2, 0xE2, 0xF2, 0xF2,
0xF2, 0xFA, 0x7A, 0x7A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x7A, 0x7A, 0xFA, 0xF2, 0xF2,
0xF2, 0xE2, 0xE2, 0xC2, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x7E, 0x7C,
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x7C, 0x7E, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F, 0x0F, 0x07,
0x07, 0x00, 0x00, 0x00, 0x00, 0x82, 0xC2, 0xE2, 0xE2, 0xF2, 0xF2, 0xF2, 0xFA, 0x7A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A,
0x3A, 0x3A, 0x3A, 0x3A, 0x72, 0x72, 0x72, 0xF2, 0xE2, 0xE2, 0xE2, 0xC6, 0xCE, 0x9E, 0x3C, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x61, 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x1F, 0x1F, 0x3E, 0x3C, 0x3C, 0x3C, 0x38, 0x38, 0x78, 0x78, 0x78, 0x78, 0x78,
0x78, 0x78, 0x7C, 0x7F, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 0x0F, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0,
0x78, 0x3C, 0x1E, 0x0E, 0x06, 0x1A, 0x3A, 0x3A, 0x7A, 0x7A, 0xFA, 0xF2, 0xF2, 0xE2, 0xE2, 0xE2, 0xC2, 0xC2, 0xC2, 0xE2,
0xE2, 0xE2, 0xE2, 0x72, 0x72, 0x72, 0x3A, 0x3A, 0x3A, 0x1A, 0x1A, 0x1A, 0x47, 0x63, 0x71, 0x70, 0x78, 0x78, 0x38, 0x3C,
0x3C, 0x1C, 0x1C, 0x1E, 0x0E, 0x0E, 0x0F, 0x07, 0x07, 0x07, 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x1F, 0x1F, 0x3E, 0x3E, 0x7E,
0x7C, 0x7C, 0x78, 0x78, 0x70, 0x00, 0xE0, 0x1C, 0x00, 0x00, 0x0E, 0x02, 0x02, 0x1A, 0x1A, 0x3A, 0x3A, 0x3A, 0x7A, 0x72,
0xF2, 0xF2, 0xE2, 0xE2, 0xE2, 0xC2, 0xE2, 0xE2, 0xE2, 0xF2, 0xF2, 0x72, 0x7A, 0x3A, 0x3A, 0x3A, 0x1A, 0x1A, 0x02, 0x02,
0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x78, 0x78, 0x7C, 0x3C, 0x3C, 0x3E, 0x1E, 0x1E, 0x0F, 0x0F, 0x07, 0x07,
0x07, 0x03, 0x07, 0x07, 0x07, 0x0F, 0x0F, 0x1E, 0x1E, 0x3E, 0x3C, 0x3C, 0x7C, 0x78, 0x78, 0x70, 0x70, 0x00, 0x00, 0x00,
0x1A, 0x1A, 0x1A, 0x3A, 0x3A, 0x3A, 0x72, 0x72, 0x72, 0xE2, 0xE2, 0xE2, 0xE2, 0xC2, 0xC2, 0xC2, 0xE2, 0xE2, 0xE2, 0xF2,
0xF2, 0xFA, 0x7A, 0x7A, 0x3A, 0x3A, 0x1A, 0x06, 0x0E, 0x1E, 0x3C, 0x78, 0xF0, 0xE0, 0xC0, 0x80, 0x1C, 0xE0, 0x00, 0x70,
0x78, 0x78, 0x7C, 0x7C, 0x7E, 0x3E, 0x3E, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x07, 0x07, 0x07, 0x0F, 0x0E, 0x0E,
0x1E, 0x1C, 0x1C, 0x3C, 0x3C, 0x38, 0x78, 0x78, 0x70, 0x71, 0x63, 0x47, 0x80, 0xC0, 0xE0, 0xF0, 0x78, 0x3C, 0x9E, 0x4E,
0xA6, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52,
0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x12, 0x27, 0x53, 0x29, 0x54, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55,
0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55,
0x2A, 0x05, 0x60, 0x1C, 0x00, 0x72, 0x0E, 0x42, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52,
0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x42, 0x0E, 0x72, 0x00, 0x00,
0x00, 0x50, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55,
0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x50, 0x00, 0x00, 0x12, 0xAA, 0x52, 0xAA,
0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA, 0x52, 0xAA,
0x52, 0xAA, 0x52, 0xA6, 0x4E, 0x9E, 0x3C, 0x78, 0xF0, 0xE0, 0xC0, 0x80, 0x1C, 0x60, 0x05, 0x2A, 0x55, 0x2A, 0x55, 0x2A,
0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A,
0x55, 0x2A, 0x55, 0x2A, 0x54, 0x29, 0x53, 0x27
};
const uint8_t BMP_MENU[62] PROGMEM = {
0x14, 0x03, 0x00, 0x9F, 0x15, 0x91, 0x00, 0x9F, 0x85, 0x9F, 0x00, 0x97, 0x95, 0x9D, 0x00, 0x93, 0x94, 0x0F, 0x00, 0x00,
0x00, 0x00, 0x40, 0xCF, 0x42, 0xCF, 0x00, 0xCF, 0x42, 0xCF, 0x00, 0xCF, 0x46, 0xCB, 0x00, 0xCF, 0x08, 0xC7, 0x00, 0xC0,
0x40, 0x40, 0x04, 0x07, 0x05, 0x07, 0x00, 0x07, 0x03, 0x05, 0x00, 0x07, 0x01, 0x07, 0x00, 0x03, 0x04, 0x03, 0x00, 0x07,
0x05, 0x04
};
const uint8_t BMP_CURSEUR[52] PROGMEM = {
0x19, 0x02, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFE, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
};
const uint8_t BMP_INTRO[207] PROGMEM = {
0x29, 0x05, 0xFE, 0x03, 0x01, 0x01, 0x01, 0x01, 0x11, 0x21, 0x41, 0x81, 0x41, 0x21, 0x11, 0x01, 0xF1, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xF1, 0x01, 0x11, 0x21, 0x41, 0x81, 0x41, 0x21, 0x11, 0x01, 0x01, 0x01,
0x03, 0xFE, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x12, 0x11, 0x10, 0x11, 0x12, 0x14, 0x10, 0xFF, 0x10, 0x10,
0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x10, 0x10, 0xFF, 0x10, 0x14, 0x12, 0x11, 0x10, 0x11, 0x12, 0x14, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x20, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x20, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x40, 0x40, 0xE1, 0x51, 0x49, 0x49, 0x49, 0x51, 0xE1, 0x41, 0xFF,
0x41, 0x41, 0xE1, 0x51, 0x49, 0x49, 0x49, 0x51, 0xE1, 0x41, 0x41, 0xFF, 0x41, 0xE1, 0x51, 0x49, 0x49, 0x49, 0x51, 0xE1,
0x40, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x32, 0x32, 0x32, 0x31, 0x30, 0x30,
0x31, 0x30, 0x30, 0x30, 0x31, 0x32, 0x32, 0x32, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x31, 0x32, 0x32, 0x32, 0x31,
0x30, 0x30, 0x30, 0x30, 0x38, 0x2F, 0x1F
};
// ----------------------------------------
// DISPLAY.CPP ----------------------------
// ----------------------------------------
#define DISPLAY_SCL PB2
#define DISPLAY_SDA PB0
#define DISPLAY_ADRESS 0x78
// ----------------------------------------
#define DIGITAL_WRITE_HIGH(PORT) PORTB |= (1 << PORT)
#define DIGITAL_WRITE_LOW(PORT) PORTB &= ~(1 << PORT)
// ----------------------------------------
const uint8_t DISPLAY_INIT_SEQUENCE[28] PROGMEM = {
0xAE, 0x20, 0b00, 0xB0, 0xC8, 0x00, 0x10, 0x40, 0x81, 0x3F, 0xA1, 0xA6, 0xA8, 0x3F, 0xA4, 0xD3, 0x00, 0xD5, 0xF0, 0xD9,
0x22, 0xDA, 0x12, 0xDB, 0x20, 0x8D, 0x14, 0xAF
};
// ----------------------------------------
void DisplayInit() {
DDRB |= (1 << DISPLAY_SDA);
DDRB |= (1 << DISPLAY_SCL);
for (uint8_t i = 0; i < sizeof(DISPLAY_INIT_SEQUENCE); i++) DisplaySendCommand(pgm_read_byte(&DISPLAY_INIT_SEQUENCE[i]));
};
void DisplaySendByte(uint8_t byte) {
for (uint8_t i = 0; i < 8; i++) {
if ((byte << i) & 0x80) DIGITAL_WRITE_HIGH(DISPLAY_SDA);
else DIGITAL_WRITE_LOW(DISPLAY_SDA);
DIGITAL_WRITE_HIGH(DISPLAY_SCL);
DIGITAL_WRITE_LOW(DISPLAY_SCL);
};
DIGITAL_WRITE_HIGH(DISPLAY_SDA);
DIGITAL_WRITE_HIGH(DISPLAY_SCL);
DIGITAL_WRITE_LOW(DISPLAY_SCL);
};
void DisplaySendCommand(uint8_t command) {
DIGITAL_WRITE_HIGH( DISPLAY_SCL);
DIGITAL_WRITE_HIGH( DISPLAY_SDA);
DIGITAL_WRITE_LOW( DISPLAY_SDA);
DIGITAL_WRITE_LOW( DISPLAY_SCL);
DisplaySendByte(DISPLAY_ADRESS);
DisplaySendByte(0x00);
DisplaySendByte(command);
DIGITAL_WRITE_LOW( DISPLAY_SCL);
DIGITAL_WRITE_LOW( DISPLAY_SDA);
DIGITAL_WRITE_HIGH( DISPLAY_SCL);
DIGITAL_WRITE_HIGH( DISPLAY_SDA);
};
void DisplayStart(uint8_t y) {
DisplaySendCommand(0xb0 + y);
DisplaySendCommand(0x00);
DisplaySendCommand(0x10);
DIGITAL_WRITE_HIGH(DISPLAY_SCL);
DIGITAL_WRITE_HIGH(DISPLAY_SDA);
DIGITAL_WRITE_LOW(DISPLAY_SDA);
DIGITAL_WRITE_LOW(DISPLAY_SCL);
DisplaySendByte(DISPLAY_ADRESS);
DisplaySendByte(0x40);
};
void DisplayStop() {
DIGITAL_WRITE_LOW(DISPLAY_SCL);
DIGITAL_WRITE_LOW(DISPLAY_SDA);
DIGITAL_WRITE_HIGH(DISPLAY_SCL);
DIGITAL_WRITE_HIGH(DISPLAY_SDA);
};
// ----------------------------------------
// JOYPAD.CPP -----------------------------
// ----------------------------------------
#define JOYPAD_LEFT (analogRead(PB5) >= 750) && (analogRead(PB5) < 950)
#define JOYPAD_RIGHT (analogRead(PB5) > 500) && (analogRead(PB5) < 750)
#define JOYPAD_DOWN (analogRead(PB3) >= 750) && (analogRead(PB3) < 950)
#define JOYPAD_UP (analogRead(PB3) > 500) && (analogRead(PB3) < 750)
#define BUTTON_DOWN (digitalRead(PB1) == 0)
#define BUTTON_UP (digitalRead(PB1) == 1)
// ----------------------------------------
#define DEBOUNCE(ZELTADA) _delay_ms(30); if (ZELTADA)
// ----------------------------------------
uint8_t BlitzSprite(int8_t xPos, int8_t yPos, uint8_t xPass, uint8_t yPass, uint8_t frame, const uint8_t *sprites) {
uint8_t outByte1;
uint8_t wSprite = (pgm_read_byte(&sprites[0]));
uint8_t hSprite = (pgm_read_byte(&sprites[1]));
uint16_t wMax = ((hSprite * wSprite) + 1);
uint16_t picByte = frame * (wMax - 1);
int8_t recupeLineY = RecupeLineY(yPos);
if ((xPass > ((xPos + (wSprite - 1)))) || (xPass < xPos) || ((recupeLineY > yPass) || ((recupeLineY + (hSprite)) < yPass))) return 0x00;
int8_t spriteYLine = (yPass - (recupeLineY));
uint8_t spriteYDecalage = (RecupeDecalageY(yPos));
uint16_t scanA = (((xPass - xPos) + (spriteYLine * wSprite)) + 2);
uint16_t scanB = (((xPass - xPos) + ((spriteYLine - 1) * wSprite)) + 2);
if (scanA > wMax) outByte1 = 0x00;
else outByte1 = SplitSpriteDecalageY(spriteYDecalage, pgm_read_byte(&sprites[scanA + (picByte)]), 1);
if (spriteYLine > 0) {
uint8_t outByte2 = SplitSpriteDecalageY(spriteYDecalage, pgm_read_byte(&sprites[scanB + (picByte)]), 0);
if (scanB > wMax) return outByte1;
else return outByte1 | outByte2;
} else return outByte1;
};
uint8_t SpeedBlitz(int8_t xPos, int8_t yPos, uint8_t xPass, uint8_t yPass, uint8_t frame, const uint8_t *sprites) {
uint8_t wSprite = (pgm_read_byte(&sprites[0]));
uint8_t hSprite = (pgm_read_byte(&sprites[1]));
if ((xPass > ((xPos + (wSprite - 1)))) || (xPass < xPos) || ((yPass < yPos) || (yPass > (yPos + (hSprite - 1))))) return 0x00;
return pgm_read_byte(&sprites[2 + (((xPass - xPos) + ((yPass - yPos) * (wSprite))) + (frame * (hSprite * wSprite)))]);
};
uint8_t SplitSpriteDecalageY(uint8_t decalage, uint8_t input, uint8_t UpOrDown) {
if (UpOrDown) return input << decalage;
return input >> (8 - decalage);
};
int8_t RecupeLineY(int8_t valeur) {
return (valeur >> 3);
};
uint8_t RecupeDecalageY(uint8_t valeur) {
return (valeur - ((valeur >> 3) << 3));
};
uint8_t MyMap(uint8_t x, uint8_t inMin, uint8_t inMax, uint8_t outMin, uint8_t outMax) {
return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
};
uint8_t TraceLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t xPass, uint8_t yPass) {
uint8_t y_1 = RecupeLineY(y1);
uint8_t y_2 = RecupeLineY(y2);
if ((xPass < x1) && (xPass < x2)) return 0;
if ((xPass > x1) && (xPass > x2)) return 0;
if (y_1 < y_2) {
if (yPass < y_1) return 0;
if (yPass > y_2) return 0;
} else {
if (yPass > y_1) return 0;
if (yPass < y_2) return 0;
};
return DirectionLine(0, x1, y1, x2, y2, xPass, yPass);
};
uint8_t DirectionLine(uint8_t desactive, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t xPass, uint8_t yPass) {
uint8_t xL = 0;
uint8_t yL = 0;
uint8_t resultant = 0;
uint8_t yRef = 0;
xL = abs(x1 - x2);
yL = abs(y1 - y2);
resultant = MyMap(xPass, x1, x2, y1, y2);
yRef = RecupeLineY(resultant);
if ((xL < yL) && (desactive == 0)) return ReturnFullByte(x1, y1, x2, y2, xPass, yPass);
else {
if (yRef == yPass) return (1 << (RecupeDecalageY(resultant)));
else return 0;
};
};
uint8_t ReturnFullByte(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t xPass, uint8_t yPass) {
uint8_t byteAdd = 0;
uint8_t t = 0;
uint8_t tout = 0;
uint8_t a = 0;
uint8_t b = 0;
a = (yPass << 3);
b = (a + 7);
if (y1 > y2) {
UniversalSwap(&y1, & y2);
UniversalSwap(&x1, & x2);
};
a = (a < y1) ? y1 : a;
b = (b > y2) ? y2 : b;
for (t = a; t < (b + 1); t++) {
if (yPass == RecupeLineY(t)) {
tout = MyMap(t, y1, y2, x1, x2);
byteAdd |= (tout == xPass) ? (0b00000001 << (RecupeDecalageY(t))) : 0x00;
};
};
return byteAdd;
};
void UniversalSwap(uint8_t *a, uint8_t *b) {
uint8_t t = *a;
*a = *b;
*b = t;
};
uint8_t ReconstructByte(uint8_t min, uint8_t max) {
uint8_t a = (0xff << min);
uint8_t b = 0xff - (0xff << max);
return (a & b);
};
void Sound(uint8_t frequency, uint8_t duration) {
for (uint8_t t = 0; t < duration; t++) {
if (frequency != 0) PORTB = PORTB | 0b00010000;
for (uint8_t t = 0; t < (255 - frequency); t++) _delay_us(1);
PORTB = PORTB & 0b11101111;
for (uint8_t t = 0; t < (255 - frequency); t++) _delay_us(1);
};
};
void JoyPadInit() {
//pinMode(PB5, INPUT);
//pinMode(PB3, INPUT);
pinMode(PB4, OUTPUT);
pinMode(PB1, INPUT);
};
// ----------------------------------------
// MAIN.CPP -------------------------------
// ----------------------------------------
uint8_t DivideBy2 = 0;
uint8_t Board[3][3];
uint8_t Players[2];
uint8_t MyTurn;
uint8_t PosXY[2];
uint8_t WinPly;
uint8_t WinCpu;
uint8_t EndGame;
uint8_t Select = 1;
// ----------------------------------------
void InitMData() {
MyTurn = 1;
EndGame = 0;
WinPly = 0;
WinCpu = 0;
PosXY[0] = 1;
PosXY[1] = 1;
for (uint8_t y = 0; y < 3; y++) {
for (uint8_t x = 0; x < 3; x++) Board[y][x] = 2;
};
};
void AssignerXMain(uint8_t Cpu0Ply1) {
Players[0] = (Cpu0Ply1 == 0) ? 1 : 0;
Players[1] = (Cpu0Ply1 == 0) ? 0 : 1;
MyTurn = (Cpu0Ply1 == 0) ? 0 : 1;
};
void SoundBox(uint8_t sound) {
uint8_t t;
switch (sound) {
case 1:
for (t = 0; t < 100; t += 10) Sound(t, 4);
_delay_ms(50);
break;
case 0:
for (t = 100; t < 200; t += 10) Sound(t, 3);
_delay_ms(50);
break;
case 2:
CompletedProcedure();
break;
case 3:
NullGame();
break;
case 4:
for (t = 1; t < 20; t++) {
Sound(4, 80);
Sound(100, 80);
};
break;
case 5:
for (t = 200; t > 10; t--) {
Sound(200 - t, 3);
Sound(t, 12);
};
break;
case 6:
Sound(100, 250);
Sound(20, 250);
break;
default:
break;
};
};
void CpuPlay() {
if (CpuTermination(Players[0])) goto GO_OUT;
if (Select > 0) {
if (CpuTermination(Players[1])) goto GO_OUT;
if (Board[1][1] == 2) {
Board[1][1] = Players[0];
goto GO_OUT;
};
if (CpuMiddle()) goto GO_OUT;
};
if (Select > 1) {
if (CpuCorner()) goto GO_OUT;
if (CpuCorner()) goto GO_OUT;
if (CpuReplicate()) goto GO_OUT;
};
CpuRnd();
GO_OUT:;
};
uint8_t CpuReplicate() {
uint8_t *p = &Board[0][0];
uint8_t t = rand() % 4;
#define RE(ZET) pgm_read_byte(&BMP_CPU_RNDALT[(t * 4) + ZET])
if (p[RE(0)] == 2) {
p[RE(0)] = Players[0];
return 1;
};
if (p[RE(1)] == 2) {
p[RE(1)] = Players[0];
return 1;
};
if (p[RE(2)] == 2) {
p[RE(2)] = Players[0];
return 1;
};
if (p[RE(3)] == 2) {
p[RE(3)] = Players[0];
return 1;
};
return 0;
};
uint8_t CpuDouble() {
uint8_t byteComp = CompactMap(2);
uint8_t *p = &Board[0][0];
if (byteComp == 0xff) {
switch (rand() % 4) {
case 0:
p[2] = Players[0];
return 1;
break;
case 1:
p[6] = Players[0];
return 1;
break;
case 2:
p[8] = Players[0];
return 1;
break;
case 3:
p[0] = Players[0];
return 1;
break;
default:
break;
};
};
return 0;
};
uint8_t CpuCorner() {
uint8_t byteComp = CompactMap(Players[1]);
uint8_t byteTmp1 = 0;
uint8_t byteTmp2 = 0;
uint8_t t1, t2;
uint8_t *p = &Board[0][0];
for (t1 = 2; t1 < 18; t1++) {
byteTmp1 = pgm_read_byte(&BMP_CPU_CHECK_MIDDLE[t1 * 2]);
if ((byteTmp1 & byteComp) == (byteTmp1)) {
byteTmp2 = pgm_read_byte(&BMP_CPU_CHECK_MIDDLE[(t1 * 2) + 1]);
for (t2 = 0; t2 < 8; t2++) {
if ((byteTmp2 & (1 << t2)) != 0) {
if (p[RecupePosGrid(t2)] == 2) {
p[RecupePosGrid(t2)] = Players[0];
return 1;
};
};
};
};
};
return 0;
};
uint8_t CompactMap(uint8_t player) {
uint8_t t;
uint8_t byteComp = 0;
uint8_t *p = &Board[0][0];
for (t = 0; t < 4; t++) {
if (p[t] == player) byteComp |= (0b00000001 << t);
};
for (t = 5; t < 9; t++) {
if (p[t] == player) byteComp |= (0b00000001 << (t - 1));
};
return byteComp;
};
uint8_t CpuMiddle() {
uint8_t t1, t2;
if (Board[1][1] == Players[0]) {
uint8_t byteComp = 0;
uint8_t byteTmp1 = 0;
uint8_t byteTmp2 = 0;
uint8_t *p = &Board[0][0];
byteComp = CompactMap(Players[1]);
for (t1 = 0; t1 < 2; t1++) {
byteTmp1 = pgm_read_byte(&BMP_CPU_CHECK_MIDDLE[t1 * 2]);
if ((byteTmp1 & byteComp) == (byteTmp1)) {
byteTmp2 = pgm_read_byte(&BMP_CPU_CHECK_MIDDLE[(t1 * 2) + 1]);
for (t2 = 0; t2 < 8; t2++) {
if ((byteTmp2 & (1 << t2)) != 0) {
if (p[RecupePosGrid(t2)] == 2) {
p[RecupePosGrid(t2)] = Players[0];
return 1;
};
};
};
};
};
};
return 0;
};
void CheckWin(uint8_t ox) {
uint8_t x;
uint8_t byteComp = 0;
uint8_t byteTmp = 0;
uint8_t *p = &Board[0][0];
uint8_t counter = 0;
byteComp = CompactMap(ox);
for (x = 0; x < 8; x++) {
byteTmp = byteComp & pgm_read_byte(&BMP_LINE_CHECK[x]);
if (byteTmp == pgm_read_byte(&BMP_LINE_CHECK[x])) {
switch (x) {
case 0 ... 3:
if (p[4] == ox) {
if (CompletedProcedure()) goto GO_OUT;
};
break;
default:
if (CompletedProcedure()) goto GO_OUT;
break;
};
};
};
for (x = 0; x < 9; x++) {
if (p[x] == 2) counter = 1;
};
if (counter == 0) NullGame();
GO_OUT:;
};
void NullGame() {
uint8_t *p = &Board[0][0];
uint8_t s;
for (s = 0; s < 30; s++) {
Sound(10, 4);
_delay_ms(4);
Sound(100, 4);
};
for (uint8_t t = 0; t < 9; t++) p[t] = 2;
MyTurn = 0;
RefreshScreen();
};
void BlinkWinner() {
uint8_t *p = &Board[0][0];
uint8_t t, s;
uint8_t pMem[9];
for (t = 0; t < 9; t++) pMem[t] = p[t];
for (s = 0; s < 10; s++) {
Sound(140, 10);
Sound(220, 4);
for (t = 0; t < 9; t++) {
if (p[t] == Players[MyTurn]) p[t] = 2;
};
RefreshScreen();
for (t = 0; t < 9; t++) p[t] = pMem[t];
Sound(10, 4);
RefreshScreen();
};
};
uint8_t CompletedProcedure() {
BlinkWinner();
uint8_t TmpOut = 0;
uint8_t *p = &Board[0][0];
for (uint8_t t = 0; t < 9; t++) p[t] = 2;
switch (MyTurn) {
case 0:
if (WinCpu < 9) WinCpu++;
else {
SoundBox(5);
EndGame = 1;
TmpOut = 1;
};
break;
case 1:
if (WinPly < 9) WinPly++;
else {
SoundBox(4);
EndGame = 2;
TmpOut = 1;
};
break;
default:
break;
};
MyTurn = 0;
RefreshScreen();
return TmpOut;
};
uint8_t RecupePosGrid(uint8_t pos) {
switch (pos) {
case 0 ... 3:
return pos;
break;
case 4 ... 7:
return (pos + 1);
break;
default:
return 0;
break;
};
};
uint8_t CpuTermination(uint8_t plys) {
uint8_t x;
uint8_t t;
uint8_t counter;
uint8_t byteComp = 0;
uint8_t byteTmp1 = 0;
uint8_t byteTmp2 = 0;
uint8_t *p = &Board[0][0];
byteComp = CompactMap(plys);
for (x = 4; x < 8; x++) {
byteTmp2 = pgm_read_byte(&BMP_LINE_CHECK[x]);
byteTmp1 = byteComp & byteTmp2;
counter = 0;
for (t = 0; t < 8; t++) {
if ((byteTmp1 & (1 << t)) != 0) counter++;
};
if (counter != 2) goto GO_NEXT1;
for (t = 0; t < 8; t++) {
if ((byteTmp2 & (1 << t)) != (byteTmp1 & (1 << t))) {
if (p[RecupePosGrid(t)] == 2) {
p[RecupePosGrid(t)] = Players[0];
return 1;
};
};
};
GO_NEXT1:;
};
for (x = 0; x < 4; x++) {
byteTmp2 = pgm_read_byte(&BMP_LINE_CHECK[x]);
byteTmp1 = byteComp & byteTmp2;
counter = 0;
for (t = 0; t < 8; t++) {
if ((byteTmp1 & (1 << t)) != 0) counter++;
};
switch (counter) {
case 1:
if (p[4] == plys) goto PUT_CORNER;
break;
case 2:
if (p[4] == 2) {
p[4] = Players[0];
return 1;
};
break;
default:
goto GO_NEXT2;
break;
};
goto GO_NEXT2;
PUT_CORNER:;
for (t = 0; t < 8; t++) {
if ((byteTmp2 & (1 << t)) != (byteTmp1 & (1 << t))) {
if (p[RecupePosGrid(t)] == 2) {
p[RecupePosGrid(t)] = Players[0];
return 1;
};
};
};
GO_NEXT2:;
};
return 0;
};
void CpuRnd() {
uint8_t x, y;
while (true) {
x = rand() % 3;
y = rand() % 3;
if (Board[y][x] == 2) {
Board[y][x] = Players[0];
break;
};
};
};
void RefreshScreen() {
Flip(1, 0, 8);
};
uint8_t RecupeUpXBoard(uint8_t xPass) {
switch (xPass) {
case 36 ... 53:
return 0;
break;
case 56 ... 73:
return 1;
break;
case 75 ... 92:
return 2;
break;
default:
return 4;
break;
};
};
uint8_t RecupeMiddleXBoard(uint8_t xPass) {
switch (xPass) {
case 25 ... 50:
return 0;
break;
case 52 ... 77:
return 1;
break;
case 78 ... 103:
return 2;
break;
default:
return 4;
break;
};
};
uint8_t RecupeDownXBoard(uint8_t xPass) {
switch (xPass) {
case 11 ... 46:
return 0;
break;
case 47 ... 81:
return 1;
break;
case 82 ... 117:
return 2;
break;
default:
return 4;
break;
};
};
uint8_t RecupeUp(uint8_t xPass, uint8_t yPass) {
uint8_t caseX = RecupeUpXBoard(xPass);
if (caseX == 4) return 0;
uint8_t sprite = Board[0][caseX];
if ((caseX == PosXY[0]) && (PosXY[1] == 0)) sprite = (DivideBy2 == 1) ? 2 : sprite;
else {
if (sprite == 2) return 0;
};
uint8_t tmpX = pgm_read_byte(&BMP_UP_POS[caseX]);
return pgm_read_byte(&BMP_UP[(sprite * 108) + (caseX * 36) + (xPass - tmpX) + ((yPass - 2) * 18)]);
};
uint8_t RecupeMiddle(uint8_t xPass, uint8_t yPass) {
uint8_t caseX = RecupeMiddleXBoard(xPass);
if (caseX == 4) return 0;
uint8_t sprite = Board[1][caseX];
if ((caseX == PosXY[0]) && (PosXY[1] == 1)) sprite = (DivideBy2 == 1) ? 2 : sprite;
else {
if (sprite == 2) return 0;
};
uint8_t tmpX = pgm_read_byte(&BMP_MIDDLE_POS[caseX]);
return pgm_read_byte(&BMP_MIDDLE[(sprite * 78) + (caseX * 26) + (xPass - tmpX) + ((yPass - 4) * 26)]);
};
uint8_t RecupeDown(uint8_t xPass, uint8_t yPass) {
uint8_t caseX = RecupeDownXBoard(xPass);
if (caseX == 4) return 0;
uint8_t sprite = Board[2][caseX];
if ((caseX == PosXY[0]) && (PosXY[1] == 2)) sprite = (DivideBy2 == 1) ? 2 : sprite;
else {
if (sprite == 2) return 0;
};
uint8_t tmpX = pgm_read_byte(&BMP_DOWN_POS[caseX]);
return pgm_read_byte(&BMP_DOWN[(sprite * 216) + (caseX * 72) + (xPass - tmpX) + ((yPass - 5) * 36)]);
};
uint8_t RecupePointer(uint8_t xPass, uint8_t yPass) {
switch (yPass) {
case 2 ... 3:
return RecupeUp(xPass, yPass);
break;
case 4:
return RecupeMiddle(xPass, yPass);
break;
case 5 ... 6:
return RecupeDown(xPass, yPass);
break;
default:
return 0;
break;
};
};
uint8_t Display(uint8_t xPass, uint8_t yPass) {
return SpeedBlitz(25, 0, xPass, yPass, WinPly, BMP_POLICE) | SpeedBlitz(90, 0, xPass, yPass, WinCpu, BMP_POLICE);
};
uint8_t RecupeBack(uint8_t xPass, uint8_t yPass) {
switch (yPass) {
case 0:
case 1:
return (pgm_read_byte(&BMP_PLATEAU_UP[xPass + ((yPass) * 128)])) & (0xff - Display(xPass, yPass));
break;
default:
break;
};
return pgm_read_byte(&BMP_PLATEAU[xPass + ((yPass - 2) * 128)]);
};
uint8_t Recupe(uint8_t xPass, uint8_t yPass) {
return (RecupeBack(xPass, yPass) | RecupePointer(xPass, yPass));
};
void Flip(uint8_t pointer, uint8_t start, uint8_t end) {
switch (pointer) {
case 1:
DivideBy2 = 0;
break;
default:
DivideBy2 = !DivideBy2;
break;
};
DivideBy2 = (MyTurn == 0) ? 0 : DivideBy2;
uint8_t y, x;
for (y = start; y < end; y++) {
DisplayStart(y);
for (x = 0; x < 128; x++) DisplaySendByte(Recupe(x, y));
DisplayStop();
};
};
uint8_t RecupeMenu(uint8_t xPass, uint8_t yPass) {
switch (yPass) {
case 0:
case 1:
return (pgm_read_byte(&BMP_PLATEAU_UP[xPass + ((yPass) * 128)])) & (0xff - Display(xPass, yPass));
break;
case 3 ... 5:
return SpeedBlitz(54, 3, xPass, yPass, 0, BMP_MENU);
break;
default:
return 0;
break;
};
};
void Menu(uint8_t pointer) {
uint8_t y, x;
for (y = 0; y < 8; y++) {
DisplayStart(y);
for (x = 0; x < 128; x++) DisplaySendByte(RecupeMenu(x, y) | (BlitzSprite(52, pointer, x, y, 0, BMP_CURSEUR)) | (BlitzSprite(8, 19, x, y, 0, BMP_INTRO)) | (BlitzSprite(80, 19, x, y, 0, BMP_INTRO)));
DisplayStop();
};
};
// ----------------------------------------
void setup() {
DisplayInit();
JoyPadInit();
};
// ----------------------------------------
void loop() {
NEW_GAME:;
Menu(22 + (Select * 7));
while (true) {
if (JOYPAD_DOWN) {
DEBOUNCE(JOYPAD_DOWN) {
Select = (Select < 2) ? Select + 1 : Select;
Menu(22 + (Select * 7));
Sound(200, 3);
};
while (true) {
if (JOYPAD_DOWN) {} else break;
};
};
if (JOYPAD_UP) {
DEBOUNCE(JOYPAD_UP) {
Select = (Select > 0) ? Select - 1 : Select;
Menu(22 + (Select * 7));
Sound(200, 3);
};
while (true) {
if (JOYPAD_UP) {} else break;
};
}
if (BUTTON_DOWN) break;
};
while (true) {
if (BUTTON_UP) break;
};
uint8_t noRipple = 0;
InitMData();
AssignerXMain(1);
Flip(0, 0, 8);
SoundBox(6);
_delay_ms(500);
while (true) {
if (MyTurn) {
if (JOYPAD_RIGHT) {
DEBOUNCE(JOYPAD_RIGHT) {
if (noRipple == 0) {
noRipple = 1;
PosXY[0] = (PosXY[0] < 2) ? PosXY[0] + 1 : 2;
};
};
} else if (JOYPAD_LEFT) {
DEBOUNCE(JOYPAD_LEFT) {
if (noRipple == 0) {
noRipple = 1;
PosXY[0] = (PosXY[0] > 0) ? PosXY[0] - 1 : 0;
};
};
} else if (JOYPAD_DOWN) {
DEBOUNCE(JOYPAD_DOWN) {
if (noRipple == 0) {
noRipple = 1;
PosXY[1] = (PosXY[1] < 2) ? PosXY[1] + 1 : 2;
};
};
} else if (JOYPAD_UP) {
DEBOUNCE(JOYPAD_UP) {
if (noRipple == 0) {
noRipple = 1;
PosXY[1] = (PosXY[1] > 0) ? PosXY[1] - 1 : 0;
};
};
} else noRipple = 0;
if ((noRipple == 0) && (BUTTON_DOWN)) {
if (Board[PosXY[1]][PosXY[0]] == 2) {
Board[PosXY[1]][PosXY[0]] = Players[1];
RefreshScreen();
SoundBox(Players[1]);
CheckWin(Players[1]);
MyTurn = 0;
noRipple = 1;
};
};
} else {
if (MyTurn == 0) {
CpuPlay();
RefreshScreen();
SoundBox(Players[0]);
CheckWin(Players[0]);
MyTurn = 1;
};
};
if (EndGame > 0) goto NEW_GAME;
Flip(0, 2, 8);
};
};