blob: 7bfc5ce21a2cdd3fb4e40b54daf4d062e05ebbf9 [file] [log] [blame]
adamdunkels7e4982c2003-03-19 16:26:18 +00001/*
2 * Copyright (c) 2002, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
14 * 3. All advertising materials mentioning features or use of this
15 * software must display the following acknowledgement:
16 * This product includes software developed by Adam Dunkels.
17 * 4. The name of the author may not be used to endorse or promote
18 * products derived from this software without specific prior
19 * written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * This file is part of the "ctk" console GUI toolkit for cc65
34 *
adamdunkels77e47062003-04-17 15:09:31 +000035 * $Id: ctk-hires.c,v 1.1 2003/04/17 15:09:45 adamdunkels Exp $
adamdunkels7e4982c2003-03-19 16:26:18 +000036 *
37 */
adamdunkels77e47062003-04-17 15:09:31 +000038
adamdunkels7e4982c2003-03-19 16:26:18 +000039#include "ctk.h"
40#include "ctk-draw.h"
adamdunkels77e47062003-04-17 15:09:31 +000041#include "ctk-hires.h"
42#include "ctk-hires-asm.h"
43
44#include "ctk-hires-theme.h"
adamdunkels7e4982c2003-03-19 16:26:18 +000045
46#include <string.h>
47
48#ifndef NULL
49#define NULL (void *)0
50#endif /* NULL */
51
52#define SCREEN_HEIGHT 25
53#define SCREEN_WIDTH 40
54
55#define SCREENADDR 0xdc00
56#define HIRESADDR 0xe000
57
58static unsigned char lineptr;
59
adamdunkels77e47062003-04-17 15:09:31 +000060unsigned char ctk_hires_cursx, ctk_hires_cursy;
61unsigned char ctk_hires_reversed;
62unsigned char ctk_hires_color;
63unsigned char ctk_hires_underline;
adamdunkels7e4982c2003-03-19 16:26:18 +000064
65static unsigned char cchar;
66
67static unsigned char tmp01;
68static unsigned char tmph, tmpl, tmpborder;
69static unsigned char *tmpptr;
70
71
72static unsigned char x, y, i;
73static unsigned char h;
74static unsigned char wfocus;
75static unsigned char x1, y1, x2, y2;
76
adamdunkels77e47062003-04-17 15:09:31 +000077struct ctk_hires_windowparams ctk_hires_windowparams;
78unsigned char *ctk_hires_bitmapptr;
adamdunkels7e4982c2003-03-19 16:26:18 +000079/*-----------------------------------------------------------------------------------*/
80/* Tables. */
81
adamdunkels7e4982c2003-03-19 16:26:18 +000082
83
adamdunkels77e47062003-04-17 15:09:31 +000084
85unsigned short ctk_hires_yscreenaddr[25] =
adamdunkels7e4982c2003-03-19 16:26:18 +000086 {0 * SCREEN_WIDTH + SCREENADDR, 1 * SCREEN_WIDTH + SCREENADDR,
87 2 * SCREEN_WIDTH + SCREENADDR, 3 * SCREEN_WIDTH + SCREENADDR,
88 4 * SCREEN_WIDTH + SCREENADDR, 5 * SCREEN_WIDTH + SCREENADDR,
89 6 * SCREEN_WIDTH + SCREENADDR, 7 * SCREEN_WIDTH + SCREENADDR,
90 8 * SCREEN_WIDTH + SCREENADDR, 9 * SCREEN_WIDTH + SCREENADDR,
91 10 * SCREEN_WIDTH + SCREENADDR, 11 * SCREEN_WIDTH + SCREENADDR,
92 12 * SCREEN_WIDTH + SCREENADDR, 13 * SCREEN_WIDTH + SCREENADDR,
93 14 * SCREEN_WIDTH + SCREENADDR, 15 * SCREEN_WIDTH + SCREENADDR,
94 16 * SCREEN_WIDTH + SCREENADDR, 17 * SCREEN_WIDTH + SCREENADDR,
95 18 * SCREEN_WIDTH + SCREENADDR, 19 * SCREEN_WIDTH + SCREENADDR,
96 20 * SCREEN_WIDTH + SCREENADDR, 21 * SCREEN_WIDTH + SCREENADDR,
97 22 * SCREEN_WIDTH + SCREENADDR, 23 * SCREEN_WIDTH + SCREENADDR,
98 24 * SCREEN_WIDTH + SCREENADDR};
99
adamdunkels77e47062003-04-17 15:09:31 +0000100unsigned short ctk_hires_yhiresaddr[25] =
adamdunkels7e4982c2003-03-19 16:26:18 +0000101 {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR,
102 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR,
103 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR,
104 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR,
105 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR,
106 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR,
107 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR,
108 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR,
109 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR,
110 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR,
111 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR,
112 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR,
113 24 * 320 + HIRESADDR};
adamdunkels77e47062003-04-17 15:09:31 +0000114extern struct ctk_hires_theme ctk_hires_theme;
115struct ctk_hires_theme *ctk_hires_theme_ptr = &ctk_hires_theme;
adamdunkels7e4982c2003-03-19 16:26:18 +0000116/*-----------------------------------------------------------------------------------*/
adamdunkels77e47062003-04-17 15:09:31 +0000117#define hires_wherex() ctk_hires_cursx
118#define hires_revers(c) ctk_hires_reversed = c
119#define hires_color(c) ctk_hires_color = c
120#define hires_underline(c) ctk_hires_underline = c
adamdunkels7e4982c2003-03-19 16:26:18 +0000121/*-----------------------------------------------------------------------------------*/
122static void
123hires_cvline(unsigned char length)
124{
125 unsigned char i;
126
127 for(i = 0; i < length; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000128 ctk_hires_cputc('|');
129 --ctk_hires_cursx;
130 ++ctk_hires_cursy;
adamdunkels7e4982c2003-03-19 16:26:18 +0000131 }
132}
133/*-----------------------------------------------------------------------------------*/
134static void
135hires_gotoxy(unsigned char x, unsigned char y)
136{
adamdunkels77e47062003-04-17 15:09:31 +0000137 ctk_hires_cursx = x;
138 ctk_hires_cursy = y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000139}
140/*-----------------------------------------------------------------------------------*/
141static void
142hires_cclearxy(unsigned char x, unsigned char y, unsigned char length)
143{
144 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000145 ctk_hires_cclear(length);
adamdunkels7e4982c2003-03-19 16:26:18 +0000146}
147/*-----------------------------------------------------------------------------------*/
148static void
149hires_chlinexy(unsigned char x, unsigned char y, unsigned char length)
150{
151 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000152 ctk_hires_chline(length);
adamdunkels7e4982c2003-03-19 16:26:18 +0000153}
154/*-----------------------------------------------------------------------------------*/
155static void
156hires_cvlinexy(unsigned char x, unsigned char y, unsigned char length)
157{
158 hires_gotoxy(x, y);
159 hires_cvline(length);
160}
161/*-----------------------------------------------------------------------------------*/
162static void
163hires_cputcxy(unsigned char x, unsigned char y, char c)
164{
165 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000166 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000167}
168/*-----------------------------------------------------------------------------------*/
169static void
170clear_line(unsigned char line)
171{
172 lineptr = line;
adamdunkels77e47062003-04-17 15:09:31 +0000173 asm("lda %v", lineptr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000174 asm("asl");
175 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000176 asm("lda %v,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000177 asm("sta ptr2");
adamdunkels77e47062003-04-17 15:09:31 +0000178 asm("lda %v+1,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000179 asm("sta ptr2+1");
adamdunkels77e47062003-04-17 15:09:31 +0000180 asm("lda %v,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000181 asm("sta ptr1");
adamdunkels77e47062003-04-17 15:09:31 +0000182 asm("lda %v+1,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000183 asm("sta ptr1+1");
184
185
186 asm("sei");
187 asm("lda $01");
188 asm("pha");
189 asm("lda #$30");
190 asm("sta $01");
191 asm("ldy #39");
adamdunkels77e47062003-04-17 15:09:31 +0000192 asm("ldx %v", lineptr);
193 asm("lda %v+%w,x", ctk_hires_theme,
194 offsetof(struct ctk_hires_theme, backgroundpatterncolors));
adamdunkels7e4982c2003-03-19 16:26:18 +0000195 asm("clearlineloop1:");
196 asm("sta (ptr1),y");
197 asm("dey");
198 asm("bpl clearlineloop1");
199 asm("pla");
200 asm("sta $01");
201 asm("cli");
202
203
adamdunkels77e47062003-04-17 15:09:31 +0000204 asm("lda %v", lineptr);
205 /* asm("and #7");*/
adamdunkels7e4982c2003-03-19 16:26:18 +0000206 asm("asl");
adamdunkels77e47062003-04-17 15:09:31 +0000207 asm("asl");
adamdunkels7e4982c2003-03-19 16:26:18 +0000208 asm("asl");
209 asm("tax");
210 asm("ldy #0");
211 asm("clearlineloop2:");
adamdunkels77e47062003-04-17 15:09:31 +0000212 asm("lda %v+%w+0,x", ctk_hires_theme,
213 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000214 asm("sta (ptr2),y");
215 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000216 asm("lda %v+%w+1,x", ctk_hires_theme,
217 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000218 asm("sta (ptr2),y");
219 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000220 asm("lda %v+%w+2,x", ctk_hires_theme,
221 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000222 asm("sta (ptr2),y");
223 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000224 asm("lda %v+%w+3,x", ctk_hires_theme,
225 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000226 asm("sta (ptr2),y");
227 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000228 asm("lda %v+%w+4,x", ctk_hires_theme,
229 offsetof(struct ctk_hires_theme, backgroundpattern));
230 asm("sta (ptr2),y");
231 asm("iny");
232 asm("lda %v+%w+5,x", ctk_hires_theme,
233 offsetof(struct ctk_hires_theme, backgroundpattern));
234 asm("sta (ptr2),y");
235 asm("iny");
236 asm("lda %v+%w+6,x", ctk_hires_theme,
237 offsetof(struct ctk_hires_theme, backgroundpattern));
238 asm("sta (ptr2),y");
239 asm("iny");
240 asm("lda %v+%w+7,x", ctk_hires_theme,
241 offsetof(struct ctk_hires_theme, backgroundpattern));
242 asm("sta (ptr2),y");
243 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000244 asm("bne clearlineloop2");
245
246 asm("inc ptr2+1");
247
248 asm("ldy #0");
249 asm("clearlineloop3:");
adamdunkels77e47062003-04-17 15:09:31 +0000250 asm("lda %v+%w+0,x", ctk_hires_theme,
251 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000252 asm("sta (ptr2),y");
253 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000254 asm("lda %v+%w+1,x", ctk_hires_theme,
255 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000256 asm("sta (ptr2),y");
257 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000258 asm("lda %v+%w+2,x", ctk_hires_theme,
259 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000260 asm("sta (ptr2),y");
261 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000262 asm("lda %v+%w+3,x", ctk_hires_theme,
263 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000264 asm("sta (ptr2),y");
265 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000266 asm("lda %v+%w+4,x", ctk_hires_theme,
267 offsetof(struct ctk_hires_theme, backgroundpattern));
268 asm("sta (ptr2),y");
269 asm("iny");
270 asm("lda %v+%w+5,x", ctk_hires_theme,
271 offsetof(struct ctk_hires_theme, backgroundpattern));
272 asm("sta (ptr2),y");
273 asm("iny");
274 asm("lda %v+%w+6,x", ctk_hires_theme,
275 offsetof(struct ctk_hires_theme, backgroundpattern));
276 asm("sta (ptr2),y");
277 asm("iny");
278 asm("lda %v+%w+7,x", ctk_hires_theme,
279 offsetof(struct ctk_hires_theme, backgroundpattern));
280 asm("sta (ptr2),y");
281 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000282 asm("cpy #$40");
283 asm("bne clearlineloop3");
284
285}
286/*-----------------------------------------------------------------------------------*/
287static void
288nmi2(void)
289{
290 asm("pla");
291 asm("sta $01");
292 asm("pla");
293 asm("rti");
294}
295/*-----------------------------------------------------------------------------------*/
296static void
297nmi(void)
298{
299 asm("sei");
300 asm("pha");
301 asm("inc $d020");
302 asm("lda $01");
303 asm("pha");
304 asm("lda #$36");
305 asm("sta $01");
306 asm("lda #>_nmi2");
307 asm("pha");
308 asm("lda #<_nmi2");
309 asm("pha");
310 asm("php");
311 asm("jmp ($0318)");
312
313 nmi2();
314}
315/*-----------------------------------------------------------------------------------*/
316static void
317setup_nmi(void)
318{
319 asm("lda #<_nmi");
320 asm("sta $fffa");
321 asm("lda #>_nmi");
322 asm("sta $fffb");
323 return;
324 nmi();
325}
326/*-----------------------------------------------------------------------------------*/
327void
328ctk_draw_init(void)
329{
adamdunkels77e47062003-04-17 15:09:31 +0000330 unsigned char i, *ptr1, *ptr2;
331
adamdunkels7e4982c2003-03-19 16:26:18 +0000332 setup_nmi();
333
334 /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for
335 hires/colors. */
336 VIC.ctrl1 = 0x3b; /* $D011 */
337 VIC.addr = 0x78; /* $D018 */
338 VIC.ctrl2 = 0xc8; /* $D016 */
adamdunkels7e4982c2003-03-19 16:26:18 +0000339 CIA2.pra = 0x00; /* $DD00 */
340
adamdunkels77e47062003-04-17 15:09:31 +0000341 VIC.bordercolor = ctk_hires_theme.bordercolor; /* $D020 */
342 VIC.bgcolor0 = ctk_hires_theme.screencolor; /* $D021 */
343
adamdunkels7e4982c2003-03-19 16:26:18 +0000344 /* Fill color memory. */
345 asm("sei");
346 asm("lda $01");
347 asm("pha");
348 asm("lda #$30");
349 asm("sta $01");
350 asm("ldx #0");
351 asm("lda #$c0");
352 asm("fillcolorloop:");
353 asm("sta $dc00,x");
354 asm("sta $dd00,x");
355 asm("sta $de00,x");
356 asm("sta $df00,x");
357 asm("inx");
358 asm("bne fillcolorloop");
adamdunkels77e47062003-04-17 15:09:31 +0000359
360 /* Setup sprite pointers */
361 asm("ldx #$fd");
362 asm("stx $dff8");
363 asm("inx");
364 asm("stx $dff9");
adamdunkels7e4982c2003-03-19 16:26:18 +0000365 asm("pla");
366 asm("sta $01");
367 asm("cli");
368
369 /* Fill hires memory with 0. */
370
371 asm("lda $fd");
372 asm("pha");
373 asm("lda $fe");
374 asm("pha");
375 asm("lda #0");
376 asm("sta $fd");
377 asm("lda #$e0");
378 asm("sta $fe");
379 asm("ldy #0");
380 asm("lda #0");
381 asm("clrscrnloop:");
382 asm("lda #$55");
383 asm("sta ($fd),y");
384 asm("iny");
385 asm("lda #$aa");
386 asm("sta ($fd),y");
387 asm("iny");
388 asm("bne clrscrnloop");
389 asm("inc $fe");
390 asm("lda $fe");
391 asm("cmp #$ff");
392 asm("bne clrscrnloop");
393
394 asm("ldy #$00");
395 asm("clrscrnloop2:");
396 asm("lda #$55");
397 asm("sta $ff00,y");
398 asm("iny");
399 asm("lda #$aa");
400 asm("sta $ff00,y");
401 asm("iny");
402 asm("cpy #$40");
403 asm("bne clrscrnloop2");
404
405
406 asm("pla");
407 asm("sta $fe");
408 asm("pla");
409 asm("sta $fd");
410
adamdunkels7e4982c2003-03-19 16:26:18 +0000411
adamdunkels77e47062003-04-17 15:09:31 +0000412 ctk_draw_clear(0, SCREEN_HEIGHT);
413
414 /* Setup mouse pointer sprite. */
415 asm("lda %v+%w", ctk_hires_theme,
416 offsetof(struct ctk_hires_theme, pointermaskcolor));
417 asm("sta $d027");
418 asm("lda %v+%w", ctk_hires_theme,
419 offsetof(struct ctk_hires_theme, pointercolor));
420 asm("sta $d028");
421
422 ptr1 = ctk_hires_theme.pointer;
423 ptr2 = (unsigned char *)0xff40;
424
425 for(i = 0; i < 0x80; ++i) {
426 *ptr2++ = *ptr1++;
427 }
428
adamdunkels7e4982c2003-03-19 16:26:18 +0000429 return;
430}
431/*-----------------------------------------------------------------------------------*/
432static void
433draw_bitmap_icon(unsigned char *bitmap)
434{
435 tmpptr = bitmap;
436
437 /* Find screen address. */
adamdunkels77e47062003-04-17 15:09:31 +0000438 asm("lda _ctk_hires_cursy");
adamdunkels7e4982c2003-03-19 16:26:18 +0000439 asm("asl");
440 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000441 asm("lda _ctk_hires_yscreenaddr,x");
adamdunkels7e4982c2003-03-19 16:26:18 +0000442 asm("sta ptr1");
adamdunkels77e47062003-04-17 15:09:31 +0000443 asm("lda _ctk_hires_yscreenaddr+1,x");
adamdunkels7e4982c2003-03-19 16:26:18 +0000444 asm("sta ptr1+1");
445
446 /* Turn off interrupts, prepare $01 to store color data in RAM under
447 I/O area. */
448 asm("sei");
449 asm("lda $01");
450 asm("sta _tmp01");
451 asm("and #$f8");
452 asm("sta $01");
453
454 /* Actually store color value in color RAM. */
adamdunkels77e47062003-04-17 15:09:31 +0000455 asm("ldy _ctk_hires_cursx");
456 asm("lda _ctk_hires_color");
adamdunkels7e4982c2003-03-19 16:26:18 +0000457 asm("sta (ptr1),y");
458 asm("iny");
459 asm("sta (ptr1),y");
460 asm("iny");
461 asm("sta (ptr1),y");
462 asm("tya");
463 asm("clc");
464 asm("adc #$26");
465 asm("tay");
adamdunkels77e47062003-04-17 15:09:31 +0000466 asm("lda _ctk_hires_color");
adamdunkels7e4982c2003-03-19 16:26:18 +0000467 asm("sta (ptr1),y");
468 asm("iny");
469 asm("sta (ptr1),y");
470 asm("iny");
471 asm("sta (ptr1),y");
472 asm("tya");
473 asm("clc");
474 asm("adc #$26");
475 asm("tay");
adamdunkels77e47062003-04-17 15:09:31 +0000476 asm("lda _ctk_hires_color");
adamdunkels7e4982c2003-03-19 16:26:18 +0000477 asm("sta (ptr1),y");
478 asm("iny");
479 asm("sta (ptr1),y");
480 asm("iny");
481 asm("sta (ptr1),y");
482
483
484
485 /* Find hires address. */
adamdunkels77e47062003-04-17 15:09:31 +0000486 asm("lda _ctk_hires_cursy");
adamdunkels7e4982c2003-03-19 16:26:18 +0000487 asm("asl");
488 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000489 asm("lda _ctk_hires_yhiresaddr,x");
adamdunkels7e4982c2003-03-19 16:26:18 +0000490 asm("sta ptr2");
adamdunkels77e47062003-04-17 15:09:31 +0000491 asm("lda _ctk_hires_yhiresaddr+1,x");
adamdunkels7e4982c2003-03-19 16:26:18 +0000492 asm("sta ptr2+1");
493
494 /* Add X coordinate to the hires address. */
495 asm("lda #0");
496 asm("sta ptr1+1");
adamdunkels77e47062003-04-17 15:09:31 +0000497 asm("lda _ctk_hires_cursx");
adamdunkels7e4982c2003-03-19 16:26:18 +0000498 asm("asl");
499 asm("rol ptr1+1");
500 asm("asl");
501 asm("rol ptr1+1");
502 asm("asl");
503 asm("rol ptr1+1");
504 asm("clc");
505 asm("adc ptr2");
506 asm("sta ptr2");
507 asm("lda ptr2+1");
508 asm("adc ptr1+1");
509 asm("sta ptr2+1");
510
511 asm("lda _tmpptr");
512 asm("sta ptr1");
513 asm("lda _tmpptr+1");
514 asm("sta ptr1+1");
515
516 asm("ldx #3");
517 asm("iconloop1:");
518 asm("ldy #0");
519 asm("iconloop2:");
520 asm("lda (ptr1),y");
521 asm("sta (ptr2),y");
522 asm("iny");
523 asm("cpy #$18");
524 asm("bne iconloop2");
525 asm("lda ptr1");
526 asm("clc");
527 asm("adc #$18");
528 asm("sta ptr1");
529 asm("lda ptr1+1");
530 asm("adc #0");
531 asm("sta ptr1+1");
532 asm("lda ptr2");
533 asm("clc");
534 asm("adc #$40");
535 asm("sta ptr2");
536 asm("lda ptr2+1");
537 asm("adc #1");
538 asm("sta ptr2+1");
539 asm("dex");
540 asm("bne iconloop1");
541
542
543
544 asm("lda _tmp01");
545 asm("sta $01");
546 asm("cli");
547}
548/*-----------------------------------------------------------------------------------*/
549static void
550draw_widget(struct ctk_widget *w,
551 unsigned char x, unsigned char y,
552 unsigned char clipy1, unsigned char clipy2,
553 unsigned char focus)
554{
555 unsigned char xpos, ypos, xscroll;
adamdunkels77e47062003-04-17 15:09:31 +0000556 unsigned char i;
adamdunkels7e4982c2003-03-19 16:26:18 +0000557 char c, *text;
558 unsigned char len;
559
560 xpos = x + w->x;
561 ypos = y + w->y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000562
563 switch(w->type) {
564 case CTK_WIDGET_SEPARATOR:
adamdunkels77e47062003-04-17 15:09:31 +0000565 hires_color(ctk_hires_theme.separatorcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000566 if(ypos >= clipy1 && ypos < clipy2) {
567 hires_chlinexy(xpos, ypos, w->w);
568 }
569 break;
570 case CTK_WIDGET_LABEL:
adamdunkels77e47062003-04-17 15:09:31 +0000571 hires_color(ctk_hires_theme.labelcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000572 text = w->widget.label.text;
573 for(i = 0; i < w->widget.label.h; ++i) {
574 if(ypos >= clipy1 && ypos < clipy2) {
575 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000576 ctk_hires_cputsn(text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000577 if(w->w - (hires_wherex() - xpos) > 0) {
adamdunkels77e47062003-04-17 15:09:31 +0000578 ctk_hires_cclear(w->w - (hires_wherex() - xpos));
adamdunkels7e4982c2003-03-19 16:26:18 +0000579 }
580 }
581 ++ypos;
582 text += w->w;
583 }
584 break;
585 case CTK_WIDGET_BUTTON:
586 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000587 hires_color(ctk_hires_theme.buttonleftcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000588 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000589 ctk_hires_draw_buttonleft();
590 hires_color(ctk_hires_theme.buttoncolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000591 hires_gotoxy(xpos + 1, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000592 ctk_hires_cputsn(w->widget.button.text, w->w);
593 hires_color(ctk_hires_theme.buttonrightcolors[focus]);
594 ctk_hires_draw_buttonright();
adamdunkels7e4982c2003-03-19 16:26:18 +0000595 }
596 break;
597 case CTK_WIDGET_HYPERLINK:
598 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000599 hires_color(ctk_hires_theme.hyperlinkcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000600 hires_underline(1);
601 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000602 ctk_hires_cputsn(w->widget.button.text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000603 hires_underline(0);
604 }
605 break;
606 case CTK_WIDGET_TEXTENTRY:
adamdunkels77e47062003-04-17 15:09:31 +0000607 hires_color(ctk_hires_theme.textentrycolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000608 text = w->widget.textentry.text;
609 if(focus & CTK_FOCUS_WIDGET &&
610 w->widget.textentry.state != CTK_TEXTENTRY_EDIT) {
611 hires_revers(1);
612 } else {
613 hires_revers(0);
614 }
615 xscroll = 0;
616 if(w->widget.textentry.xpos >= w->w - 1) {
617 xscroll = w->widget.textentry.xpos - w->w + 1;
618 }
adamdunkels77e47062003-04-17 15:09:31 +0000619 if(ypos >= clipy1 && ypos < clipy2) {
620 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) {
621 hires_revers(0);
622 hires_cputcxy(xpos, ypos, '>');
623 for(i = 0; i < w->w; ++i) {
624 c = text[i + xscroll];
625 if(i == w->widget.textentry.xpos - xscroll) {
626 hires_revers(1);
627 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000628 hires_revers(0);
629 }
adamdunkels77e47062003-04-17 15:09:31 +0000630 if(c == 0) {
631 ctk_hires_cputc(' ');
632 } else {
633 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000634 }
adamdunkels77e47062003-04-17 15:09:31 +0000635 hires_revers(0);
adamdunkels7e4982c2003-03-19 16:26:18 +0000636 }
adamdunkels77e47062003-04-17 15:09:31 +0000637 ctk_hires_cputc('<');
638 } else {
639 hires_cputcxy(xpos, ypos, '|');
640 /* hires_gotoxy(xpos + 1, ypos); */
641 ctk_hires_cputsn(text, w->w);
642 i = hires_wherex();
643 if(i - xpos - 1 < w->w) {
644 ctk_hires_cclear(w->w - (i - xpos) + 1);
645 }
646 ctk_hires_cputc('|');
adamdunkels7e4982c2003-03-19 16:26:18 +0000647 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000648 }
649 hires_revers(0);
650 break;
651 case CTK_WIDGET_ICON:
652 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000653 hires_color(ctk_hires_theme.iconcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000654 hires_gotoxy(xpos, ypos);
655 if(w->widget.icon.bitmap != NULL) {
656 draw_bitmap_icon(w->widget.icon.bitmap);
657 }
658 x = xpos;
659
660 len = strlen(w->widget.icon.title);
661 if(x + len >= SCREEN_WIDTH) {
662 x = SCREEN_WIDTH - len;
663 }
664
665 hires_gotoxy(x, ypos + 3);
adamdunkels77e47062003-04-17 15:09:31 +0000666 ctk_hires_cputsn(w->widget.icon.title, len);
adamdunkels7e4982c2003-03-19 16:26:18 +0000667 }
668 break;
adamdunkels77e47062003-04-17 15:09:31 +0000669 case CTK_WIDGET_BITMAP:
670 hires_color(ctk_hires_theme.bitmapcolors[focus]);
671 ctk_hires_bitmapptr = w->widget.bitmap.bitmap;
672 for(i = 0; i < w->widget.bitmap.h; ++i) {
673 if(ypos >= clipy1 && ypos < clipy2) {
674 hires_gotoxy(xpos, ypos);
675 ctk_hires_draw_bitmapline(w->w);
676 }
677 ctk_hires_bitmapptr += w->w * 8;
678 ++ypos;
679 }
680 break;
681
adamdunkels7e4982c2003-03-19 16:26:18 +0000682 default:
683 break;
684 }
685}
686/*-----------------------------------------------------------------------------------*/
687void
688ctk_draw_widget(struct ctk_widget *w,
689 unsigned char focus,
690 unsigned char clipy1,
691 unsigned char clipy2)
692{
693 struct ctk_window *win = w->window;
694 unsigned char posx, posy;
695
696 posx = win->x + 1;
697 posy = win->y + 2;
698
699 if(w == win->focused) {
700 focus |= CTK_FOCUS_WIDGET;
701 }
702
703 draw_widget(w, posx, posy,
704 clipy1, clipy2,
705 focus);
706}
707/*-----------------------------------------------------------------------------------*/
708void
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000709ctk_draw_clear_window(struct ctk_window *window,
710 unsigned char focus,
711 unsigned char clipy1,
712 unsigned char clipy2)
713{
714 unsigned char h;
715
adamdunkels77e47062003-04-17 15:09:31 +0000716 hires_color(ctk_hires_theme.windowcolors[focus]);
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000717
718 h = window->y + 2 + window->h;
719 /* Clear window contents. */
720 for(i = window->y + 2; i < h; ++i) {
721 if(i >= clipy1 && i < clipy2) {
722 hires_cclearxy(window->x + 1, i, window->w);
723 }
724 }
725}
726/*-----------------------------------------------------------------------------------*/
727void
adamdunkels7e4982c2003-03-19 16:26:18 +0000728ctk_draw_window(register struct ctk_window *window,
729 unsigned char focus,
730 unsigned char clipy1, unsigned char clipy2)
731{
732 register struct ctk_widget *w;
733
adamdunkels7e4982c2003-03-19 16:26:18 +0000734 x = window->x;
735 y = window->y + 1;
736
737 ++clipy2;
738
739 if(clipy2 < y) {
740 return;
741 }
adamdunkels77e47062003-04-17 15:09:31 +0000742
743 hires_color(ctk_hires_theme.windowcolors[focus+1]);
744
adamdunkels7e4982c2003-03-19 16:26:18 +0000745 x1 = x + 1;
746 y1 = y + 1;
747 x2 = x1 + window->w;
748 y2 = y1 + window->h;
749
adamdunkels77e47062003-04-17 15:09:31 +0000750
adamdunkels7e4982c2003-03-19 16:26:18 +0000751 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000752 ctk_hires_windowparams.w = window->w;
753 ctk_hires_windowparams.h = window->h;
adamdunkels7e4982c2003-03-19 16:26:18 +0000754 if(clipy1 < y) {
adamdunkels77e47062003-04-17 15:09:31 +0000755 ctk_hires_windowparams.clipy1 = 0;
adamdunkels7e4982c2003-03-19 16:26:18 +0000756 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000757 ctk_hires_windowparams.clipy1 = clipy1 - y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000758 }
adamdunkels77e47062003-04-17 15:09:31 +0000759 ctk_hires_windowparams.clipy2 = clipy2 - y;
760 ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1];
761 ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus];
762 ctk_hires_windowparams.title = window->title;
763 ctk_hires_windowparams.titlelen = window->titlelen;
adamdunkels7e4982c2003-03-19 16:26:18 +0000764
adamdunkels77e47062003-04-17 15:09:31 +0000765 ctk_hires_draw_windowborders();
adamdunkels7e4982c2003-03-19 16:26:18 +0000766
767#if 0
768 /* Draw window frame. */
769 if(y >= clipy1) {
770 windowulcorner(x, y);
771 windowupperborder(x + 3 + strlen(window->title),
772 y, window->w - 5 - strlen(window->title));
773 windowurcorner(x + window->w + 1, y);
774 hires_gotoxy(x + 1, y);
adamdunkels77e47062003-04-17 15:09:31 +0000775 hires_color(ctk_hires_theme.windowcolors[focus]);
776 ctk_hires_cputc(' ');
777 ctk_hires_cputsn(window->title, window->titlelen);
778 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000779 }
780
781 h = window->h;
782
783 if(clipy1 > y1) {
784 if(clipy1 - y1 < h) {
785 h = clipy1 - y1;
786 y1 = clipy1;
787 } else {
788 h = 0;
789 }
790 }
791
792 if(y1 + h >= clipy2) {
793 if(y1 >= clipy2) {
794 h = 0;
795 } else {
796 h = clipy2 - y1;
797 }
798 }
799
800 if(h == 0) {
801 return;
802 }
803
adamdunkels77e47062003-04-17 15:09:31 +0000804 hires_color(ctk_hires_theme.windowcolors[focus+1]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000805 windowsideborder(x, y1, h+1, 0xc0);
adamdunkels77e47062003-04-17 15:09:31 +0000806 hires_color(ctk_hires_theme.windowcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000807 windowsideborder(x2, y+1, h, 0x0b);
808
809 if(y + window->h >= clipy1 &&
810 y + window->h < clipy2) {
811 windowlowerborder(x1, y2, window->w);
812 }
813
814#endif /* 0 */
815
816 focus = focus & CTK_FOCUS_WINDOW;
817
818 /* Draw inactive widgets. */
819 for(w = window->inactive; w != NULL; w = w->next) {
820 draw_widget(w, x1, y1,
821 clipy1, clipy2,
822 focus);
823 }
824
825 /* Draw active widgets. */
826 for(w = window->active; w != NULL; w = w->next) {
827 wfocus = focus;
828 if(w == window->focused) {
829 wfocus |= CTK_FOCUS_WIDGET;
830 }
831 draw_widget(w, x1, y1,
832 clipy1, clipy2,
833 wfocus);
834 }
835}
836/*-----------------------------------------------------------------------------------*/
837void
838ctk_draw_dialog(register struct ctk_window *dialog)
839{
840 register struct ctk_widget *w;
841
adamdunkels77e47062003-04-17 15:09:31 +0000842 hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000843
844 /* x = (SCREEN_WIDTH - dialog->w) / 2;
845 y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */
846 x = dialog->x;
847 y = dialog->y + 1;
848
849
850 x1 = x + 1;
851 y1 = y + 1;
852 x2 = x1 + dialog->w;
853 y2 = y1 + dialog->h;
854
855
856 /* Draw dialog frame. */
857
858 hires_cvlinexy(x, y1,
859 dialog->h);
860 hires_cvlinexy(x2, y1,
861 dialog->h);
862
863 hires_chlinexy(x1, y,
864 dialog->w);
865 hires_chlinexy(x1, y2,
866 dialog->w);
867
868 hires_cputcxy(x, y, CH_ULCORNER);
869 hires_cputcxy(x, y2, CH_LLCORNER);
870 hires_cputcxy(x2, y, CH_URCORNER);
871 hires_cputcxy(x2, y2, CH_LRCORNER);
872
873
874 /* Clear window contents. */
875 for(i = y1; i < y2; ++i) {
876 hires_cclearxy(x1, i, dialog->w);
877 }
878
879 /* Clear dialog contents. */
880 for(i = y1; i < y2; ++i) {
881 hires_cclearxy(x1, i, dialog->w);
882 }
883
884 /* Draw inactive widgets. */
885 for(w = dialog->inactive; w != NULL; w = w->next) {
886 draw_widget(w, x1, y1,
887 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG);
888 }
889
890
891 /* Draw active widgets. */
892 for(w = dialog->active; w != NULL; w = w->next) {
893 wfocus = CTK_FOCUS_DIALOG;
894 if(w == dialog->focused) {
895 wfocus |= CTK_FOCUS_WIDGET;
896 }
897 draw_widget(w, x1, y1,
898 0, SCREEN_HEIGHT, wfocus);
899 }
900
901}
902/*-----------------------------------------------------------------------------------*/
903void
904ctk_draw_clear(unsigned char y1, unsigned char y2)
905{
906 for(i = y1; i < y2; ++i) {
907 clear_line(i);
908 }
909}
910/*-----------------------------------------------------------------------------------*/
911static void
912draw_menu(struct ctk_menu *m)
913{
914 unsigned char x, x2, y;
915
adamdunkels77e47062003-04-17 15:09:31 +0000916 hires_color(ctk_hires_theme.openmenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000917 x = hires_wherex();
adamdunkels77e47062003-04-17 15:09:31 +0000918 ctk_hires_cputsn(m->title, m->titlelen);
919 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000920 x2 = hires_wherex();
921 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
922 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
923 }
924 for(y = 0; y < m->nitems; ++y) {
925 if(y == m->active) {
adamdunkels77e47062003-04-17 15:09:31 +0000926 hires_color(ctk_hires_theme.activemenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000927 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000928 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000929 }
930 hires_gotoxy(x, y + 1);
931 if(m->items[y].title[0] == '-') {
adamdunkels77e47062003-04-17 15:09:31 +0000932 ctk_hires_chline(CTK_CONF_MENUWIDTH);
adamdunkels7e4982c2003-03-19 16:26:18 +0000933 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000934 ctk_hires_cputsn(m->items[y].title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000935 strlen(m->items[y].title));
936 }
adamdunkels77e47062003-04-17 15:09:31 +0000937 ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex());
adamdunkels7e4982c2003-03-19 16:26:18 +0000938 hires_revers(0);
939 }
940 hires_gotoxy(x2, 0);
adamdunkels77e47062003-04-17 15:09:31 +0000941 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000942}
943/*-----------------------------------------------------------------------------------*/
944void
945ctk_draw_menus(struct ctk_menus *menus)
946{
947 struct ctk_menu *m;
948
949 /* Draw menus */
adamdunkels77e47062003-04-17 15:09:31 +0000950
951 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000952 hires_gotoxy(0, 0);
953 hires_revers(0);
adamdunkels77e47062003-04-17 15:09:31 +0000954 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000955 for(m = menus->menus->next; m != NULL; m = m->next) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000956 if(m != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000957 ctk_hires_cputsn(m->title, m->titlelen);
958 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000959 } else {
960 draw_menu(m);
961 }
962 }
adamdunkels77e47062003-04-17 15:09:31 +0000963 ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() -
adamdunkels7e4982c2003-03-19 16:26:18 +0000964 strlen(menus->desktopmenu->title) - 1);
965
966 /* Draw desktopmenu */
967 if(menus->desktopmenu != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000968 ctk_hires_cputsn(menus->desktopmenu->title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000969 menus->desktopmenu->titlelen);
adamdunkels77e47062003-04-17 15:09:31 +0000970 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000971 } else {
972 draw_menu(menus->desktopmenu);
973 }
974
975}
976/*-----------------------------------------------------------------------------------*/
977unsigned char
978ctk_draw_height(void)
979{
980 return SCREEN_HEIGHT;
981}
982/*-----------------------------------------------------------------------------------*/
983unsigned char
984ctk_draw_width(void)
985{
986 return SCREEN_WIDTH;
987}
988/*-----------------------------------------------------------------------------------*/