blob: a9018f842b44bc1eb897957851518f852bff50cc [file] [log] [blame]
kthacker6de67752006-04-17 15:02:26 +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. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior
16 * written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * This file is part of the "ctk" console GUI toolkit for cc65
31 *
32 * $Id: ctk-hires-service.c,v 1.1 2006/04/17 15:02:31 kthacker Exp $
33 *
34 */
35
36#include "contiki-version.h"
37
38#include "ctk.h"
39#include "ctk-draw.h"
40#include "ctk-draw-service.h"
41#include "ctk-hires.h"
42#include "ctk-hires-asm.h"
43
44#include "ctk-hires-theme.h"
45
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
60unsigned char ctk_hires_cursx, ctk_hires_cursy;
61unsigned char ctk_hires_reversed;
62unsigned char ctk_hires_color;
63unsigned char ctk_hires_underline;
64
65/*static 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;
73/*static unsigned char h;*/
74static unsigned char wfocus;
75static unsigned char x1, y1, x2, y2;
76
77struct ctk_hires_windowparams ctk_hires_windowparams;
78unsigned char *ctk_hires_bitmapptr;
79
80/*unsigned char ctk_draw_windowborder_height = 1;
81unsigned char ctk_draw_windowborder_width = 1;
82unsigned char ctk_draw_windowtitle_height = 1;*/
83
84static void s_ctk_draw_clear(unsigned char y1, unsigned char y2);
85
86
87/*-----------------------------------------------------------------------------------*/
88/* Tables. */
89
90unsigned short ctk_hires_yscreenaddr[25] =
91 {0 * SCREEN_WIDTH + SCREENADDR, 1 * SCREEN_WIDTH + SCREENADDR,
92 2 * SCREEN_WIDTH + SCREENADDR, 3 * SCREEN_WIDTH + SCREENADDR,
93 4 * SCREEN_WIDTH + SCREENADDR, 5 * SCREEN_WIDTH + SCREENADDR,
94 6 * SCREEN_WIDTH + SCREENADDR, 7 * SCREEN_WIDTH + SCREENADDR,
95 8 * SCREEN_WIDTH + SCREENADDR, 9 * SCREEN_WIDTH + SCREENADDR,
96 10 * SCREEN_WIDTH + SCREENADDR, 11 * SCREEN_WIDTH + SCREENADDR,
97 12 * SCREEN_WIDTH + SCREENADDR, 13 * SCREEN_WIDTH + SCREENADDR,
98 14 * SCREEN_WIDTH + SCREENADDR, 15 * SCREEN_WIDTH + SCREENADDR,
99 16 * SCREEN_WIDTH + SCREENADDR, 17 * SCREEN_WIDTH + SCREENADDR,
100 18 * SCREEN_WIDTH + SCREENADDR, 19 * SCREEN_WIDTH + SCREENADDR,
101 20 * SCREEN_WIDTH + SCREENADDR, 21 * SCREEN_WIDTH + SCREENADDR,
102 22 * SCREEN_WIDTH + SCREENADDR, 23 * SCREEN_WIDTH + SCREENADDR,
103 24 * SCREEN_WIDTH + SCREENADDR};
104
105unsigned short ctk_hires_yhiresaddr[25] =
106 {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR,
107 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR,
108 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR,
109 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR,
110 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR,
111 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR,
112 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR,
113 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR,
114 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR,
115 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR,
116 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR,
117 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR,
118 24 * 320 + HIRESADDR};
119extern struct ctk_hires_theme ctk_hires_theme;
120struct ctk_hires_theme *ctk_hires_theme_ptr = &ctk_hires_theme;
121/*-----------------------------------------------------------------------------------*/
122#define hires_wherex() ctk_hires_cursx
123#define hires_revers(c) ctk_hires_reversed = c
124#define hires_color(c) ctk_hires_color = c
125#define hires_underline(c) ctk_hires_underline = c
126/*-----------------------------------------------------------------------------------*/
127static void __fastcall__
128hires_cvline(unsigned char length)
129{
130 static unsigned char i;
131
132 for(i = 0; i < length; ++i) {
133 ctk_hires_cputc('|');
134 --ctk_hires_cursx;
135 ++ctk_hires_cursy;
136 }
137}
138/*-----------------------------------------------------------------------------------*/
139static void __fastcall__
140hires_gotoxy(unsigned char x, unsigned char y)
141{
142 ctk_hires_cursx = x;
143 ctk_hires_cursy = y;
144}
145/*-----------------------------------------------------------------------------------*/
146static void __fastcall__
147hires_cclearxy(unsigned char x, unsigned char y, unsigned char length)
148{
149 hires_gotoxy(x, y);
150 ctk_hires_cclear(length);
151}
152/*-----------------------------------------------------------------------------------*/
153static void __fastcall__
154hires_chlinexy(unsigned char x, unsigned char y, unsigned char length)
155{
156 hires_gotoxy(x, y);
157 ctk_hires_chline(length);
158}
159/*-----------------------------------------------------------------------------------*/
160static void __fastcall__
161hires_cvlinexy(unsigned char x, unsigned char y, unsigned char length)
162{
163 hires_gotoxy(x, y);
164 hires_cvline(length);
165}
166/*-----------------------------------------------------------------------------------*/
167static void __fastcall__
168hires_cputcxy(unsigned char x, unsigned char y, char c)
169{
170 hires_gotoxy(x, y);
171 ctk_hires_cputc(c);
172}
173/*-----------------------------------------------------------------------------------*/
174#pragma optimize(push, off)
175static void
176clear_line(unsigned char line)
177{
178 lineptr = line;
179 asm("lda %v", lineptr);
180 asm("asl");
181 asm("tax");
182 asm("lda %v,x", ctk_hires_yhiresaddr);
183 asm("sta ptr2");
184 asm("lda %v+1,x", ctk_hires_yhiresaddr);
185 asm("sta ptr2+1");
186 asm("lda %v,x", ctk_hires_yscreenaddr);
187 asm("sta ptr1");
188 asm("lda %v+1,x", ctk_hires_yscreenaddr);
189 asm("sta ptr1+1");
190
191
192 asm("sei");
193 asm("lda $01");
194 asm("pha");
195 asm("lda #$30");
196 asm("sta $01");
197 asm("ldy #39");
198 asm("ldx %v", lineptr);
199 asm("lda %v+%w,x", ctk_hires_theme,
200 offsetof(struct ctk_hires_theme, backgroundpatterncolors));
201 asm("clearlineloop1:");
202 asm("sta (ptr1),y");
203 asm("dey");
204 asm("bpl clearlineloop1");
205 asm("pla");
206 asm("sta $01");
207 asm("cli");
208
209
210 asm("lda %v", lineptr);
211 /* asm("and #7");*/
212 asm("asl");
213 asm("asl");
214 asm("asl");
215 asm("tax");
216 asm("ldy #0");
217 asm("clearlineloop2:");
218 asm("lda %v+%w+0,x", ctk_hires_theme,
219 offsetof(struct ctk_hires_theme, backgroundpattern));
220 asm("sta (ptr2),y");
221 asm("iny");
222 asm("lda %v+%w+1,x", ctk_hires_theme,
223 offsetof(struct ctk_hires_theme, backgroundpattern));
224 asm("sta (ptr2),y");
225 asm("iny");
226 asm("lda %v+%w+2,x", ctk_hires_theme,
227 offsetof(struct ctk_hires_theme, backgroundpattern));
228 asm("sta (ptr2),y");
229 asm("iny");
230 asm("lda %v+%w+3,x", ctk_hires_theme,
231 offsetof(struct ctk_hires_theme, backgroundpattern));
232 asm("sta (ptr2),y");
233 asm("iny");
234 asm("lda %v+%w+4,x", ctk_hires_theme,
235 offsetof(struct ctk_hires_theme, backgroundpattern));
236 asm("sta (ptr2),y");
237 asm("iny");
238 asm("lda %v+%w+5,x", ctk_hires_theme,
239 offsetof(struct ctk_hires_theme, backgroundpattern));
240 asm("sta (ptr2),y");
241 asm("iny");
242 asm("lda %v+%w+6,x", ctk_hires_theme,
243 offsetof(struct ctk_hires_theme, backgroundpattern));
244 asm("sta (ptr2),y");
245 asm("iny");
246 asm("lda %v+%w+7,x", ctk_hires_theme,
247 offsetof(struct ctk_hires_theme, backgroundpattern));
248 asm("sta (ptr2),y");
249 asm("iny");
250 asm("bne clearlineloop2");
251
252 asm("inc ptr2+1");
253
254 asm("ldy #0");
255 asm("clearlineloop3:");
256 asm("lda %v+%w+0,x", ctk_hires_theme,
257 offsetof(struct ctk_hires_theme, backgroundpattern));
258 asm("sta (ptr2),y");
259 asm("iny");
260 asm("lda %v+%w+1,x", ctk_hires_theme,
261 offsetof(struct ctk_hires_theme, backgroundpattern));
262 asm("sta (ptr2),y");
263 asm("iny");
264 asm("lda %v+%w+2,x", ctk_hires_theme,
265 offsetof(struct ctk_hires_theme, backgroundpattern));
266 asm("sta (ptr2),y");
267 asm("iny");
268 asm("lda %v+%w+3,x", ctk_hires_theme,
269 offsetof(struct ctk_hires_theme, backgroundpattern));
270 asm("sta (ptr2),y");
271 asm("iny");
272 asm("lda %v+%w+4,x", ctk_hires_theme,
273 offsetof(struct ctk_hires_theme, backgroundpattern));
274 asm("sta (ptr2),y");
275 asm("iny");
276 asm("lda %v+%w+5,x", ctk_hires_theme,
277 offsetof(struct ctk_hires_theme, backgroundpattern));
278 asm("sta (ptr2),y");
279 asm("iny");
280 asm("lda %v+%w+6,x", ctk_hires_theme,
281 offsetof(struct ctk_hires_theme, backgroundpattern));
282 asm("sta (ptr2),y");
283 asm("iny");
284 asm("lda %v+%w+7,x", ctk_hires_theme,
285 offsetof(struct ctk_hires_theme, backgroundpattern));
286 asm("sta (ptr2),y");
287 asm("iny");
288 asm("cpy #$40");
289 asm("bne clearlineloop3");
290
291
292 if(lineptr == 24) {
293 hires_color(ctk_hires_theme.backgroundpatterncolors[24]);
294 hires_gotoxy(0, 24);
295 ctk_hires_cputsn(CONTIKI_VERSION_STRING,
296 sizeof(CONTIKI_VERSION_STRING) - 1);
297 }
298}
299#pragma optimize(pop)
300/*-----------------------------------------------------------------------------------*/
301#pragma optimize(push, off)
302static void
303nmi2(void)
304{
305 asm("pla");
306 asm("sta $01");
307 asm("pla");
308 asm("rti");
309}
310#pragma optimize(pop)
311/*-----------------------------------------------------------------------------------*/
312#pragma optimize(push, off)
313static void
314nmi(void)
315{
316 asm("sei");
317 asm("pha");
318 asm("inc $d020");
319 asm("lda $01");
320 asm("pha");
321 asm("lda #$36");
322 asm("sta $01");
323 asm("lda #>_nmi2");
324 asm("pha");
325 asm("lda #<_nmi2");
326 asm("pha");
327 asm("php");
328 asm("jmp ($0318)");
329
330 nmi2();
331}
332#pragma optimize(pop)
333/*-----------------------------------------------------------------------------------*/
334#pragma optimize(push, off)
335static void
336setup_nmi(void)
337{
338 asm("lda #<_nmi");
339 asm("sta $fffa");
340 asm("lda #>_nmi");
341 asm("sta $fffb");
342 return;
343 nmi();
344}
345#pragma optimize(pop)
346/*-----------------------------------------------------------------------------------*/
347#pragma optimize(push, off)
348static void
349s_ctk_draw_init(void)
350{
351 unsigned char i, *ptr1, *ptr2;
352
353
354 setup_nmi();
355
356 /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for
357 hires/colors. */
358 VIC.ctrl1 = 0x3b; /* $D011 */
359 VIC.addr = 0x78; /* $D018 */
360 VIC.ctrl2 = 0xc8; /* $D016 */
361 CIA2.pra = 0x00; /* $DD00 */
362
363 VIC.bordercolor = ctk_hires_theme.bordercolor; /* $D020 */
364 VIC.bgcolor0 = ctk_hires_theme.screencolor; /* $D021 */
365
366 /* Fill color memory. */
367 asm("sei");
368 asm("lda $01");
369 asm("pha");
370 asm("lda #$30");
371 asm("sta $01");
372 asm("ldx #0");
373 asm("lda #$c0");
374 asm("fillcolorloop:");
375 asm("sta $dc00,x");
376 asm("sta $dd00,x");
377 asm("sta $de00,x");
378 asm("sta $df00,x");
379 asm("inx");
380 asm("bne fillcolorloop");
381
382 /* Setup sprite pointers */
383 asm("ldx #$fd");
384 asm("stx $dff8");
385 asm("inx");
386 asm("stx $dff9");
387 asm("pla");
388 asm("sta $01");
389 asm("cli");
390
391 /* Fill hires memory with 0. */
392
393 asm("lda $fd");
394 asm("pha");
395 asm("lda $fe");
396 asm("pha");
397 asm("lda #0");
398 asm("sta $fd");
399 asm("lda #$e0");
400 asm("sta $fe");
401 asm("ldy #0");
402 asm("lda #0");
403 asm("clrscrnloop:");
404 asm("lda #$55");
405 asm("sta ($fd),y");
406 asm("iny");
407 asm("lda #$aa");
408 asm("sta ($fd),y");
409 asm("iny");
410 asm("bne clrscrnloop");
411 asm("inc $fe");
412 asm("lda $fe");
413 asm("cmp #$ff");
414 asm("bne clrscrnloop");
415
416 asm("ldy #$00");
417 asm("clrscrnloop2:");
418 asm("lda #$55");
419 asm("sta $ff00,y");
420 asm("iny");
421 asm("lda #$aa");
422 asm("sta $ff00,y");
423 asm("iny");
424 asm("cpy #$40");
425 asm("bne clrscrnloop2");
426
427
428 asm("pla");
429 asm("sta $fe");
430 asm("pla");
431 asm("sta $fd");
432
433
434 s_ctk_draw_clear(0, SCREEN_HEIGHT);
435
436 /* Setup mouse pointer sprite. */
437 asm("lda %v+%w", ctk_hires_theme,
438 offsetof(struct ctk_hires_theme, pointermaskcolor));
439 asm("sta $d027");
440 asm("lda %v+%w", ctk_hires_theme,
441 offsetof(struct ctk_hires_theme, pointercolor));
442 asm("sta $d028");
443
444 ptr1 = ctk_hires_theme.pointer;
445 ptr2 = (unsigned char *)0xff40;
446
447 for(i = 0; i < 0x80; ++i) {
448 *ptr2++ = *ptr1++;
449 }
450
451 return;
452}
453#pragma optimize(pop)
454/*-----------------------------------------------------------------------------------*/
455static void __fastcall__
456draw_widget(register struct ctk_widget *w,
457 unsigned char x, unsigned char y,
458 unsigned char clipy1, unsigned char clipy2,
459 unsigned char afocus)
460{
461 static unsigned char xpos, ypos, xscroll;
462 static unsigned char i;
463 static char c;
464 static unsigned char len;
465 static unsigned char tmp;
466 static unsigned char yclipped;
467 static unsigned char focus;
468 char *text;
469
470 xpos = x + w->x;
471 ypos = y + w->y;
472
473 yclipped = 0;
474 if(ypos >= clipy1 && ypos < clipy2) {
475 yclipped = 1;
476 }
477 focus = afocus;
478
479
480 switch(w->type) {
481 case CTK_WIDGET_SEPARATOR:
482 hires_color(ctk_hires_theme.separatorcolors[focus]);
483 if(yclipped) {
484 hires_chlinexy(xpos, ypos, w->w);
485 }
486 break;
487 case CTK_WIDGET_LABEL:
488 hires_color(ctk_hires_theme.labelcolors[focus]);
489 text = w->widget.label.text;
490 for(i = 0; i < w->h; ++i) {
491 if(ypos >= clipy1 && ypos < clipy2) {
492 hires_gotoxy(xpos, ypos);
493 ctk_hires_cputsn(text, w->w);
494 tmp = w->w - (hires_wherex() - xpos);
495 if(tmp > 0) {
496 ctk_hires_cclear(tmp);
497 }
498 }
499 ++ypos;
500 text += w->w;
501 }
502 break;
503 case CTK_WIDGET_BUTTON:
504 if(yclipped) {
505 hires_color(ctk_hires_theme.buttonleftcolors[focus]);
506 hires_gotoxy(xpos, ypos);
507 ctk_hires_draw_buttonleft();
508 hires_color(ctk_hires_theme.buttoncolors[focus]);
509 hires_gotoxy(xpos + 1, ypos);
510 ctk_hires_cputsn(w->widget.button.text, w->w);
511 hires_color(ctk_hires_theme.buttonrightcolors[focus]);
512 ctk_hires_draw_buttonright();
513 }
514 break;
515 case CTK_WIDGET_HYPERLINK:
516 if(yclipped) {
517 hires_color(ctk_hires_theme.hyperlinkcolors[focus]);
518 hires_underline(1);
519 hires_gotoxy(xpos, ypos);
520 ctk_hires_cputsn(w->widget.button.text, w->w);
521 hires_underline(0);
522 }
523 break;
524 case CTK_WIDGET_TEXTENTRY:
525 if(yclipped) {
526 hires_color(ctk_hires_theme.textentrycolors[focus]);
527
528 if((focus & CTK_FOCUS_WIDGET) &&
529 w->widget.textentry.state != CTK_TEXTENTRY_EDIT) {
530 hires_revers(1);
531 } else {
532 hires_revers(0);
533 }
534 xscroll = 0;
535 tmp = w->w - 1;
536 if(w->widget.textentry.xpos >= tmp) {
537 xscroll = w->widget.textentry.xpos - tmp;
538 }
539 text = w->widget.textentry.text;
540 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) {
541 hires_revers(0);
542 hires_cputcxy(xpos, ypos, '>');
543 text += xscroll;
544 for(i = 0; i < w->w; ++i) {
545 c = *text;
546 if(i == w->widget.textentry.xpos - xscroll) {
547 hires_revers(1);
548 } else {
549 hires_revers(0);
550 }
551 if(c == 0) {
552 ctk_hires_cputc(' ');
553 } else {
554 ctk_hires_cputc(c);
555 }
556 hires_revers(0);
557 ++text;
558 }
559 ctk_hires_cputc('<');
560 } else {
561 hires_cputcxy(xpos, ypos, '|');
562 /* hires_gotoxy(xpos + 1, ypos); */
563 ctk_hires_cputsn(text, w->w);
564 i = hires_wherex();
565 tmp = i - xpos - 1;
566 if(tmp < w->w) {
567 ctk_hires_cclear(w->w - tmp);
568 }
569 ctk_hires_cputc('|');
570 }
571 }
572 hires_revers(0);
573 break;
574 case CTK_WIDGET_ICON:
575 if(yclipped) {
576 hires_color(ctk_hires_theme.iconcolors[focus]);
577
578 x = xpos;
579 len = strlen(w->widget.icon.title);
580 if(x + len >= SCREEN_WIDTH) {
581 x = SCREEN_WIDTH - len;
582 }
583
584 tmp = ypos + 3;
585
586 if(tmp < clipy2) {
587 hires_gotoxy(x, tmp);
588 ctk_hires_cputsn(w->widget.icon.title, len);
589 }
590
591 hires_gotoxy(xpos, ypos);
592 if(w->widget.icon.bitmap != NULL) {
593 ctk_hires_bitmapptr = w->widget.icon.bitmap;
594 for(i = 0; i < 3; ++i) {
595 if(ypos >= clipy1 && ypos < clipy2) {
596 hires_gotoxy(xpos, ypos);
597 ctk_hires_draw_bitmapline(3);
598 }
599 ctk_hires_bitmapptr += 3 * 8;
600 ++ypos;
601 }
602
603 /* draw_bitmap_icon(w->widget.icon.bitmap);*/
604 }
605
606 }
607 break;
608 case CTK_WIDGET_BITMAP:
609 hires_color(ctk_hires_theme.bitmapcolors[focus]);
610 ctk_hires_bitmapptr = w->widget.bitmap.bitmap;
611 for(i = 0; i < w->h; ++i) {
612 if(ypos >= clipy1 && ypos < clipy2) {
613 hires_gotoxy(xpos, ypos);
614 ctk_hires_draw_bitmapline(w->w);
615 }
616 ctk_hires_bitmapptr += w->w * 8;
617 ++ypos;
618 }
619 break;
620
621 default:
622 break;
623 }
624}
625/*-----------------------------------------------------------------------------------*/
626static void
627s_ctk_draw_widget(struct ctk_widget *w,
628 unsigned char focus,
629 unsigned char clipy1,
630 unsigned char clipy2)
631{
632 struct ctk_window *win = w->window;
633 unsigned char posx, posy;
634
635 posx = win->x + 1;
636 posy = win->y + 2;
637
638 if(w == win->focused) {
639 focus |= CTK_FOCUS_WIDGET;
640 }
641
642 draw_widget(w, posx, posy,
643 clipy1, clipy2,
644 focus);
645}
646/*-----------------------------------------------------------------------------------*/
647static void
648s_ctk_draw_clear_window(register struct ctk_window *window,
649 unsigned char focus,
650 unsigned char clipy1,
651 unsigned char clipy2)
652{
653 static unsigned char h;
654
655 hires_color(ctk_hires_theme.windowcolors[focus]);
656
657 h = window->y + 2 + window->h;
658 /* Clear window contents. */
659 for(i = window->y + 2; i < h; ++i) {
660 if(i >= clipy1 && i <= clipy2) {
661 hires_cclearxy(window->x + 1, i, window->w);
662 }
663 }
664}
665/*-----------------------------------------------------------------------------------*/
666static void
667s_ctk_draw_window(register struct ctk_window *window,
668 unsigned char focus,
669 unsigned char clipy1, unsigned char clipy2)
670{
671 register struct ctk_widget *w;
672
673 x = window->x;
674 y = window->y + 1;
675
676 ++clipy2;
677
678 if(clipy2 <= y) {
679 return;
680 }
681
682 /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/
683
684 x1 = x + 1;
685 y1 = y + 1;
686 /* x2 = x1 + window->w;
687 y2 = y1 + window->h;*/
688
689 hires_gotoxy(x, y);
690 ctk_hires_windowparams.w = window->w;
691 ctk_hires_windowparams.h = window->h;
692 if(clipy1 < y) {
693 ctk_hires_windowparams.clipy1 = 0;
694 } else {
695 ctk_hires_windowparams.clipy1 = clipy1 - y;
696 }
697 ctk_hires_windowparams.clipy2 = clipy2 - y;
698 ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1];
699 ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus];
700 ctk_hires_windowparams.title = window->title;
701 ctk_hires_windowparams.titlelen = window->titlelen;
702
703 if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 &&
704 ctk_hires_windowparams.clipy2 > 0) {
705 ctk_hires_draw_windowborders();
706 }
707
708 focus = focus & CTK_FOCUS_WINDOW;
709
710 /* Draw inactive widgets. */
711 for(w = window->inactive; w != NULL; w = w->next) {
712 draw_widget(w, x1, y1,
713 clipy1, clipy2,
714 focus);
715 }
716
717 /* Draw active widgets. */
718 for(w = window->active; w != NULL; w = w->next) {
719 wfocus = focus;
720 if(w == window->focused) {
721 wfocus |= CTK_FOCUS_WIDGET;
722 }
723 draw_widget(w, x1, y1,
724 clipy1, clipy2,
725 wfocus);
726 }
727}
728/*-----------------------------------------------------------------------------------*/
729static void
730s_ctk_draw_dialog(register struct ctk_window *dialog)
731{
732 register struct ctk_widget *w;
733
734 hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]);
735
736 /* x = (SCREEN_WIDTH - dialog->w) / 2;
737 y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */
738 x = dialog->x;
739 y = dialog->y + 1;
740
741
742 x1 = x + 1;
743 y1 = y + 1;
744 x2 = x1 + dialog->w;
745 y2 = y1 + dialog->h;
746
747
748 /* Draw dialog frame. */
749
750 hires_cvlinexy(x, y1, dialog->h);
751 hires_cvlinexy(x2, y1, dialog->h);
752
753 hires_chlinexy(x1, y, dialog->w);
754 hires_chlinexy(x1, y2, dialog->w);
755
756 hires_cputcxy(x, y, CH_ULCORNER);
757 hires_cputcxy(x, y2, CH_LLCORNER);
758 hires_cputcxy(x2, y, CH_URCORNER);
759 hires_cputcxy(x2, y2, CH_LRCORNER);
760
761
762 /* Clear window contents. */
763 for(i = y1; i < y2; ++i) {
764 hires_cclearxy(x1, i, dialog->w);
765 }
766
767 /* Draw inactive widgets. */
768 for(w = dialog->inactive; w != NULL; w = w->next) {
769 draw_widget(w, x1, y1,
770 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG);
771 }
772
773
774 /* Draw active widgets. */
775 for(w = dialog->active; w != NULL; w = w->next) {
776 wfocus = CTK_FOCUS_DIALOG;
777 if(w == dialog->focused) {
778 wfocus |= CTK_FOCUS_WIDGET;
779 }
780 draw_widget(w, x1, y1,
781 0, SCREEN_HEIGHT, wfocus);
782 }
783
784}
785/*-----------------------------------------------------------------------------------*/
786static void
787s_ctk_draw_clear(unsigned char y1, unsigned char y2)
788{
789 for(i = y1; i < y2; ++i) {
790 clear_line(i);
791 }
792}
793/*-----------------------------------------------------------------------------------*/
794static void
795draw_menu(register struct ctk_menu *m)
796{
797 static unsigned char x, x2, y;
798
799 hires_color(ctk_hires_theme.openmenucolor);
800 x = hires_wherex();
801 ctk_hires_cputsn(m->title, m->titlelen);
802 ctk_hires_cputc(' ');
803 x2 = hires_wherex();
804 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
805 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
806 }
807 for(y = 0; y < m->nitems; ++y) {
808 if(y == m->active) {
809 hires_color(ctk_hires_theme.activemenucolor);
810 } else {
811 hires_color(ctk_hires_theme.menucolor);
812 }
813 hires_gotoxy(x, y + 1);
814 if(m->items[y].title[0] == '-') {
815 ctk_hires_chline(CTK_CONF_MENUWIDTH);
816 } else {
817 ctk_hires_cputsn(m->items[y].title,
818 strlen(m->items[y].title));
819 }
820 ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex());
821 hires_revers(0);
822 }
823 hires_gotoxy(x2, 0);
824 hires_color(ctk_hires_theme.menucolor);
825}
826/*-----------------------------------------------------------------------------------*/
827static void
828s_ctk_draw_menus(struct ctk_menus *menus)
829{
830 struct ctk_menu *m;
831
832 /* Draw menus */
833 hires_color(ctk_hires_theme.menucolor);
834 hires_gotoxy(0, 0);
835 hires_revers(0);
836 ctk_hires_cputc(' ');
837 for(m = menus->menus->next; m != NULL; m = m->next) {
838 if(m != menus->open) {
839 ctk_hires_cputsn(m->title, m->titlelen);
840 ctk_hires_cputc(' ');
841 } else {
842 draw_menu(m);
843 }
844 }
845 ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() -
846 strlen(menus->desktopmenu->title) - 1);
847
848 /* Draw desktopmenu */
849 if(menus->desktopmenu != menus->open) {
850 ctk_hires_cputsn(menus->desktopmenu->title,
851 menus->desktopmenu->titlelen);
852 ctk_hires_cputc(' ');
853 } else {
854 draw_menu(menus->desktopmenu);
855 }
856
857}
858/*-----------------------------------------------------------------------------------*/
859static unsigned char
860s_ctk_draw_height(void)
861{
862 return SCREEN_HEIGHT;
863}
864/*-----------------------------------------------------------------------------------*/
865static unsigned char
866s_ctk_draw_width(void)
867{
868 return SCREEN_WIDTH;
869}
870/*-----------------------------------------------------------------------------------*/
871static unsigned short
872s_ctk_mouse_xtoc(unsigned short x)
873{
874 return x / 8;
875}
876/*-----------------------------------------------------------------------------------*/
877static unsigned short
878s_ctk_mouse_ytoc(unsigned short y)
879{
880 return y / 8;
881}
882/*-----------------------------------------------------------------------------------*/
883static const struct ctk_draw_service_interface interface =
884 {CTK_DRAW_SERVICE_VERSION,
885 1,
886 1,
887 1,
888 s_ctk_draw_init,
889 s_ctk_draw_clear,
890 s_ctk_draw_clear_window,
891 s_ctk_draw_window,
892 s_ctk_draw_dialog,
893 s_ctk_draw_widget,
894 s_ctk_draw_menus,
895 s_ctk_draw_width,
896 s_ctk_draw_height,
897 s_ctk_mouse_xtoc,
898 s_ctk_mouse_ytoc,
899 };
900
901EK_EVENTHANDLER(eventhandler, ev, data);
902EK_PROCESS(proc, CTK_DRAW_SERVICE_NAME ": hires", EK_PRIO_NORMAL,
903 eventhandler, NULL, (void *)&interface);
904
905/*--------------------------------------------------------------------------*/
906LOADER_INIT_FUNC(ctk_conio_service_init, arg)
907{
908 ek_service_start(CTK_DRAW_SERVICE_NAME, &proc);
909}
910/*--------------------------------------------------------------------------*/
911EK_EVENTHANDLER(eventhandler, ev, data)
912{
913 EK_EVENTHANDLER_ARGS(ev, data);
914
915 switch(ev) {
916 case EK_EVENT_INIT:
917 case EK_EVENT_REPLACE:
918 s_ctk_draw_init();
919 ctk_restore();
920 break;
921 case EK_EVENT_REQUEST_REPLACE:
922 VIC.ctrl1 = 0x1b; /* $D011 */
923 VIC.addr = 0x17; /* $D018 */
924 VIC.ctrl2 = 0xc8; /* $D016 */
925 CIA2.pra = 0x03; /* $DD00 */
926 ek_replace((struct ek_proc *)data, NULL);
927 LOADER_UNLOAD();
928 break;
929 }
930}
931/*--------------------------------------------------------------------------*/