blob: ad01bc38efaa1be9c1cb60e1d1b60e4699bf9d32 [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 *
adamdunkels9e046b42003-04-24 17:05:41 +000035 * $Id: ctk-hires.c,v 1.2 2003/04/24 17:05:41 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/*-----------------------------------------------------------------------------------*/
adamdunkels9e046b42003-04-24 17:05:41 +0000432#if 0
adamdunkels7e4982c2003-03-19 16:26:18 +0000433static void
434draw_bitmap_icon(unsigned char *bitmap)
435{
436 tmpptr = bitmap;
437
438 /* Find screen address. */
adamdunkels77e47062003-04-17 15:09:31 +0000439 asm("lda _ctk_hires_cursy");
adamdunkels7e4982c2003-03-19 16:26:18 +0000440 asm("asl");
441 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000442 asm("lda _ctk_hires_yscreenaddr,x");
adamdunkels7e4982c2003-03-19 16:26:18 +0000443 asm("sta ptr1");
adamdunkels77e47062003-04-17 15:09:31 +0000444 asm("lda _ctk_hires_yscreenaddr+1,x");
adamdunkels7e4982c2003-03-19 16:26:18 +0000445 asm("sta ptr1+1");
446
447 /* Turn off interrupts, prepare $01 to store color data in RAM under
448 I/O area. */
449 asm("sei");
450 asm("lda $01");
451 asm("sta _tmp01");
452 asm("and #$f8");
453 asm("sta $01");
454
455 /* Actually store color value in color RAM. */
adamdunkels77e47062003-04-17 15:09:31 +0000456 asm("ldy _ctk_hires_cursx");
457 asm("lda _ctk_hires_color");
adamdunkels7e4982c2003-03-19 16:26:18 +0000458 asm("sta (ptr1),y");
459 asm("iny");
460 asm("sta (ptr1),y");
461 asm("iny");
462 asm("sta (ptr1),y");
463 asm("tya");
464 asm("clc");
465 asm("adc #$26");
466 asm("tay");
adamdunkels77e47062003-04-17 15:09:31 +0000467 asm("lda _ctk_hires_color");
adamdunkels7e4982c2003-03-19 16:26:18 +0000468 asm("sta (ptr1),y");
469 asm("iny");
470 asm("sta (ptr1),y");
471 asm("iny");
472 asm("sta (ptr1),y");
473 asm("tya");
474 asm("clc");
475 asm("adc #$26");
476 asm("tay");
adamdunkels77e47062003-04-17 15:09:31 +0000477 asm("lda _ctk_hires_color");
adamdunkels7e4982c2003-03-19 16:26:18 +0000478 asm("sta (ptr1),y");
479 asm("iny");
480 asm("sta (ptr1),y");
481 asm("iny");
482 asm("sta (ptr1),y");
483
484
485
486 /* Find hires address. */
adamdunkels77e47062003-04-17 15:09:31 +0000487 asm("lda _ctk_hires_cursy");
adamdunkels7e4982c2003-03-19 16:26:18 +0000488 asm("asl");
489 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000490 asm("lda _ctk_hires_yhiresaddr,x");
adamdunkels7e4982c2003-03-19 16:26:18 +0000491 asm("sta ptr2");
adamdunkels77e47062003-04-17 15:09:31 +0000492 asm("lda _ctk_hires_yhiresaddr+1,x");
adamdunkels7e4982c2003-03-19 16:26:18 +0000493 asm("sta ptr2+1");
494
495 /* Add X coordinate to the hires address. */
496 asm("lda #0");
497 asm("sta ptr1+1");
adamdunkels77e47062003-04-17 15:09:31 +0000498 asm("lda _ctk_hires_cursx");
adamdunkels7e4982c2003-03-19 16:26:18 +0000499 asm("asl");
500 asm("rol ptr1+1");
501 asm("asl");
502 asm("rol ptr1+1");
503 asm("asl");
504 asm("rol ptr1+1");
505 asm("clc");
506 asm("adc ptr2");
507 asm("sta ptr2");
508 asm("lda ptr2+1");
509 asm("adc ptr1+1");
510 asm("sta ptr2+1");
511
512 asm("lda _tmpptr");
513 asm("sta ptr1");
514 asm("lda _tmpptr+1");
515 asm("sta ptr1+1");
516
517 asm("ldx #3");
518 asm("iconloop1:");
519 asm("ldy #0");
520 asm("iconloop2:");
521 asm("lda (ptr1),y");
522 asm("sta (ptr2),y");
523 asm("iny");
524 asm("cpy #$18");
525 asm("bne iconloop2");
526 asm("lda ptr1");
527 asm("clc");
528 asm("adc #$18");
529 asm("sta ptr1");
530 asm("lda ptr1+1");
531 asm("adc #0");
532 asm("sta ptr1+1");
533 asm("lda ptr2");
534 asm("clc");
535 asm("adc #$40");
536 asm("sta ptr2");
537 asm("lda ptr2+1");
538 asm("adc #1");
539 asm("sta ptr2+1");
540 asm("dex");
541 asm("bne iconloop1");
542
543
544
545 asm("lda _tmp01");
546 asm("sta $01");
adamdunkels9e046b42003-04-24 17:05:41 +0000547 asm("cli");
adamdunkels7e4982c2003-03-19 16:26:18 +0000548}
adamdunkels9e046b42003-04-24 17:05:41 +0000549#endif /* 0 */
adamdunkels7e4982c2003-03-19 16:26:18 +0000550/*-----------------------------------------------------------------------------------*/
551static void
552draw_widget(struct ctk_widget *w,
553 unsigned char x, unsigned char y,
554 unsigned char clipy1, unsigned char clipy2,
555 unsigned char focus)
556{
557 unsigned char xpos, ypos, xscroll;
adamdunkels77e47062003-04-17 15:09:31 +0000558 unsigned char i;
adamdunkels7e4982c2003-03-19 16:26:18 +0000559 char c, *text;
560 unsigned char len;
561
562 xpos = x + w->x;
563 ypos = y + w->y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000564
565 switch(w->type) {
566 case CTK_WIDGET_SEPARATOR:
adamdunkels77e47062003-04-17 15:09:31 +0000567 hires_color(ctk_hires_theme.separatorcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000568 if(ypos >= clipy1 && ypos < clipy2) {
569 hires_chlinexy(xpos, ypos, w->w);
570 }
571 break;
572 case CTK_WIDGET_LABEL:
adamdunkels77e47062003-04-17 15:09:31 +0000573 hires_color(ctk_hires_theme.labelcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000574 text = w->widget.label.text;
575 for(i = 0; i < w->widget.label.h; ++i) {
576 if(ypos >= clipy1 && ypos < clipy2) {
577 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000578 ctk_hires_cputsn(text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000579 if(w->w - (hires_wherex() - xpos) > 0) {
adamdunkels77e47062003-04-17 15:09:31 +0000580 ctk_hires_cclear(w->w - (hires_wherex() - xpos));
adamdunkels7e4982c2003-03-19 16:26:18 +0000581 }
582 }
583 ++ypos;
584 text += w->w;
585 }
586 break;
587 case CTK_WIDGET_BUTTON:
588 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000589 hires_color(ctk_hires_theme.buttonleftcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000590 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000591 ctk_hires_draw_buttonleft();
592 hires_color(ctk_hires_theme.buttoncolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000593 hires_gotoxy(xpos + 1, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000594 ctk_hires_cputsn(w->widget.button.text, w->w);
595 hires_color(ctk_hires_theme.buttonrightcolors[focus]);
596 ctk_hires_draw_buttonright();
adamdunkels7e4982c2003-03-19 16:26:18 +0000597 }
598 break;
599 case CTK_WIDGET_HYPERLINK:
600 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000601 hires_color(ctk_hires_theme.hyperlinkcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000602 hires_underline(1);
603 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000604 ctk_hires_cputsn(w->widget.button.text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000605 hires_underline(0);
606 }
607 break;
608 case CTK_WIDGET_TEXTENTRY:
adamdunkels77e47062003-04-17 15:09:31 +0000609 hires_color(ctk_hires_theme.textentrycolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000610 text = w->widget.textentry.text;
611 if(focus & CTK_FOCUS_WIDGET &&
612 w->widget.textentry.state != CTK_TEXTENTRY_EDIT) {
613 hires_revers(1);
614 } else {
615 hires_revers(0);
616 }
617 xscroll = 0;
618 if(w->widget.textentry.xpos >= w->w - 1) {
619 xscroll = w->widget.textentry.xpos - w->w + 1;
620 }
adamdunkels77e47062003-04-17 15:09:31 +0000621 if(ypos >= clipy1 && ypos < clipy2) {
622 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) {
623 hires_revers(0);
624 hires_cputcxy(xpos, ypos, '>');
625 for(i = 0; i < w->w; ++i) {
626 c = text[i + xscroll];
627 if(i == w->widget.textentry.xpos - xscroll) {
628 hires_revers(1);
629 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000630 hires_revers(0);
631 }
adamdunkels77e47062003-04-17 15:09:31 +0000632 if(c == 0) {
633 ctk_hires_cputc(' ');
634 } else {
635 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000636 }
adamdunkels77e47062003-04-17 15:09:31 +0000637 hires_revers(0);
adamdunkels7e4982c2003-03-19 16:26:18 +0000638 }
adamdunkels77e47062003-04-17 15:09:31 +0000639 ctk_hires_cputc('<');
640 } else {
641 hires_cputcxy(xpos, ypos, '|');
642 /* hires_gotoxy(xpos + 1, ypos); */
643 ctk_hires_cputsn(text, w->w);
644 i = hires_wherex();
645 if(i - xpos - 1 < w->w) {
646 ctk_hires_cclear(w->w - (i - xpos) + 1);
647 }
648 ctk_hires_cputc('|');
adamdunkels7e4982c2003-03-19 16:26:18 +0000649 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000650 }
651 hires_revers(0);
652 break;
653 case CTK_WIDGET_ICON:
654 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000655 hires_color(ctk_hires_theme.iconcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000656
adamdunkels9e046b42003-04-24 17:05:41 +0000657 x = xpos;
adamdunkels7e4982c2003-03-19 16:26:18 +0000658 len = strlen(w->widget.icon.title);
659 if(x + len >= SCREEN_WIDTH) {
660 x = SCREEN_WIDTH - len;
661 }
662
adamdunkels9e046b42003-04-24 17:05:41 +0000663 if(ypos + 3 < clipy2) {
664 hires_gotoxy(x, ypos + 3);
665 ctk_hires_cputsn(w->widget.icon.title, len);
666 }
667
668 hires_gotoxy(xpos, ypos);
669 if(w->widget.icon.bitmap != NULL) {
670 ctk_hires_bitmapptr = w->widget.icon.bitmap;
671 for(i = 0; i < 3; ++i) {
672 if(ypos >= clipy1 && ypos < clipy2) {
673 hires_gotoxy(xpos, ypos);
674 ctk_hires_draw_bitmapline(3);
675 }
676 ctk_hires_bitmapptr += 3 * 8;
677 ++ypos;
678 }
679
680 /* draw_bitmap_icon(w->widget.icon.bitmap);*/
681 }
682
adamdunkels7e4982c2003-03-19 16:26:18 +0000683 }
684 break;
adamdunkels77e47062003-04-17 15:09:31 +0000685 case CTK_WIDGET_BITMAP:
686 hires_color(ctk_hires_theme.bitmapcolors[focus]);
687 ctk_hires_bitmapptr = w->widget.bitmap.bitmap;
688 for(i = 0; i < w->widget.bitmap.h; ++i) {
689 if(ypos >= clipy1 && ypos < clipy2) {
690 hires_gotoxy(xpos, ypos);
691 ctk_hires_draw_bitmapline(w->w);
692 }
693 ctk_hires_bitmapptr += w->w * 8;
694 ++ypos;
695 }
696 break;
697
adamdunkels7e4982c2003-03-19 16:26:18 +0000698 default:
699 break;
700 }
701}
702/*-----------------------------------------------------------------------------------*/
703void
704ctk_draw_widget(struct ctk_widget *w,
705 unsigned char focus,
706 unsigned char clipy1,
707 unsigned char clipy2)
708{
709 struct ctk_window *win = w->window;
710 unsigned char posx, posy;
711
712 posx = win->x + 1;
713 posy = win->y + 2;
714
715 if(w == win->focused) {
716 focus |= CTK_FOCUS_WIDGET;
717 }
718
719 draw_widget(w, posx, posy,
720 clipy1, clipy2,
721 focus);
722}
723/*-----------------------------------------------------------------------------------*/
724void
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000725ctk_draw_clear_window(struct ctk_window *window,
726 unsigned char focus,
727 unsigned char clipy1,
728 unsigned char clipy2)
729{
730 unsigned char h;
731
adamdunkels77e47062003-04-17 15:09:31 +0000732 hires_color(ctk_hires_theme.windowcolors[focus]);
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000733
734 h = window->y + 2 + window->h;
735 /* Clear window contents. */
736 for(i = window->y + 2; i < h; ++i) {
adamdunkels9e046b42003-04-24 17:05:41 +0000737 if(i >= clipy1 && i <= clipy2) {
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000738 hires_cclearxy(window->x + 1, i, window->w);
739 }
740 }
741}
742/*-----------------------------------------------------------------------------------*/
743void
adamdunkels7e4982c2003-03-19 16:26:18 +0000744ctk_draw_window(register struct ctk_window *window,
745 unsigned char focus,
746 unsigned char clipy1, unsigned char clipy2)
747{
748 register struct ctk_widget *w;
749
adamdunkels7e4982c2003-03-19 16:26:18 +0000750 x = window->x;
751 y = window->y + 1;
752
753 ++clipy2;
754
adamdunkels9e046b42003-04-24 17:05:41 +0000755 if(clipy2 <= y) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000756 return;
757 }
adamdunkels77e47062003-04-17 15:09:31 +0000758
adamdunkels9e046b42003-04-24 17:05:41 +0000759 /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/
adamdunkels77e47062003-04-17 15:09:31 +0000760
adamdunkels7e4982c2003-03-19 16:26:18 +0000761 x1 = x + 1;
762 y1 = y + 1;
adamdunkels9e046b42003-04-24 17:05:41 +0000763 /* x2 = x1 + window->w;
764 y2 = y1 + window->h;*/
adamdunkels77e47062003-04-17 15:09:31 +0000765
adamdunkels7e4982c2003-03-19 16:26:18 +0000766 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000767 ctk_hires_windowparams.w = window->w;
768 ctk_hires_windowparams.h = window->h;
adamdunkels7e4982c2003-03-19 16:26:18 +0000769 if(clipy1 < y) {
adamdunkels77e47062003-04-17 15:09:31 +0000770 ctk_hires_windowparams.clipy1 = 0;
adamdunkels7e4982c2003-03-19 16:26:18 +0000771 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000772 ctk_hires_windowparams.clipy1 = clipy1 - y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000773 }
adamdunkels77e47062003-04-17 15:09:31 +0000774 ctk_hires_windowparams.clipy2 = clipy2 - y;
775 ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1];
776 ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus];
777 ctk_hires_windowparams.title = window->title;
778 ctk_hires_windowparams.titlelen = window->titlelen;
adamdunkels7e4982c2003-03-19 16:26:18 +0000779
adamdunkels9e046b42003-04-24 17:05:41 +0000780 if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 &&
781 ctk_hires_windowparams.clipy2 > 0) {
782 ctk_hires_draw_windowborders();
adamdunkels7e4982c2003-03-19 16:26:18 +0000783 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000784
785 focus = focus & CTK_FOCUS_WINDOW;
786
787 /* Draw inactive widgets. */
788 for(w = window->inactive; w != NULL; w = w->next) {
789 draw_widget(w, x1, y1,
790 clipy1, clipy2,
791 focus);
792 }
793
794 /* Draw active widgets. */
795 for(w = window->active; w != NULL; w = w->next) {
796 wfocus = focus;
797 if(w == window->focused) {
798 wfocus |= CTK_FOCUS_WIDGET;
799 }
800 draw_widget(w, x1, y1,
801 clipy1, clipy2,
802 wfocus);
803 }
804}
805/*-----------------------------------------------------------------------------------*/
806void
807ctk_draw_dialog(register struct ctk_window *dialog)
808{
809 register struct ctk_widget *w;
810
adamdunkels77e47062003-04-17 15:09:31 +0000811 hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000812
813 /* x = (SCREEN_WIDTH - dialog->w) / 2;
814 y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */
815 x = dialog->x;
816 y = dialog->y + 1;
817
818
819 x1 = x + 1;
820 y1 = y + 1;
821 x2 = x1 + dialog->w;
822 y2 = y1 + dialog->h;
823
824
825 /* Draw dialog frame. */
826
827 hires_cvlinexy(x, y1,
828 dialog->h);
829 hires_cvlinexy(x2, y1,
830 dialog->h);
831
832 hires_chlinexy(x1, y,
833 dialog->w);
834 hires_chlinexy(x1, y2,
835 dialog->w);
836
837 hires_cputcxy(x, y, CH_ULCORNER);
838 hires_cputcxy(x, y2, CH_LLCORNER);
839 hires_cputcxy(x2, y, CH_URCORNER);
840 hires_cputcxy(x2, y2, CH_LRCORNER);
841
842
843 /* Clear window contents. */
844 for(i = y1; i < y2; ++i) {
845 hires_cclearxy(x1, i, dialog->w);
846 }
847
848 /* Clear dialog contents. */
849 for(i = y1; i < y2; ++i) {
850 hires_cclearxy(x1, i, dialog->w);
851 }
852
853 /* Draw inactive widgets. */
854 for(w = dialog->inactive; w != NULL; w = w->next) {
855 draw_widget(w, x1, y1,
856 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG);
857 }
858
859
860 /* Draw active widgets. */
861 for(w = dialog->active; w != NULL; w = w->next) {
862 wfocus = CTK_FOCUS_DIALOG;
863 if(w == dialog->focused) {
864 wfocus |= CTK_FOCUS_WIDGET;
865 }
866 draw_widget(w, x1, y1,
867 0, SCREEN_HEIGHT, wfocus);
868 }
869
870}
871/*-----------------------------------------------------------------------------------*/
872void
873ctk_draw_clear(unsigned char y1, unsigned char y2)
874{
875 for(i = y1; i < y2; ++i) {
876 clear_line(i);
877 }
878}
879/*-----------------------------------------------------------------------------------*/
880static void
881draw_menu(struct ctk_menu *m)
882{
883 unsigned char x, x2, y;
884
adamdunkels77e47062003-04-17 15:09:31 +0000885 hires_color(ctk_hires_theme.openmenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000886 x = hires_wherex();
adamdunkels77e47062003-04-17 15:09:31 +0000887 ctk_hires_cputsn(m->title, m->titlelen);
888 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000889 x2 = hires_wherex();
890 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
891 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
892 }
893 for(y = 0; y < m->nitems; ++y) {
894 if(y == m->active) {
adamdunkels77e47062003-04-17 15:09:31 +0000895 hires_color(ctk_hires_theme.activemenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000896 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000897 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000898 }
899 hires_gotoxy(x, y + 1);
900 if(m->items[y].title[0] == '-') {
adamdunkels77e47062003-04-17 15:09:31 +0000901 ctk_hires_chline(CTK_CONF_MENUWIDTH);
adamdunkels7e4982c2003-03-19 16:26:18 +0000902 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000903 ctk_hires_cputsn(m->items[y].title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000904 strlen(m->items[y].title));
905 }
adamdunkels77e47062003-04-17 15:09:31 +0000906 ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex());
adamdunkels7e4982c2003-03-19 16:26:18 +0000907 hires_revers(0);
908 }
909 hires_gotoxy(x2, 0);
adamdunkels77e47062003-04-17 15:09:31 +0000910 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000911}
912/*-----------------------------------------------------------------------------------*/
913void
914ctk_draw_menus(struct ctk_menus *menus)
915{
916 struct ctk_menu *m;
917
918 /* Draw menus */
adamdunkels77e47062003-04-17 15:09:31 +0000919
920 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000921 hires_gotoxy(0, 0);
922 hires_revers(0);
adamdunkels77e47062003-04-17 15:09:31 +0000923 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000924 for(m = menus->menus->next; m != NULL; m = m->next) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000925 if(m != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000926 ctk_hires_cputsn(m->title, m->titlelen);
927 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000928 } else {
929 draw_menu(m);
930 }
931 }
adamdunkels77e47062003-04-17 15:09:31 +0000932 ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() -
adamdunkels7e4982c2003-03-19 16:26:18 +0000933 strlen(menus->desktopmenu->title) - 1);
934
935 /* Draw desktopmenu */
936 if(menus->desktopmenu != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000937 ctk_hires_cputsn(menus->desktopmenu->title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000938 menus->desktopmenu->titlelen);
adamdunkels77e47062003-04-17 15:09:31 +0000939 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000940 } else {
941 draw_menu(menus->desktopmenu);
942 }
943
944}
945/*-----------------------------------------------------------------------------------*/
946unsigned char
947ctk_draw_height(void)
948{
949 return SCREEN_HEIGHT;
950}
951/*-----------------------------------------------------------------------------------*/
952unsigned char
953ctk_draw_width(void)
954{
955 return SCREEN_WIDTH;
956}
957/*-----------------------------------------------------------------------------------*/