paint.c (19404B)
1#include <gb/gb.h> 2#include <stdint.h> 3#include <gb/drawing.h> 4 5#define NB_TOOLS 18 6#define NB_DATA_TILES 48 7 8#define ARROW 0 9#define PEN 1 10#define BRUSH 2 11#define FILL 3 12#define ERASER 4 13#define CROSS 5 14 15#define UNSELECTED 0 16#define SELECTED 1 17 18#define FIRST_TOOL 0 19#define LAST_TOOL 9 20#define FIRST_COLOR 10 21#define LAST_COLOR 13 22#define FIRST_MODE 14 23#define LAST_MODE 17 24 25typedef struct icon_info_ 26{ 27 uint8_t data_idx; /* Index of data in the data array */ 28 uint8_t x, y, w, h; /* Position and size (in tiles) */ 29 uint8_t up, down, left, right; /* Index of next icons (for cursor movements) */ 30 uint8_t cursor; /* Cursor associated with icon */ 31} icon_info; 32 33typedef struct cursor_info_ 34{ 35 uint8_t data_idx; /* Index of data in the data array */ 36 uint8_t w, h; /* Size (in tiles) */ 37 uint8_t hot_x, hot_y; /* Position of hot point, relatice to top-left of sprite (in pixels) */ 38} cursor_info; 39 40const icon_info icons[] = 41{ 42 /* Pen */ 43 { 0, 0, 0, 2, 2, 10, 2, 1, 1, 1 }, /* 0 */ 44 /* Brush */ 45 { 4, 2, 0, 2, 2, 14, 3, 0, 0, 2 }, /* 1 */ 46 /* Fill */ 47 { 8, 0, 2, 2, 2, 0, 4, 3, 3, 3 }, /* 2 */ 48 /* Eraser */ 49 { 12, 2, 2, 2, 2, 1, 5, 2, 2, 4 }, /* 3 */ 50 /* Line */ 51 { 16, 0, 4, 2, 2, 2, 6, 5, 5, 5 }, /* 4 */ 52 /* Line */ 53 { 20, 2, 4, 2, 2, 3, 7, 4, 4, 5 }, /* 5 */ 54 /* Rectangle */ 55 { 24, 0, 6, 2, 2, 4, 8, 7, 7, 5 }, /* 6 */ 56 /* Oval */ 57 { 28, 2, 6, 2, 2, 5, 9, 6, 6, 5 }, /* 7 */ 58 /* Filled rectangle */ 59 { 32, 0, 8, 2, 2, 6, 10, 9, 9, 5 }, /* 8 */ 60 /* Filled oval */ 61 { 36, 2, 8, 2, 2, 7, 14, 8, 8, 5 }, /* 9 */ 62 /* Color */ 63 { 40, 0, 10, 1, 1, 8, 11, 16, 12, 0 }, /* 10 */ 64 { 41, 0, 11, 1, 1, 10, 0, 17, 13, 0 }, /* 11 */ 65 { 42, 1, 10, 1, 1, 8, 13, 10, 14, 0 }, /* 12 */ 66 { 43, 1, 11, 1, 1, 12, 0, 11, 15, 0 }, /* 13 */ 67 /* Mode */ 68 { 44, 2, 10, 1, 1, 9, 15, 12, 16, 0 }, /* 14 */ 69 { 45, 2, 11, 1, 1, 14, 1, 13, 17, 0 }, /* 15 */ 70 { 46, 3, 10, 1, 1, 9, 17, 14, 10, 0 }, /* 16 */ 71 { 47, 3, 11, 1, 1, 16, 1, 15, 11, 0 } /* 17 */ 72}; 73 74const unsigned char data[NB_DATA_TILES][0x10] = 75{ 76 /* Pen */ 77 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01 }, 78 { 0x7E,0x02,0x7D,0x05,0x7B,0x0A,0x77,0x14,0x7F,0x18,0x7F,0x27,0x7F,0x00,0x00,0x7F }, 79 { 0x00,0x00,0xFE,0x01,0xFE,0x0D,0xF6,0x15,0xEE,0x29,0xDE,0x51,0xBE,0xA1,0x7E,0x41 }, 80 { 0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0x01,0x00,0xFF }, 81 /* Brush */ 82 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01 }, 83 { 0x7E,0x02,0x7D,0x0D,0x7F,0x1E,0x7F,0x1E,0x7F,0x1D,0x7F,0x11,0x7F,0x00,0x00,0x7F }, 84 { 0x00,0x00,0xFE,0x01,0xFE,0x0D,0xF6,0x15,0xEE,0x29,0xDE,0x51,0xBE,0xA1,0x7E,0x41 }, 85 { 0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0xFD,0xFE,0x01,0x00,0xFF }, 86 /* Fill */ 87 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01,0x7F,0x02,0x7E,0x0C,0x7D,0x18,0x7E,0x1D }, 88 { 0x7F,0x1B,0x7F,0x19,0x7F,0x18,0x7F,0x08,0x7F,0x08,0x7F,0x08,0x7F,0x00,0x00,0x7F }, 89 { 0x00,0x00,0xFE,0x01,0xFE,0x81,0xFE,0x41,0x7E,0x21,0xBE,0x71,0x5E,0xE9,0xAE,0xC5 }, 90 { 0x5E,0x89,0xBE,0x11,0xFE,0xA1,0xFE,0x41,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x00,0xFF }, 91 /* Eraser */ 92 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x01,0x7E,0x02,0x7C,0x04 }, 93 { 0x78,0x08,0x7F,0x1F,0x71,0x11,0x7F,0x1F,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F }, 94 { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xF9,0x1E,0x19,0x2E,0x29,0x5E,0x51 }, 95 { 0xBE,0xA1,0x7E,0x41,0xFE,0x81,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x00,0xFF }, 96 /* Line */ 97 { 0x00,0x00,0x7F,0x00,0x7F,0x20,0x7F,0x10,0x7F,0x08,0x7F,0x04,0x7F,0x02,0x7F,0x01 }, 98 { 0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F }, 99 { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01 }, 100 { 0xFE,0x81,0xFE,0x41,0xFE,0x21,0xFE,0x11,0xFE,0x09,0xFE,0x05,0xFE,0x01,0x00,0xFF }, 101 /* Arc */ 102 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x1E,0x7F,0x01,0x7F,0x00,0x7F,0x00,0x7F,0x00 }, 103 { 0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x00,0x00,0x7F }, 104 { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x81,0xFE,0x41,0xFE,0x21,0xFE,0x11 }, 105 { 0xFE,0x11,0xFE,0x09,0xFE,0x09,0xFE,0x09,0xFE,0x09,0xFE,0x01,0xFE,0x01,0x00,0xFF }, 106 /* Rectangle */ 107 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x3F,0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x20 }, 108 { 0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x20,0x7F,0x3F,0x7F,0x00,0x7F,0x00,0x00,0x7F }, 109 { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0x05 }, 110 { 0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0x05,0xFE,0xFD,0xFE,0x01,0xFE,0x01,0x00,0xFF }, 111 /* Oval */ 112 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x03,0x7F,0x0C,0x7F,0x10,0x7F,0x20,0x7F,0x20 }, 113 { 0x7F,0x20,0x7F,0x20,0x7F,0x10,0x7F,0x0C,0x7F,0x03,0x7F,0x00,0x7F,0x00,0x00,0x7F }, 114 { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xC1,0xFE,0x31,0xFE,0x09,0xFE,0x05,0xFE,0x05 }, 115 { 0xFE,0x05,0xFE,0x05,0xFE,0x09,0xFE,0x31,0xFE,0xC1,0xFE,0x01,0xFE,0x01,0x00,0xFF }, 116 /* Filled rectangle */ 117 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x3F,0x6A,0x3F,0x75,0x3F,0x6A,0x3F,0x75,0x3F }, 118 { 0x6A,0x3F,0x75,0x3F,0x6A,0x3F,0x75,0x3F,0x7F,0x3F,0x7F,0x00,0x7F,0x00,0x00,0x7F }, 119 { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xFD,0xAE,0xFD,0x56,0xFD,0xAE,0xFD,0x56,0xFD }, 120 { 0xAE,0xFD,0x56,0xFD,0xAE,0xFD,0x56,0xFD,0xFE,0xFD,0xFE,0x01,0xFE,0x01,0x00,0xFF }, 121 /* Filled oval */ 122 { 0x00,0x00,0x7F,0x00,0x7F,0x00,0x7F,0x03,0x7E,0x0F,0x75,0x1F,0x6A,0x3F,0x75,0x3F }, 123 { 0x6A,0x3F,0x75,0x3F,0x7A,0x1F,0x7D,0x0F,0x7F,0x03,0x7F,0x00,0x7F,0x00,0x00,0x7F }, 124 { 0x00,0x00,0xFE,0x01,0xFE,0x01,0xFE,0xC1,0xBE,0xF1,0x5E,0xF9,0xAE,0xFD,0x56,0xFD }, 125 { 0xAE,0xFD,0x56,0xFD,0xAE,0xF9,0x7E,0xF1,0xFE,0xC1,0xFE,0x01,0xFE,0x01,0x00,0xFF }, 126 /* Color */ 127 { 0x00,0x00,0x7F,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }, 128 { 0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x40,0x7F,0x7F,0x7F,0x00,0x7F }, 129 { 0x00,0x00,0xFE,0xFF,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03,0xFE,0x03 }, 130 { 0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0x00,0xFF }, 131 /* Mode */ 132 { 0x00,0x00,0x7F,0x00,0x7F,0x0C,0x7F,0x10,0x7F,0x08,0x7F,0x04,0x7F,0x18,0x7F,0x00 }, 133 { 0x7F,0x00,0x7F,0x08,0x7F,0x14,0x7F,0x14,0x7F,0x14,0x7F,0x08,0x7F,0x00,0x00,0x7F }, 134 { 0x00,0x01,0xFE,0x01,0xFE,0x29,0xFE,0x29,0xFE,0x11,0xFE,0x29,0xFE,0x29,0xFE,0x01 }, 135 { 0xFE,0x01,0xFE,0x11,0xFE,0x29,0xFE,0x39,0xFE,0x29,0xFE,0x29,0xFE,0x01,0x00,0xFF } 136}; 137 138const unsigned char selected_data[NB_DATA_TILES][0x10] = 139{ 140 /* Pen */ 141 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE }, 142 { 0x81,0xFD,0x82,0xFA,0x84,0xF5,0x88,0xEB,0x80,0xE7,0x80,0xD8,0x80,0xFF,0xFF,0x80 }, 143 { 0xFF,0xFF,0x01,0xFE,0x01,0xF2,0x09,0xEA,0x11,0xD6,0x21,0xAE,0x41,0x5E,0x81,0xBE }, 144 { 0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0xFE,0xFF,0x00 }, 145 /* Brush */ 146 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE }, 147 { 0x81,0xFD,0x82,0xF2,0x80,0xE1,0x80,0xE1,0x80,0xE2,0x80,0xEE,0x80,0xFF,0xFF,0x80 }, 148 { 0xFF,0xFF,0x01,0xFE,0x01,0xF2,0x09,0xEA,0x11,0xD6,0x21,0xAE,0x41,0x5E,0x81,0xBE }, 149 { 0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0x02,0x01,0xFE,0xFF,0x00 }, 150 /* Fill */ 151 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE,0x80,0xFD,0x81,0xF3,0x82,0xE7,0x81,0xE2 }, 152 { 0x80,0xE4,0x80,0xE7,0x80,0xE7,0x80,0xF7,0x80,0xF7,0x80,0xF7,0x80,0xFF,0xFF,0x80 }, 153 { 0xFF,0xFF,0x01,0xFE,0x01,0x7E,0x01,0xBE,0x81,0xDE,0x41,0x8E,0xA1,0x16,0x51,0x3A }, 154 { 0xA1,0x76,0x41,0xEE,0x01,0x5E,0x01,0xBE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, 155 /* Eraser */ 156 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFE,0x81,0xFD,0x83,0xFB }, 157 { 0x87,0xF7,0x80,0xE0,0x8E,0xEE,0x80,0xE0,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, 158 { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x06,0xE1,0xE6,0xD1,0xD6,0xA1,0xAE }, 159 { 0x41,0x5E,0x81,0xBE,0x01,0x7E,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, 160 /* Line */ 161 { 0xFF,0xFF,0x80,0xFF,0x80,0xDF,0x80,0xEF,0x80,0xF7,0x80,0xFB,0x80,0xFD,0x80,0xFE }, 162 { 0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, 163 { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE }, 164 { 0x01,0x7E,0x01,0xBE,0x01,0xDE,0x01,0xEE,0x01,0xF6,0x01,0xFA,0x01,0xFE,0xFF,0x00 }, 165 /* Arc */ 166 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xE1,0x80,0xFE,0x80,0xFF,0x80,0xFF,0x80,0xFF }, 167 { 0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, 168 { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0x7E,0x01,0xBE,0x01,0xDE,0x01,0xEE }, 169 { 0x01,0xEE,0x01,0xF6,0x01,0xF6,0x01,0xF6,0x01,0xF6,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, 170 /* Rectangle */ 171 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xC0,0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xDF }, 172 { 0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xDF,0x80,0xC0,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, 173 { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x02,0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0xFA }, 174 { 0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0xFA,0x01,0x02,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, 175 /* Oval */ 176 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFC,0x80,0xF3,0x80,0xEF,0x80,0xDF,0x80,0xDF }, 177 { 0x80,0xDF,0x80,0xDF,0x80,0xEF,0x80,0xF3,0x80,0xFC,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, 178 { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x3E,0x01,0xCE,0x01,0xF6,0x01,0xFA,0x01,0xFA }, 179 { 0x01,0xFA,0x01,0xFA,0x01,0xF6,0x01,0xCE,0x01,0x3E,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, 180 /* Filled rectangle */ 181 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0 }, 182 { 0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x9F,0xC0,0x80,0xC0,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, 183 { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02 }, 184 { 0xF9,0x02,0xF9,0x02,0xF9,0x02,0xF9,0x02,0x01,0x02,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, 185 /* Filled oval */ 186 { 0xFF,0xFF,0x80,0xFF,0x80,0xFF,0x80,0xFC,0x83,0xF0,0x8F,0xE0,0x9F,0xC0,0x9F,0xC0 }, 187 { 0x9F,0xC0,0x9F,0xC0,0x8F,0xE0,0x83,0xF0,0x80,0xFC,0x80,0xFF,0x80,0xFF,0xFF,0x80 }, 188 { 0xFF,0xFF,0x01,0xFE,0x01,0xFE,0x01,0x3E,0xC1,0x0E,0xF1,0x06,0xF9,0x02,0xF9,0x02 }, 189 { 0xF9,0x02,0xF9,0x02,0xF1,0x06,0xC1,0x0E,0x01,0x3E,0x01,0xFE,0x01,0xFE,0xFF,0x00 }, 190 /* Color */ 191 { 0x00,0x00,0x7F,0x7F,0x61,0x61,0x52,0x52,0x4C,0x4C,0x4C,0x4C,0x52,0x52,0x61,0x61 }, 192 { 0x40,0x5E,0x40,0x6D,0x40,0x73,0x40,0x73,0x40,0x6D,0x40,0x5E,0x7F,0x7F,0x00,0x7F }, 193 { 0x00,0x00,0xFE,0xFF,0xFE,0x87,0xFE,0x4B,0xFE,0x33,0xFE,0x33,0xFE,0x4B,0xFE,0x87 }, 194 { 0x7A,0x7B,0xB6,0xB7,0xCE,0xCF,0xCE,0xCF,0xB6,0xB7,0x7A,0x7B,0xFE,0xFF,0x00,0xFF }, 195 /* Mode */ 196 { 0x00,0x00,0x7F,0x7F,0x73,0x73,0x6F,0x6F,0x77,0x77,0x7B,0x7B,0x67,0x67,0x7F,0x7F }, 197 { 0x7F,0x7F,0x77,0x77,0x6B,0x6B,0x6B,0x6B,0x6B,0x6B,0x77,0x77,0x7F,0x7F,0x00,0x7F }, 198 { 0x00,0x01,0xFE,0xFF,0xD6,0xD7,0xD6,0xD7,0xEE,0xEF,0xD6,0xD7,0xD6,0xD7,0xFE,0xFF }, 199 { 0xFE,0xFF,0xEE,0xEF,0xD6,0xD7,0xC6,0xC7,0xD6,0xD7,0xD6,0xD7,0xFE,0xFF,0x00,0xFF } 200}; 201 202const cursor_info cursors[] = 203{ 204 /* Arrow */ 205 { 0, 1, 1, 0, 0 }, 206 /* Pen */ 207 { 1, 2, 2, 0, 15 }, 208 /* Brush */ 209 { 5, 2, 2, 0, 15 }, 210 /* Fill */ 211 { 9, 2, 2, 2, 15 }, 212 /* Eraser */ 213 { 13, 2, 2, 0, 15 }, 214 /* Cross */ 215 { 17, 2, 2, 5, 10 } 216}; 217 218const unsigned char cursors_data[][0x10] = { 219 /* Arrow */ 220 { 0xFF,0x00,0xFF,0x7E,0xFF,0x7C,0xFE,0x78,0xFF,0x7C,0xFF,0x6E,0xFF,0x46,0xEF,0x00 }, 221 /* Pen */ 222 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x01 }, 223 { 0x0F,0x02,0x1F,0x05,0x3F,0x0A,0x7F,0x14,0x7E,0x28,0xFC,0x30,0xF8,0x40,0x60,0x00 }, 224 { 0x00,0x00,0x00,0x00,0x3C,0x00,0x7C,0x18,0xFC,0x28,0xFC,0x50,0xF8,0xA0,0xF0,0x40 }, 225 { 0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 226 /* Brush */ 227 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x01,0x0F,0x02 }, 228 { 0x1F,0x05,0x7F,0x0A,0xFF,0x34,0xFE,0x78,0xFC,0x78,0xFC,0x70,0xF8,0x40,0x60,0x00 }, 229 { 0x00,0x00,0x00,0x00,0x78,0x00,0xF8,0x30,0xF8,0x50,0xF8,0xA0,0xF0,0x40,0xE0,0x80 }, 230 { 0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 231 /* Fill */ 232 { 0x00,0x00,0x00,0x00,0x07,0x00,0x0F,0x02,0x1F,0x05,0x7F,0x08,0xFE,0x31,0xFD,0x63 }, 233 { 0xFA,0x77,0xFD,0x6E,0xFF,0x64,0xFF,0x62,0xF7,0x21,0x73,0x20,0x70,0x20,0x50,0x00 }, 234 { 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xC0,0x00,0xE0,0x80,0xF0,0xC0,0x78,0xA0 }, 235 { 0xF8,0x10,0xF8,0x20,0xF0,0x40,0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00 }, 236 /* Eraser */ 237 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0F,0x03 }, 238 { 0x1F,0x04,0x3F,0x08,0x7F,0x11,0xFF,0x22,0xFF,0x7D,0xFF,0x46,0xFF,0x7C,0x7E,0x00 }, 239 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xF0,0xE0 }, 240 { 0xF0,0x60,0xF0,0xA0,0xF0,0x40,0xE0,0x80,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00 }, 241 /* Cross */ 242 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x04,0x0E,0x04 }, 243 { 0x0E,0x04,0xFF,0x04,0xFB,0x7B,0xFF,0x04,0x0E,0x04,0x0E,0x04,0x0E,0x04,0x0E,0x00 }, 244 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 245 { 0x00,0x00,0xE0,0x00,0xE0,0xC0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 246}; 247 248unsigned char data_buffer[NB_DATA_TILES][0x10]; 249 250const uint8_t colors[] = { WHITE, DKGREY, LTGREY, BLACK }; 251const uint8_t modes[] = { SOLID, OR, XOR, AND }; 252 253uint8_t current_tool; 254uint8_t current_color; 255uint8_t current_mode; 256uint8_t current_cursor; 257uint8_t menu_cursor_pos; 258 259uint8_t cursor_x; 260uint8_t cursor_y; 261 262void set_cursor() 263{ 264 uint8_t x, y, i; 265 266 i = 0; 267 for(x = 0; x < cursors[current_cursor].w; x++) 268 for(y = 0; y < cursors[current_cursor].h; y++) { 269 set_sprite_data(i, 270 1, 271 cursors_data[cursors[current_cursor].data_idx+i]); 272 set_sprite_tile(i, i); 273 set_sprite_prop(i, 0x10); 274 i++; 275 } 276 /* Hide unused sprites */ 277 for(; i < 4; i++) { 278 move_sprite(i, 0, 0); 279 } 280} 281 282void move_cursor() 283{ 284 uint8_t x, y; 285 286 for(x = 0; x < cursors[current_cursor].w; x++) 287 for(y = 0; y < cursors[current_cursor].h; y++) 288 move_sprite((x<<1)+y, 289 cursor_x+8 - cursors[current_cursor].hot_x + (x<<3), 290 cursor_y+16 - cursors[current_cursor].hot_y + (y<<3)); 291} 292 293void move_menu_cursor() 294{ 295 move_sprite(0, 296 ((icons[menu_cursor_pos].x+icons[menu_cursor_pos].w)<<3) + 4, 297 ((icons[menu_cursor_pos].y+icons[menu_cursor_pos].h)<<3) + 12); 298} 299 300void set_icon(uint8_t icon, uint8_t selected) 301{ 302 uint8_t x, y; 303 304 for(x = 0; x < icons[icon].w; x++) 305 for(y = 0; y < icons[icon].h; y++) { 306 uint16_t index = icons[icon].data_idx+((uint16_t)x<<1)+y; 307 switch_data(icons[icon].x + x, 308 icons[icon].y + y, 309 selected ? selected_data[index] : data[index], 310 data_buffer[index]); 311 } 312} 313 314void change_icon(uint8_t icon, uint8_t selected) 315{ 316 uint8_t x, y; 317 318 for(x = 0; x < icons[icon].w; x++) 319 for(y = 0; y < icons[icon].h; y++) 320 switch_data(icons[icon].x + x, 321 icons[icon].y + y, 322 (selected ? 323 selected_data[icons[icon].data_idx+((uint16_t)x<<1)+y] : 324 data[icons[icon].data_idx+((uint16_t)x<<1)+y]), 325 NULL); 326} 327 328void reset_icon(uint8_t icon) 329{ 330 uint8_t x, y; 331 332 for(x = 0; x < icons[icon].w; x++) 333 for(y = 0; y < icons[icon].h; y++) 334 switch_data(icons[icon].x + x, 335 icons[icon].y + y, 336 data_buffer[icons[icon].data_idx+(x<<1)+y], 337 NULL); 338} 339 340void splash() 341{ 342 uint8_t x, y; 343 344 cursor_x = 40; 345 cursor_y = 50; 346 current_cursor = PEN; 347 set_cursor(); 348 move_cursor(); 349 SHOW_SPRITES; 350 351 for(; cursor_x < 120; cursor_x++) { 352 wait_vbl_done(); 353 move_cursor(); 354 plot(cursor_x, cursor_y, BLACK, SOLID); 355 } 356 for(; cursor_y < 94; cursor_y++) { 357 wait_vbl_done(); 358 move_cursor(); 359 plot(cursor_x, cursor_y, BLACK, SOLID); 360 } 361 for(; cursor_x > 40; cursor_x--) { 362 wait_vbl_done(); 363 move_cursor(); 364 plot(cursor_x, cursor_y, BLACK, SOLID); 365 } 366 for(; cursor_y > 50; cursor_y--) { 367 wait_vbl_done(); 368 move_cursor(); 369 plot(cursor_x, cursor_y, BLACK, SOLID); 370 } 371 cursor_x = 160/2; 372 cursor_y = 144/2; 373 current_cursor = FILL; 374 set_cursor(); 375 move_cursor(); 376 377 for(y = 51; y < 94; y++) 378 for(x = 41; x < 120; x++) 379 plot(x, y, LTGREY, SOLID); 380 381 // HIDE_SPRITES; 382} 383 384void menu() 385{ 386 uint8_t i, key; 387 uint8_t slowdown; 388 uint8_t cursor; 389 390 slowdown = 50; 391 392 for(i = 0; i < NB_TOOLS; i++) 393 set_icon(i, 394 i == FIRST_TOOL + current_tool || 395 i == FIRST_COLOR + current_color || 396 i == FIRST_MODE + current_mode); 397 398 cursor = current_cursor; 399 current_cursor = ARROW; 400 set_cursor(); 401 move_menu_cursor(); 402 SHOW_SPRITES; 403 waitpadup(); 404 do { 405 wait_vbl_done(); 406 key = joypad(); 407 if(key & (J_UP|J_DOWN|J_LEFT|J_RIGHT)) { 408 if(key & J_UP) 409 menu_cursor_pos = icons[menu_cursor_pos].up; 410 if(key & J_DOWN) 411 menu_cursor_pos = icons[menu_cursor_pos].down; 412 if(key & J_LEFT) 413 menu_cursor_pos = icons[menu_cursor_pos].left; 414 if(key & J_RIGHT) 415 menu_cursor_pos = icons[menu_cursor_pos].right; 416 move_menu_cursor(); 417 while(slowdown && key == joypad()) { 418 wait_vbl_done(); 419 slowdown--; 420 } 421 slowdown = 10; 422 } else 423 slowdown = 50; 424 if(key & J_A) { 425 if( /* menu_cursor_pos >= FIRST_TOOL && */ menu_cursor_pos <= LAST_TOOL) { 426 if(menu_cursor_pos != /* FIRST_TOOL + */ current_tool) { 427 change_icon(/* FIRST_TOOL + */ current_tool, UNSELECTED); 428 current_tool = menu_cursor_pos /* - FIRST_TOOL */; 429 change_icon(/* FIRST_TOOL + */ current_tool, SELECTED); 430 cursor = icons[/* FIRST_TOOL + */ current_tool].cursor; 431 } 432 } else if(menu_cursor_pos >= FIRST_COLOR && menu_cursor_pos <= LAST_COLOR) { 433 if(menu_cursor_pos != FIRST_COLOR + current_color) { 434 change_icon(FIRST_COLOR + current_color, UNSELECTED); 435 current_color = menu_cursor_pos - FIRST_COLOR; 436 change_icon(FIRST_COLOR + current_color, SELECTED); 437 } 438 } else if(menu_cursor_pos >= FIRST_MODE && menu_cursor_pos <= LAST_MODE) { 439 if(menu_cursor_pos != FIRST_MODE + current_mode) { 440 change_icon(FIRST_MODE + current_mode, UNSELECTED); 441 current_mode = menu_cursor_pos - FIRST_MODE; 442 change_icon(FIRST_MODE + current_mode, SELECTED); 443 } 444 } 445 } 446 } while(key != J_SELECT); 447 waitpadup(); 448 for(i = 0; i < NB_TOOLS; i++) 449 reset_icon(i); 450 HIDE_SPRITES; 451 current_cursor = cursor; 452} 453 454void run() 455{ 456 uint8_t key; 457 uint8_t slowdown; 458 uint8_t drawn, erased; 459 460 slowdown = 10; 461 drawn = erased = 0; 462 463 set_cursor(); 464 move_cursor(); 465 SHOW_SPRITES; 466 467 while(1) { 468 wait_vbl_done(); 469 key = joypad(); 470 if(key & (J_UP|J_DOWN|J_LEFT|J_RIGHT)) { 471 if(key & J_UP && cursor_y > 0) 472 cursor_y--; 473 if(key & J_DOWN && cursor_y < 143) 474 cursor_y++; 475 if(key & J_LEFT && cursor_x > 0) 476 cursor_x--; 477 if(key & J_RIGHT && cursor_x < 159) 478 cursor_x++; 479 move_cursor(); 480 while(slowdown && key == joypad()) { 481 wait_vbl_done(); 482 slowdown--; 483 } 484 slowdown = 1; 485 drawn = erased = 0; 486 } else 487 slowdown = 10; 488 if(key & J_SELECT) { 489 HIDE_SPRITES; 490 menu(); 491 set_cursor(); 492 move_cursor(); 493 SHOW_SPRITES; 494 } 495 if((key & (J_A|J_B)) == J_A) { 496 if(!drawn) { 497 drawn++; 498 plot(cursor_x, cursor_y, colors[current_color], modes[current_mode]); 499 } 500 } else 501 drawn = 0; 502 if((key & (J_A|J_B)) == J_B) { 503 if(!erased) { 504 erased++; 505 plot(cursor_x, cursor_y, WHITE, SOLID); 506 } 507 } else 508 erased = 0; 509 } 510} 511 512void main() 513{ 514 /* Initialize sprite palette */ 515 OBP1_REG = 0xE0U; 516 517 splash(); 518 519 current_tool = 0; 520 current_color = BLACK; 521 current_mode = SOLID; 522 current_cursor = PEN; 523 menu_cursor_pos = 0; 524 cursor_x = 160/2; 525 cursor_y = 144/2; 526 527 run(); 528}