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.