blob: 5725d2e2fa79f264b223a763bca82a5bec6fe14e [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 *
adamdunkelsd7422082003-08-05 13:57:01 +000035 * $Id: ctk-hires.c,v 1.4 2003/08/05 13:57:01 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
adamdunkelsd7422082003-08-05 13:57:01 +0000552draw_widget(register struct ctk_widget *w,
adamdunkels7e4982c2003-03-19 16:26:18 +0000553 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;
adamdunkels41343612003-07-31 23:23:25 +0000575 for(i = 0; i < w->h; ++i) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000576 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;
adamdunkels41343612003-07-31 23:23:25 +0000688 for(i = 0; i < w->h; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000689 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
adamdunkelsd7422082003-08-05 13:57:01 +0000725ctk_draw_clear_window(register struct ctk_window *window,
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000726 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;
adamdunkels7e4982c2003-03-19 16:26:18 +0000749 x = window->x;
750 y = window->y + 1;
751
752 ++clipy2;
753
adamdunkels9e046b42003-04-24 17:05:41 +0000754 if(clipy2 <= y) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000755 return;
756 }
adamdunkels77e47062003-04-17 15:09:31 +0000757
adamdunkels9e046b42003-04-24 17:05:41 +0000758 /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/
adamdunkels77e47062003-04-17 15:09:31 +0000759
adamdunkels7e4982c2003-03-19 16:26:18 +0000760 x1 = x + 1;
761 y1 = y + 1;
adamdunkels9e046b42003-04-24 17:05:41 +0000762 /* x2 = x1 + window->w;
763 y2 = y1 + window->h;*/
adamdunkels77e47062003-04-17 15:09:31 +0000764
adamdunkels7e4982c2003-03-19 16:26:18 +0000765 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000766 ctk_hires_windowparams.w = window->w;
767 ctk_hires_windowparams.h = window->h;
adamdunkels7e4982c2003-03-19 16:26:18 +0000768 if(clipy1 < y) {
adamdunkels77e47062003-04-17 15:09:31 +0000769 ctk_hires_windowparams.clipy1 = 0;
adamdunkels7e4982c2003-03-19 16:26:18 +0000770 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000771 ctk_hires_windowparams.clipy1 = clipy1 - y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000772 }
adamdunkels77e47062003-04-17 15:09:31 +0000773 ctk_hires_windowparams.clipy2 = clipy2 - y;
774 ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1];
775 ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus];
776 ctk_hires_windowparams.title = window->title;
777 ctk_hires_windowparams.titlelen = window->titlelen;
adamdunkels7e4982c2003-03-19 16:26:18 +0000778
adamdunkels9e046b42003-04-24 17:05:41 +0000779 if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 &&
780 ctk_hires_windowparams.clipy2 > 0) {
781 ctk_hires_draw_windowborders();
adamdunkels7e4982c2003-03-19 16:26:18 +0000782 }
adamdunkels41343612003-07-31 23:23:25 +0000783
adamdunkels7e4982c2003-03-19 16:26:18 +0000784 focus = focus & CTK_FOCUS_WINDOW;
785
786 /* Draw inactive widgets. */
787 for(w = window->inactive; w != NULL; w = w->next) {
788 draw_widget(w, x1, y1,
789 clipy1, clipy2,
790 focus);
791 }
792
793 /* Draw active widgets. */
794 for(w = window->active; w != NULL; w = w->next) {
795 wfocus = focus;
796 if(w == window->focused) {
797 wfocus |= CTK_FOCUS_WIDGET;
798 }
799 draw_widget(w, x1, y1,
800 clipy1, clipy2,
801 wfocus);
802 }
803}
804/*-----------------------------------------------------------------------------------*/
805void
806ctk_draw_dialog(register struct ctk_window *dialog)
807{
808 register struct ctk_widget *w;
809
adamdunkels77e47062003-04-17 15:09:31 +0000810 hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000811
812 /* x = (SCREEN_WIDTH - dialog->w) / 2;
813 y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */
814 x = dialog->x;
815 y = dialog->y + 1;
816
817
818 x1 = x + 1;
819 y1 = y + 1;
820 x2 = x1 + dialog->w;
821 y2 = y1 + dialog->h;
822
823
824 /* Draw dialog frame. */
825
826 hires_cvlinexy(x, y1,
827 dialog->h);
828 hires_cvlinexy(x2, y1,
829 dialog->h);
830
831 hires_chlinexy(x1, y,
832 dialog->w);
833 hires_chlinexy(x1, y2,
834 dialog->w);
835
836 hires_cputcxy(x, y, CH_ULCORNER);
837 hires_cputcxy(x, y2, CH_LLCORNER);
838 hires_cputcxy(x2, y, CH_URCORNER);
839 hires_cputcxy(x2, y2, CH_LRCORNER);
840
841
842 /* Clear window contents. */
843 for(i = y1; i < y2; ++i) {
844 hires_cclearxy(x1, i, dialog->w);
845 }
846
847 /* Clear dialog contents. */
848 for(i = y1; i < y2; ++i) {
849 hires_cclearxy(x1, i, dialog->w);
850 }
851
852 /* Draw inactive widgets. */
853 for(w = dialog->inactive; w != NULL; w = w->next) {
854 draw_widget(w, x1, y1,
855 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG);
856 }
857
858
859 /* Draw active widgets. */
860 for(w = dialog->active; w != NULL; w = w->next) {
861 wfocus = CTK_FOCUS_DIALOG;
862 if(w == dialog->focused) {
863 wfocus |= CTK_FOCUS_WIDGET;
864 }
865 draw_widget(w, x1, y1,
866 0, SCREEN_HEIGHT, wfocus);
867 }
868
869}
870/*-----------------------------------------------------------------------------------*/
871void
872ctk_draw_clear(unsigned char y1, unsigned char y2)
873{
874 for(i = y1; i < y2; ++i) {
875 clear_line(i);
876 }
877}
878/*-----------------------------------------------------------------------------------*/
879static void
adamdunkelsd7422082003-08-05 13:57:01 +0000880draw_menu(register struct ctk_menu *m)
adamdunkels7e4982c2003-03-19 16:26:18 +0000881{
882 unsigned char x, x2, y;
883
adamdunkels77e47062003-04-17 15:09:31 +0000884 hires_color(ctk_hires_theme.openmenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000885 x = hires_wherex();
adamdunkels77e47062003-04-17 15:09:31 +0000886 ctk_hires_cputsn(m->title, m->titlelen);
887 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000888 x2 = hires_wherex();
889 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
890 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
891 }
892 for(y = 0; y < m->nitems; ++y) {
893 if(y == m->active) {
adamdunkels77e47062003-04-17 15:09:31 +0000894 hires_color(ctk_hires_theme.activemenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000895 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000896 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000897 }
898 hires_gotoxy(x, y + 1);
899 if(m->items[y].title[0] == '-') {
adamdunkels77e47062003-04-17 15:09:31 +0000900 ctk_hires_chline(CTK_CONF_MENUWIDTH);
adamdunkels7e4982c2003-03-19 16:26:18 +0000901 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000902 ctk_hires_cputsn(m->items[y].title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000903 strlen(m->items[y].title));
904 }
adamdunkels77e47062003-04-17 15:09:31 +0000905 ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex());
adamdunkels7e4982c2003-03-19 16:26:18 +0000906 hires_revers(0);
907 }
908 hires_gotoxy(x2, 0);
adamdunkels77e47062003-04-17 15:09:31 +0000909 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000910}
911/*-----------------------------------------------------------------------------------*/
912void
913ctk_draw_menus(struct ctk_menus *menus)
914{
915 struct ctk_menu *m;
adamdunkels41343612003-07-31 23:23:25 +0000916
adamdunkels7e4982c2003-03-19 16:26:18 +0000917 /* Draw menus */
adamdunkels77e47062003-04-17 15:09:31 +0000918 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000919 hires_gotoxy(0, 0);
920 hires_revers(0);
adamdunkels77e47062003-04-17 15:09:31 +0000921 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000922 for(m = menus->menus->next; m != NULL; m = m->next) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000923 if(m != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000924 ctk_hires_cputsn(m->title, m->titlelen);
925 ctk_hires_cputc(' ');
adamdunkels41343612003-07-31 23:23:25 +0000926 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000927 draw_menu(m);
928 }
929 }
adamdunkels77e47062003-04-17 15:09:31 +0000930 ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() -
adamdunkels7e4982c2003-03-19 16:26:18 +0000931 strlen(menus->desktopmenu->title) - 1);
932
933 /* Draw desktopmenu */
934 if(menus->desktopmenu != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000935 ctk_hires_cputsn(menus->desktopmenu->title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000936 menus->desktopmenu->titlelen);
adamdunkels77e47062003-04-17 15:09:31 +0000937 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000938 } else {
939 draw_menu(menus->desktopmenu);
940 }
941
942}
943/*-----------------------------------------------------------------------------------*/
944unsigned char
945ctk_draw_height(void)
946{
947 return SCREEN_HEIGHT;
948}
949/*-----------------------------------------------------------------------------------*/
950unsigned char
951ctk_draw_width(void)
952{
953 return SCREEN_WIDTH;
954}
955/*-----------------------------------------------------------------------------------*/