draw.asm (5112B)
1 org 0x20000 2 bits 32 3 4 pix: equ 0x40000 5 screen_size: equ 0x10000 6 input: equ 0x50000 7 8 header: db '#!/usr/bin/env b8', 0x0a 9 times 32-$+header db 0x0 10 11 jmp [state_fun] 12 state_fun dd init 13 14 init: 15 call inv_cross 16 mov eax, draw_loop 17 mov [state_fun], eax 18 ret 19 20 draw_loop: 21 ; undraw cross 22 call inv_cross 23 24 call preprocess_input 25 26 ; update coords 27 mov eax, 0 28 mov al, byte [input] 29 mov edx, [coords] 30 31 .check_left: 32 mov cl, 1b 33 and cl, al 34 jz .check_right 35 dec dl 36 37 .check_right: 38 mov cl, 10b 39 and cl, al 40 jz .check_up 41 inc dl 42 43 .check_up: 44 mov cl, 100b 45 and cl, al 46 jz .check_down 47 dec dh 48 49 .check_down: 50 mov cl, 1000b 51 and cl, al 52 jz .update_coords 53 inc dh 54 55 .update_coords: 56 mov [coords], edx 57 58 ; update color 59 mov al, byte [pressed_input] 60 .check_x: 61 mov cl, 10000b 62 and cl, al 63 jz .check_c 64 65 call inv_cross 66 call swap_palette_buffer 67 mov ecx, palette_loop 68 mov [state_fun], ecx 69 ret 70 71 ; draw pixel 72 .check_c 73 mov al, [input] 74 mov cl, 100000b 75 and cl, al 76 jz .check_end 77 78 call draw_point 79 80 .check_end: 81 82 call inv_cross 83 84 ret 85 86 palette_loop: 87 call draw_palette 88 89 call preprocess_input 90 91 mov eax, 0 92 mov al, byte [pressed_input] 93 94 .check_x: 95 mov cl, 10000b 96 and cl, al 97 jz .check_left 98 call swap_palette_buffer 99 mov ecx, draw_loop 100 mov [state_fun], ecx 101 ret 102 103 ; move color cursor 104 105 .check_left: 106 mov eax, 0 107 mov al, byte [pressed_input] 108 109 mov cl, 1b 110 and cl, al 111 jz .check_right 112 113 mov cl, [selected] 114 inc cl 115 and cl, [palette_mask] 116 mov byte [selected], cl 117 118 .check_right: 119 mov cl, 10b 120 and cl, al 121 jz .check_up 122 123 mov cl, [selected] 124 dec cl 125 and cl, [palette_mask] 126 mov byte [selected], cl 127 128 ; change draw point radius 129 .check_up: 130 mov cl, 100b 131 and cl, al 132 jz .check_down 133 134 mov cl, [radius] 135 inc cl 136 cmp cl, 5 137 jle .no_huge_radius 138 dec cl 139 .no_huge_radius 140 and cl, [palette_mask] 141 mov byte [radius], cl 142 143 .check_down: 144 mov cl, 1000b 145 and cl, al 146 jz .check_end 147 148 mov cl, [radius] 149 dec cl 150 jnz .no_null_radius 151 inc cl 152 .no_null_radius: 153 and cl, [palette_mask] 154 mov byte [radius], cl 155 156 .check_end: 157 158 ret 159 160 inv_cross: 161 mov edx, [coords] 162 mov ecx, 0 163 164 ;up 165 mov cx, dx 166 sub cx, 0x100 167 call inv_pix 168 sub cx, 0x100 169 call inv_pix 170 171 ;down 172 mov cx, dx 173 add cx, 0x100 174 call inv_pix 175 add cx, 0x100 176 call inv_pix 177 178 ;left 179 mov cx, dx 180 dec cx 181 call inv_pix 182 dec cx 183 call inv_pix 184 185 ;right 186 mov cx, dx 187 inc cx 188 call inv_pix 189 inc cx 190 call inv_pix 191 192 ret 193 194 inv_pix: ;pass coords in cl 195 mov eax, 0 196 mov al, byte [pix+ecx] 197 xor al, ~0 198 mov byte [pix+ecx], al 199 ret 200 201 draw_palette: 202 mov ecx, 0xf 203 mov edx, pix 204 205 .y_loop: 206 push ecx 207 208 ; this gives a slight slant to color cells 209 ; but it's actually funny 210 mov ecx, 0xff 211 212 .x_loop: 213 push edx 214 215 ; get color id 216 mov edx, ecx 217 sar edx, 5 218 219 mov eax, 0 220 mov al, [selected] 221 222 ;spagetti party! 223 cmp al, dl 224 je .draw_selected 225 226 .draw_direct: 227 mov al, byte [palette + edx] 228 jmp .draw 229 230 .draw_selected: 231 ;TODO: remove hardcoded values 232 ; limiting to 16 color palettes 233 234 ;column borders 235 mov eax, ecx 236 and eax, 0x1f 237 cmp eax, 4 238 jl .do_it 239 240 cmp eax, 27 241 jg .do_it 242 243 ;line borderes 244 mov eax, [esp+4] 245 cmp eax, 4 246 jl .do_it 247 248 cmp eax, 13 249 jg .do_it 250 251 jmp .draw_direct 252 253 .do_it 254 mov al, byte [palette + edx] 255 xor al, ~0 256 257 .draw: 258 pop edx 259 mov [edx], al ; put color to screen 260 inc edx 261 loop .x_loop 262 263 pop ecx 264 loop .y_loop 265 266 ; draw a point to show the radius 267 268 mov edx, [coords] 269 push edx 270 271 mov al, byte [selected] 272 push eax 273 274 ; set point coords 275 mov dh, 7 276 277 mov dl, 7 278 sub dl, al 279 sal dl, 5 280 add dl, 8 281 282 mov [coords], edx 283 284 ; set point color 285 286 cmp al, 0 287 jne .no_black 288 289 mov al, 7 290 291 jmp .store_selected 292 293 .no_black: 294 295 mov al, 0 296 297 .store_selected: 298 299 mov byte [selected], al 300 301 ; draw point 302 303 call draw_point 304 305 pop eax 306 mov byte [selected], al 307 308 pop edx 309 mov [coords], edx 310 311 ret 312 313 swap_palette_buffer: 314 mov ecx, 0x1000 315 316 .loop: 317 mov al, byte [pix + ecx] 318 mov dl, byte [palette_buffer + ecx] 319 mov byte [pix + ecx], dl 320 mov byte [palette_buffer + ecx], al 321 loop .loop 322 323 ret 324 325 preprocess_input: 326 mov al, byte [new_input] 327 mov byte [old_input], al 328 mov cl, byte [input] 329 mov byte [new_input], cl 330 331 xor al, ~0 332 and cl, al 333 mov byte [pressed_input], cl 334 335 mov al, byte [old_input] 336 mov cl, byte [new_input] 337 xor cl, ~0 338 and al, cl 339 mov byte [released_input], cl 340 341 ret 342 343 draw_point: 344 ; get topright corner 345 mov edx, [coords] 346 mov ecx, [radius] 347 348 sub dh, cl 349 inc dh 350 add dl, cl 351 352 ; cover the square surface 353 mov ecx, [radius] 354 sal ecx, 1 355 dec ecx 356 .x_loop: 357 push ecx 358 mov ecx, [radius] 359 sal ecx, 1 360 dec ecx 361 362 ; get to the left side 363 sub dl, cl 364 .y_loop 365 push ecx 366 367 ; get color & draw pixel 368 mov ecx, 0 369 mov eax, 0 370 mov cl, byte [selected] 371 mov al, byte [palette + ecx] 372 mov byte [pix+edx], al 373 374 pop ecx 375 376 ; go one pixel right 377 inc dl 378 loop .y_loop 379 pop ecx 380 381 ; go one pixel down 382 inc dh 383 loop .x_loop 384 ret 385 386 old_input: db 0 387 new_input: db 0 388 pressed_input: db 0 389 released_input: db 0 390 391 coords: dd 0x8080 392 393 radius: dd 0x2 394 395 selected: db 0 396 palette: db 0, 11b, 11111b, 11100b, 11111100b, 11100000b, 11100011b, ~0 397 palette_mask: db 7 398 palette_buffer: db 0 ;times 0x1000 db 0 ;256 col * 16 lines