git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-lib/examples/gb/paint/paint.c

      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 
     25 typedef 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 
     33 typedef 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, relative to top-left of sprite (in pixels) */
     38 } cursor_info;
     39 
     40 const 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 
     74 const 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 
    138 const 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 
    202 const 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 
    218 const 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 
    248 unsigned char data_buffer[NB_DATA_TILES][0x10];
    249 
    250 const uint8_t colors[] = { WHITE, DKGREY, LTGREY, BLACK };
    251 const uint8_t modes[] = { SOLID, OR, XOR, AND };
    252 
    253 uint8_t current_tool;
    254 uint8_t current_color;
    255 uint8_t current_mode;
    256 uint8_t current_cursor;
    257 uint8_t menu_cursor_pos;
    258 
    259 uint8_t cursor_x;
    260 uint8_t cursor_y;
    261 
    262 void set_cursor(void)
    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 
    282 void move_cursor(void)
    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 
    293 void move_menu_cursor(void)
    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 
    300 void 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 
    314 void 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 
    328 void 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 
    340 void splash(void)
    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     vsync();
    353     move_cursor();
    354     plot(cursor_x, cursor_y, BLACK, SOLID);
    355   }
    356   for(; cursor_y < 94; cursor_y++) {
    357     vsync();
    358     move_cursor();
    359     plot(cursor_x, cursor_y, BLACK, SOLID);
    360   }
    361   for(; cursor_x > 40; cursor_x--) {
    362     vsync();
    363     move_cursor();
    364     plot(cursor_x, cursor_y, BLACK, SOLID);
    365   }
    366   for(; cursor_y > 50; cursor_y--) {
    367     vsync();
    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 
    384 void menu(void)
    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     vsync();
    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 	vsync();
    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 
    454 void run(void)
    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     vsync();
    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 	vsync();
    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 
    512 void main(void)
    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 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.