blob: a1a1ee68657d5d6710cc91be13e9dd2186e91427 [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.
adamdunkels0a08fda2004-07-04 18:33:07 +000014 * 3. The name of the author may not be used to endorse or promote
adamdunkels7e4982c2003-03-19 16:26:18 +000015 * 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 *
adamdunkels0a08fda2004-07-04 18:33:07 +000032 * $Id: ctk-hires.c,v 1.11 2004/07/04 18:33:08 adamdunkels Exp $
adamdunkels7e4982c2003-03-19 16:26:18 +000033 *
34 */
adamdunkels77e47062003-04-17 15:09:31 +000035
adamdunkels10367222004-02-24 09:50:58 +000036#include "contiki-version.h"
37
adamdunkels7e4982c2003-03-19 16:26:18 +000038#include "ctk.h"
39#include "ctk-draw.h"
adamdunkels77e47062003-04-17 15:09:31 +000040#include "ctk-hires.h"
41#include "ctk-hires-asm.h"
42
43#include "ctk-hires-theme.h"
adamdunkels7e4982c2003-03-19 16:26:18 +000044
45#include <string.h>
46
47#ifndef NULL
48#define NULL (void *)0
49#endif /* NULL */
50
51#define SCREEN_HEIGHT 25
52#define SCREEN_WIDTH 40
53
54#define SCREENADDR 0xdc00
55#define HIRESADDR 0xe000
56
57static unsigned char lineptr;
58
adamdunkels77e47062003-04-17 15:09:31 +000059unsigned char ctk_hires_cursx, ctk_hires_cursy;
60unsigned char ctk_hires_reversed;
61unsigned char ctk_hires_color;
62unsigned char ctk_hires_underline;
adamdunkels7e4982c2003-03-19 16:26:18 +000063
adamdunkelsc1c84be2003-08-09 13:26:22 +000064/*static unsigned char cchar;
adamdunkels7e4982c2003-03-19 16:26:18 +000065
66static unsigned char tmp01;
67static unsigned char tmph, tmpl, tmpborder;
adamdunkelsc1c84be2003-08-09 13:26:22 +000068static unsigned char *tmpptr;*/
adamdunkels7e4982c2003-03-19 16:26:18 +000069
70
71static unsigned char x, y, i;
adamdunkelsc1c84be2003-08-09 13:26:22 +000072/*static unsigned char h;*/
adamdunkels7e4982c2003-03-19 16:26:18 +000073static unsigned char wfocus;
74static unsigned char x1, y1, x2, y2;
75
adamdunkels77e47062003-04-17 15:09:31 +000076struct ctk_hires_windowparams ctk_hires_windowparams;
77unsigned char *ctk_hires_bitmapptr;
adamdunkels97c19b72003-08-24 22:29:41 +000078
adamdunkels0a08fda2004-07-04 18:33:07 +000079unsigned char ctk_draw_windowborder_height = 1;
80unsigned char ctk_draw_windowborder_width = 1;
81unsigned char ctk_draw_windowtitle_height = 1;
82
adamdunkels7e4982c2003-03-19 16:26:18 +000083/*-----------------------------------------------------------------------------------*/
84/* Tables. */
85
adamdunkels77e47062003-04-17 15:09:31 +000086unsigned short ctk_hires_yscreenaddr[25] =
adamdunkels7e4982c2003-03-19 16:26:18 +000087 {0 * SCREEN_WIDTH + SCREENADDR, 1 * SCREEN_WIDTH + SCREENADDR,
88 2 * SCREEN_WIDTH + SCREENADDR, 3 * SCREEN_WIDTH + SCREENADDR,
89 4 * SCREEN_WIDTH + SCREENADDR, 5 * SCREEN_WIDTH + SCREENADDR,
90 6 * SCREEN_WIDTH + SCREENADDR, 7 * SCREEN_WIDTH + SCREENADDR,
91 8 * SCREEN_WIDTH + SCREENADDR, 9 * SCREEN_WIDTH + SCREENADDR,
92 10 * SCREEN_WIDTH + SCREENADDR, 11 * SCREEN_WIDTH + SCREENADDR,
93 12 * SCREEN_WIDTH + SCREENADDR, 13 * SCREEN_WIDTH + SCREENADDR,
94 14 * SCREEN_WIDTH + SCREENADDR, 15 * SCREEN_WIDTH + SCREENADDR,
95 16 * SCREEN_WIDTH + SCREENADDR, 17 * SCREEN_WIDTH + SCREENADDR,
96 18 * SCREEN_WIDTH + SCREENADDR, 19 * SCREEN_WIDTH + SCREENADDR,
97 20 * SCREEN_WIDTH + SCREENADDR, 21 * SCREEN_WIDTH + SCREENADDR,
98 22 * SCREEN_WIDTH + SCREENADDR, 23 * SCREEN_WIDTH + SCREENADDR,
99 24 * SCREEN_WIDTH + SCREENADDR};
100
adamdunkels77e47062003-04-17 15:09:31 +0000101unsigned short ctk_hires_yhiresaddr[25] =
adamdunkels7e4982c2003-03-19 16:26:18 +0000102 {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR,
103 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR,
104 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR,
105 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR,
106 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR,
107 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR,
108 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR,
109 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR,
110 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR,
111 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR,
112 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR,
113 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR,
114 24 * 320 + HIRESADDR};
adamdunkels77e47062003-04-17 15:09:31 +0000115extern struct ctk_hires_theme ctk_hires_theme;
116struct ctk_hires_theme *ctk_hires_theme_ptr = &ctk_hires_theme;
adamdunkels7e4982c2003-03-19 16:26:18 +0000117/*-----------------------------------------------------------------------------------*/
adamdunkels77e47062003-04-17 15:09:31 +0000118#define hires_wherex() ctk_hires_cursx
119#define hires_revers(c) ctk_hires_reversed = c
120#define hires_color(c) ctk_hires_color = c
121#define hires_underline(c) ctk_hires_underline = c
adamdunkels7e4982c2003-03-19 16:26:18 +0000122/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000123static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000124hires_cvline(unsigned char length)
125{
adamdunkels23b30d52003-08-15 18:46:25 +0000126 static unsigned char i;
adamdunkels7e4982c2003-03-19 16:26:18 +0000127
128 for(i = 0; i < length; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000129 ctk_hires_cputc('|');
130 --ctk_hires_cursx;
131 ++ctk_hires_cursy;
adamdunkels7e4982c2003-03-19 16:26:18 +0000132 }
133}
134/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000135static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000136hires_gotoxy(unsigned char x, unsigned char y)
137{
adamdunkels77e47062003-04-17 15:09:31 +0000138 ctk_hires_cursx = x;
139 ctk_hires_cursy = y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000140}
141/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000142static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000143hires_cclearxy(unsigned char x, unsigned char y, unsigned char length)
144{
145 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000146 ctk_hires_cclear(length);
adamdunkels7e4982c2003-03-19 16:26:18 +0000147}
148/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000149static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000150hires_chlinexy(unsigned char x, unsigned char y, unsigned char length)
151{
152 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000153 ctk_hires_chline(length);
adamdunkels7e4982c2003-03-19 16:26:18 +0000154}
155/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000156static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000157hires_cvlinexy(unsigned char x, unsigned char y, unsigned char length)
158{
159 hires_gotoxy(x, y);
160 hires_cvline(length);
161}
162/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000163static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000164hires_cputcxy(unsigned char x, unsigned char y, char c)
165{
166 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000167 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000168}
169/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000170static void
adamdunkels7e4982c2003-03-19 16:26:18 +0000171clear_line(unsigned char line)
172{
173 lineptr = line;
adamdunkels77e47062003-04-17 15:09:31 +0000174 asm("lda %v", lineptr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000175 asm("asl");
176 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000177 asm("lda %v,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000178 asm("sta ptr2");
adamdunkels77e47062003-04-17 15:09:31 +0000179 asm("lda %v+1,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000180 asm("sta ptr2+1");
adamdunkels77e47062003-04-17 15:09:31 +0000181 asm("lda %v,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000182 asm("sta ptr1");
adamdunkels77e47062003-04-17 15:09:31 +0000183 asm("lda %v+1,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000184 asm("sta ptr1+1");
185
186
187 asm("sei");
188 asm("lda $01");
189 asm("pha");
190 asm("lda #$30");
191 asm("sta $01");
192 asm("ldy #39");
adamdunkels77e47062003-04-17 15:09:31 +0000193 asm("ldx %v", lineptr);
194 asm("lda %v+%w,x", ctk_hires_theme,
195 offsetof(struct ctk_hires_theme, backgroundpatterncolors));
adamdunkels7e4982c2003-03-19 16:26:18 +0000196 asm("clearlineloop1:");
197 asm("sta (ptr1),y");
198 asm("dey");
199 asm("bpl clearlineloop1");
200 asm("pla");
201 asm("sta $01");
202 asm("cli");
203
204
adamdunkels77e47062003-04-17 15:09:31 +0000205 asm("lda %v", lineptr);
206 /* asm("and #7");*/
adamdunkels7e4982c2003-03-19 16:26:18 +0000207 asm("asl");
adamdunkels77e47062003-04-17 15:09:31 +0000208 asm("asl");
adamdunkels7e4982c2003-03-19 16:26:18 +0000209 asm("asl");
210 asm("tax");
211 asm("ldy #0");
212 asm("clearlineloop2:");
adamdunkels77e47062003-04-17 15:09:31 +0000213 asm("lda %v+%w+0,x", ctk_hires_theme,
214 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000215 asm("sta (ptr2),y");
216 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000217 asm("lda %v+%w+1,x", ctk_hires_theme,
218 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000219 asm("sta (ptr2),y");
220 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000221 asm("lda %v+%w+2,x", ctk_hires_theme,
222 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000223 asm("sta (ptr2),y");
224 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000225 asm("lda %v+%w+3,x", ctk_hires_theme,
226 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000227 asm("sta (ptr2),y");
228 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000229 asm("lda %v+%w+4,x", ctk_hires_theme,
230 offsetof(struct ctk_hires_theme, backgroundpattern));
231 asm("sta (ptr2),y");
232 asm("iny");
233 asm("lda %v+%w+5,x", ctk_hires_theme,
234 offsetof(struct ctk_hires_theme, backgroundpattern));
235 asm("sta (ptr2),y");
236 asm("iny");
237 asm("lda %v+%w+6,x", ctk_hires_theme,
238 offsetof(struct ctk_hires_theme, backgroundpattern));
239 asm("sta (ptr2),y");
240 asm("iny");
241 asm("lda %v+%w+7,x", ctk_hires_theme,
242 offsetof(struct ctk_hires_theme, backgroundpattern));
243 asm("sta (ptr2),y");
244 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000245 asm("bne clearlineloop2");
246
247 asm("inc ptr2+1");
248
249 asm("ldy #0");
250 asm("clearlineloop3:");
adamdunkels77e47062003-04-17 15:09:31 +0000251 asm("lda %v+%w+0,x", ctk_hires_theme,
252 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000253 asm("sta (ptr2),y");
254 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000255 asm("lda %v+%w+1,x", ctk_hires_theme,
256 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000257 asm("sta (ptr2),y");
258 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000259 asm("lda %v+%w+2,x", ctk_hires_theme,
260 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000261 asm("sta (ptr2),y");
262 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000263 asm("lda %v+%w+3,x", ctk_hires_theme,
264 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000265 asm("sta (ptr2),y");
266 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000267 asm("lda %v+%w+4,x", ctk_hires_theme,
268 offsetof(struct ctk_hires_theme, backgroundpattern));
269 asm("sta (ptr2),y");
270 asm("iny");
271 asm("lda %v+%w+5,x", ctk_hires_theme,
272 offsetof(struct ctk_hires_theme, backgroundpattern));
273 asm("sta (ptr2),y");
274 asm("iny");
275 asm("lda %v+%w+6,x", ctk_hires_theme,
276 offsetof(struct ctk_hires_theme, backgroundpattern));
277 asm("sta (ptr2),y");
278 asm("iny");
279 asm("lda %v+%w+7,x", ctk_hires_theme,
280 offsetof(struct ctk_hires_theme, backgroundpattern));
281 asm("sta (ptr2),y");
282 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000283 asm("cpy #$40");
284 asm("bne clearlineloop3");
adamdunkels1de1f842004-02-16 20:57:36 +0000285
adamdunkels7e4982c2003-03-19 16:26:18 +0000286
adamdunkels1de1f842004-02-16 20:57:36 +0000287 if(lineptr == 24) {
adamdunkels1de1f842004-02-16 20:57:36 +0000288 hires_color(ctk_hires_theme.backgroundpatterncolors[24]);
289 hires_gotoxy(0, 24);
290 ctk_hires_cputsn(CONTIKI_VERSION_STRING,
291 sizeof(CONTIKI_VERSION_STRING) - 1);
292 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000293}
294/*-----------------------------------------------------------------------------------*/
295static void
296nmi2(void)
297{
298 asm("pla");
299 asm("sta $01");
300 asm("pla");
301 asm("rti");
302}
303/*-----------------------------------------------------------------------------------*/
304static void
305nmi(void)
306{
307 asm("sei");
308 asm("pha");
309 asm("inc $d020");
310 asm("lda $01");
311 asm("pha");
312 asm("lda #$36");
313 asm("sta $01");
314 asm("lda #>_nmi2");
315 asm("pha");
316 asm("lda #<_nmi2");
317 asm("pha");
318 asm("php");
319 asm("jmp ($0318)");
320
321 nmi2();
322}
323/*-----------------------------------------------------------------------------------*/
324static void
325setup_nmi(void)
326{
327 asm("lda #<_nmi");
328 asm("sta $fffa");
329 asm("lda #>_nmi");
330 asm("sta $fffb");
331 return;
332 nmi();
333}
334/*-----------------------------------------------------------------------------------*/
335void
336ctk_draw_init(void)
337{
adamdunkels77e47062003-04-17 15:09:31 +0000338 unsigned char i, *ptr1, *ptr2;
339
adamdunkels7e4982c2003-03-19 16:26:18 +0000340 setup_nmi();
341
342 /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for
343 hires/colors. */
344 VIC.ctrl1 = 0x3b; /* $D011 */
345 VIC.addr = 0x78; /* $D018 */
346 VIC.ctrl2 = 0xc8; /* $D016 */
adamdunkels7e4982c2003-03-19 16:26:18 +0000347 CIA2.pra = 0x00; /* $DD00 */
348
adamdunkels77e47062003-04-17 15:09:31 +0000349 VIC.bordercolor = ctk_hires_theme.bordercolor; /* $D020 */
350 VIC.bgcolor0 = ctk_hires_theme.screencolor; /* $D021 */
351
adamdunkels7e4982c2003-03-19 16:26:18 +0000352 /* Fill color memory. */
353 asm("sei");
354 asm("lda $01");
355 asm("pha");
356 asm("lda #$30");
357 asm("sta $01");
358 asm("ldx #0");
359 asm("lda #$c0");
360 asm("fillcolorloop:");
361 asm("sta $dc00,x");
362 asm("sta $dd00,x");
363 asm("sta $de00,x");
364 asm("sta $df00,x");
365 asm("inx");
366 asm("bne fillcolorloop");
adamdunkels77e47062003-04-17 15:09:31 +0000367
368 /* Setup sprite pointers */
369 asm("ldx #$fd");
370 asm("stx $dff8");
371 asm("inx");
372 asm("stx $dff9");
adamdunkels7e4982c2003-03-19 16:26:18 +0000373 asm("pla");
374 asm("sta $01");
375 asm("cli");
376
377 /* Fill hires memory with 0. */
378
379 asm("lda $fd");
380 asm("pha");
381 asm("lda $fe");
382 asm("pha");
383 asm("lda #0");
384 asm("sta $fd");
385 asm("lda #$e0");
386 asm("sta $fe");
387 asm("ldy #0");
388 asm("lda #0");
389 asm("clrscrnloop:");
390 asm("lda #$55");
391 asm("sta ($fd),y");
392 asm("iny");
393 asm("lda #$aa");
394 asm("sta ($fd),y");
395 asm("iny");
396 asm("bne clrscrnloop");
397 asm("inc $fe");
398 asm("lda $fe");
399 asm("cmp #$ff");
400 asm("bne clrscrnloop");
401
402 asm("ldy #$00");
403 asm("clrscrnloop2:");
404 asm("lda #$55");
405 asm("sta $ff00,y");
406 asm("iny");
407 asm("lda #$aa");
408 asm("sta $ff00,y");
409 asm("iny");
410 asm("cpy #$40");
411 asm("bne clrscrnloop2");
412
413
414 asm("pla");
415 asm("sta $fe");
416 asm("pla");
417 asm("sta $fd");
418
adamdunkels7e4982c2003-03-19 16:26:18 +0000419
adamdunkels77e47062003-04-17 15:09:31 +0000420 ctk_draw_clear(0, SCREEN_HEIGHT);
421
422 /* Setup mouse pointer sprite. */
423 asm("lda %v+%w", ctk_hires_theme,
424 offsetof(struct ctk_hires_theme, pointermaskcolor));
425 asm("sta $d027");
426 asm("lda %v+%w", ctk_hires_theme,
427 offsetof(struct ctk_hires_theme, pointercolor));
428 asm("sta $d028");
429
430 ptr1 = ctk_hires_theme.pointer;
431 ptr2 = (unsigned char *)0xff40;
432
433 for(i = 0; i < 0x80; ++i) {
434 *ptr2++ = *ptr1++;
435 }
436
adamdunkels7e4982c2003-03-19 16:26:18 +0000437 return;
438}
439/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000440static void __fastcall__
adamdunkelsd7422082003-08-05 13:57:01 +0000441draw_widget(register struct ctk_widget *w,
adamdunkels7e4982c2003-03-19 16:26:18 +0000442 unsigned char x, unsigned char y,
443 unsigned char clipy1, unsigned char clipy2,
adamdunkels97c19b72003-08-24 22:29:41 +0000444 unsigned char afocus)
adamdunkels7e4982c2003-03-19 16:26:18 +0000445{
adamdunkels23b30d52003-08-15 18:46:25 +0000446 static unsigned char xpos, ypos, xscroll;
447 static unsigned char i;
448 static char c;
449 static unsigned char len;
adamdunkelsd388da12003-08-20 19:55:25 +0000450 static unsigned char tmp;
adamdunkels97c19b72003-08-24 22:29:41 +0000451 static unsigned char yclipped;
452 static unsigned char focus;
adamdunkels23b30d52003-08-15 18:46:25 +0000453 char *text;
454
adamdunkels7e4982c2003-03-19 16:26:18 +0000455 xpos = x + w->x;
adamdunkelsd388da12003-08-20 19:55:25 +0000456 ypos = y + w->y;
adamdunkels97c19b72003-08-24 22:29:41 +0000457
458 yclipped = 0;
459 if(ypos >= clipy1 && ypos < clipy2) {
460 yclipped = 1;
461 }
462 focus = afocus;
463
adamdunkels7e4982c2003-03-19 16:26:18 +0000464
465 switch(w->type) {
466 case CTK_WIDGET_SEPARATOR:
adamdunkels77e47062003-04-17 15:09:31 +0000467 hires_color(ctk_hires_theme.separatorcolors[focus]);
adamdunkels97c19b72003-08-24 22:29:41 +0000468 if(yclipped) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000469 hires_chlinexy(xpos, ypos, w->w);
470 }
471 break;
472 case CTK_WIDGET_LABEL:
adamdunkels77e47062003-04-17 15:09:31 +0000473 hires_color(ctk_hires_theme.labelcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000474 text = w->widget.label.text;
adamdunkels41343612003-07-31 23:23:25 +0000475 for(i = 0; i < w->h; ++i) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000476 if(ypos >= clipy1 && ypos < clipy2) {
477 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000478 ctk_hires_cputsn(text, w->w);
adamdunkels97c19b72003-08-24 22:29:41 +0000479 tmp = w->w - (hires_wherex() - xpos);
480 if(tmp > 0) {
481 ctk_hires_cclear(tmp);
adamdunkels7e4982c2003-03-19 16:26:18 +0000482 }
483 }
484 ++ypos;
485 text += w->w;
486 }
487 break;
488 case CTK_WIDGET_BUTTON:
adamdunkels97c19b72003-08-24 22:29:41 +0000489 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000490 hires_color(ctk_hires_theme.buttonleftcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000491 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000492 ctk_hires_draw_buttonleft();
493 hires_color(ctk_hires_theme.buttoncolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000494 hires_gotoxy(xpos + 1, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000495 ctk_hires_cputsn(w->widget.button.text, w->w);
496 hires_color(ctk_hires_theme.buttonrightcolors[focus]);
497 ctk_hires_draw_buttonright();
adamdunkels7e4982c2003-03-19 16:26:18 +0000498 }
499 break;
500 case CTK_WIDGET_HYPERLINK:
adamdunkels97c19b72003-08-24 22:29:41 +0000501 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000502 hires_color(ctk_hires_theme.hyperlinkcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000503 hires_underline(1);
504 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000505 ctk_hires_cputsn(w->widget.button.text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000506 hires_underline(0);
507 }
508 break;
509 case CTK_WIDGET_TEXTENTRY:
adamdunkels97c19b72003-08-24 22:29:41 +0000510 if(yclipped) {
511 hires_color(ctk_hires_theme.textentrycolors[focus]);
512
513 if((focus & CTK_FOCUS_WIDGET) &&
514 w->widget.textentry.state != CTK_TEXTENTRY_EDIT) {
515 hires_revers(1);
516 } else {
517 hires_revers(0);
518 }
519 xscroll = 0;
520 tmp = w->w - 1;
521 if(w->widget.textentry.xpos >= tmp) {
522 xscroll = w->widget.textentry.xpos - tmp;
523 }
524 text = w->widget.textentry.text;
adamdunkels77e47062003-04-17 15:09:31 +0000525 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) {
526 hires_revers(0);
527 hires_cputcxy(xpos, ypos, '>');
adamdunkels97c19b72003-08-24 22:29:41 +0000528 text += xscroll;
adamdunkels77e47062003-04-17 15:09:31 +0000529 for(i = 0; i < w->w; ++i) {
adamdunkels97c19b72003-08-24 22:29:41 +0000530 c = *text;
adamdunkels77e47062003-04-17 15:09:31 +0000531 if(i == w->widget.textentry.xpos - xscroll) {
532 hires_revers(1);
533 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000534 hires_revers(0);
535 }
adamdunkels77e47062003-04-17 15:09:31 +0000536 if(c == 0) {
537 ctk_hires_cputc(' ');
538 } else {
539 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000540 }
adamdunkels77e47062003-04-17 15:09:31 +0000541 hires_revers(0);
adamdunkels97c19b72003-08-24 22:29:41 +0000542 ++text;
adamdunkels7e4982c2003-03-19 16:26:18 +0000543 }
adamdunkels77e47062003-04-17 15:09:31 +0000544 ctk_hires_cputc('<');
545 } else {
546 hires_cputcxy(xpos, ypos, '|');
547 /* hires_gotoxy(xpos + 1, ypos); */
548 ctk_hires_cputsn(text, w->w);
549 i = hires_wherex();
adamdunkelsd388da12003-08-20 19:55:25 +0000550 tmp = i - xpos - 1;
551 if(tmp < w->w) {
552 ctk_hires_cclear(w->w - tmp);
adamdunkels77e47062003-04-17 15:09:31 +0000553 }
554 ctk_hires_cputc('|');
adamdunkels7e4982c2003-03-19 16:26:18 +0000555 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000556 }
557 hires_revers(0);
558 break;
559 case CTK_WIDGET_ICON:
adamdunkels97c19b72003-08-24 22:29:41 +0000560 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000561 hires_color(ctk_hires_theme.iconcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000562
adamdunkels9e046b42003-04-24 17:05:41 +0000563 x = xpos;
adamdunkels7e4982c2003-03-19 16:26:18 +0000564 len = strlen(w->widget.icon.title);
565 if(x + len >= SCREEN_WIDTH) {
566 x = SCREEN_WIDTH - len;
567 }
adamdunkelsd388da12003-08-20 19:55:25 +0000568
569 tmp = ypos + 3;
570
571 if(tmp < clipy2) {
572 hires_gotoxy(x, tmp);
adamdunkels9e046b42003-04-24 17:05:41 +0000573 ctk_hires_cputsn(w->widget.icon.title, len);
574 }
575
576 hires_gotoxy(xpos, ypos);
577 if(w->widget.icon.bitmap != NULL) {
578 ctk_hires_bitmapptr = w->widget.icon.bitmap;
579 for(i = 0; i < 3; ++i) {
580 if(ypos >= clipy1 && ypos < clipy2) {
581 hires_gotoxy(xpos, ypos);
582 ctk_hires_draw_bitmapline(3);
583 }
584 ctk_hires_bitmapptr += 3 * 8;
585 ++ypos;
586 }
587
588 /* draw_bitmap_icon(w->widget.icon.bitmap);*/
589 }
590
adamdunkels7e4982c2003-03-19 16:26:18 +0000591 }
592 break;
adamdunkels77e47062003-04-17 15:09:31 +0000593 case CTK_WIDGET_BITMAP:
594 hires_color(ctk_hires_theme.bitmapcolors[focus]);
595 ctk_hires_bitmapptr = w->widget.bitmap.bitmap;
adamdunkels41343612003-07-31 23:23:25 +0000596 for(i = 0; i < w->h; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000597 if(ypos >= clipy1 && ypos < clipy2) {
598 hires_gotoxy(xpos, ypos);
599 ctk_hires_draw_bitmapline(w->w);
600 }
601 ctk_hires_bitmapptr += w->w * 8;
602 ++ypos;
603 }
604 break;
605
adamdunkels7e4982c2003-03-19 16:26:18 +0000606 default:
607 break;
608 }
609}
610/*-----------------------------------------------------------------------------------*/
611void
612ctk_draw_widget(struct ctk_widget *w,
613 unsigned char focus,
614 unsigned char clipy1,
615 unsigned char clipy2)
616{
617 struct ctk_window *win = w->window;
618 unsigned char posx, posy;
619
620 posx = win->x + 1;
621 posy = win->y + 2;
622
623 if(w == win->focused) {
624 focus |= CTK_FOCUS_WIDGET;
625 }
626
627 draw_widget(w, posx, posy,
628 clipy1, clipy2,
629 focus);
630}
631/*-----------------------------------------------------------------------------------*/
632void
adamdunkelsd7422082003-08-05 13:57:01 +0000633ctk_draw_clear_window(register struct ctk_window *window,
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000634 unsigned char focus,
635 unsigned char clipy1,
636 unsigned char clipy2)
637{
adamdunkels23b30d52003-08-15 18:46:25 +0000638 static unsigned char h;
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000639
adamdunkels77e47062003-04-17 15:09:31 +0000640 hires_color(ctk_hires_theme.windowcolors[focus]);
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000641
642 h = window->y + 2 + window->h;
643 /* Clear window contents. */
644 for(i = window->y + 2; i < h; ++i) {
adamdunkels9e046b42003-04-24 17:05:41 +0000645 if(i >= clipy1 && i <= clipy2) {
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000646 hires_cclearxy(window->x + 1, i, window->w);
647 }
648 }
649}
650/*-----------------------------------------------------------------------------------*/
651void
adamdunkels7e4982c2003-03-19 16:26:18 +0000652ctk_draw_window(register struct ctk_window *window,
653 unsigned char focus,
654 unsigned char clipy1, unsigned char clipy2)
655{
656 register struct ctk_widget *w;
adamdunkels7e4982c2003-03-19 16:26:18 +0000657 x = window->x;
658 y = window->y + 1;
659
660 ++clipy2;
661
adamdunkels9e046b42003-04-24 17:05:41 +0000662 if(clipy2 <= y) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000663 return;
664 }
adamdunkels77e47062003-04-17 15:09:31 +0000665
adamdunkels9e046b42003-04-24 17:05:41 +0000666 /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/
adamdunkels77e47062003-04-17 15:09:31 +0000667
adamdunkels7e4982c2003-03-19 16:26:18 +0000668 x1 = x + 1;
669 y1 = y + 1;
adamdunkels9e046b42003-04-24 17:05:41 +0000670 /* x2 = x1 + window->w;
671 y2 = y1 + window->h;*/
adamdunkels77e47062003-04-17 15:09:31 +0000672
adamdunkels7e4982c2003-03-19 16:26:18 +0000673 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000674 ctk_hires_windowparams.w = window->w;
675 ctk_hires_windowparams.h = window->h;
adamdunkels7e4982c2003-03-19 16:26:18 +0000676 if(clipy1 < y) {
adamdunkels77e47062003-04-17 15:09:31 +0000677 ctk_hires_windowparams.clipy1 = 0;
adamdunkels7e4982c2003-03-19 16:26:18 +0000678 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000679 ctk_hires_windowparams.clipy1 = clipy1 - y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000680 }
adamdunkels77e47062003-04-17 15:09:31 +0000681 ctk_hires_windowparams.clipy2 = clipy2 - y;
682 ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1];
683 ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus];
684 ctk_hires_windowparams.title = window->title;
685 ctk_hires_windowparams.titlelen = window->titlelen;
adamdunkels7e4982c2003-03-19 16:26:18 +0000686
adamdunkels9e046b42003-04-24 17:05:41 +0000687 if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 &&
688 ctk_hires_windowparams.clipy2 > 0) {
689 ctk_hires_draw_windowborders();
adamdunkels7e4982c2003-03-19 16:26:18 +0000690 }
adamdunkels41343612003-07-31 23:23:25 +0000691
adamdunkels7e4982c2003-03-19 16:26:18 +0000692 focus = focus & CTK_FOCUS_WINDOW;
693
694 /* Draw inactive widgets. */
695 for(w = window->inactive; w != NULL; w = w->next) {
696 draw_widget(w, x1, y1,
697 clipy1, clipy2,
698 focus);
699 }
700
701 /* Draw active widgets. */
702 for(w = window->active; w != NULL; w = w->next) {
703 wfocus = focus;
704 if(w == window->focused) {
705 wfocus |= CTK_FOCUS_WIDGET;
706 }
707 draw_widget(w, x1, y1,
708 clipy1, clipy2,
709 wfocus);
710 }
711}
712/*-----------------------------------------------------------------------------------*/
713void
714ctk_draw_dialog(register struct ctk_window *dialog)
715{
716 register struct ctk_widget *w;
717
adamdunkels77e47062003-04-17 15:09:31 +0000718 hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000719
720 /* x = (SCREEN_WIDTH - dialog->w) / 2;
721 y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */
722 x = dialog->x;
723 y = dialog->y + 1;
724
725
726 x1 = x + 1;
727 y1 = y + 1;
728 x2 = x1 + dialog->w;
729 y2 = y1 + dialog->h;
730
731
732 /* Draw dialog frame. */
733
adamdunkels97c19b72003-08-24 22:29:41 +0000734 hires_cvlinexy(x, y1, dialog->h);
735 hires_cvlinexy(x2, y1, dialog->h);
adamdunkels7e4982c2003-03-19 16:26:18 +0000736
adamdunkels97c19b72003-08-24 22:29:41 +0000737 hires_chlinexy(x1, y, dialog->w);
738 hires_chlinexy(x1, y2, dialog->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000739
740 hires_cputcxy(x, y, CH_ULCORNER);
741 hires_cputcxy(x, y2, CH_LLCORNER);
742 hires_cputcxy(x2, y, CH_URCORNER);
743 hires_cputcxy(x2, y2, CH_LRCORNER);
744
745
746 /* Clear window contents. */
adamdunkels97c19b72003-08-24 22:29:41 +0000747 for(i = y1; i < y2; ++i) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000748 hires_cclearxy(x1, i, dialog->w);
749 }
750
adamdunkels7e4982c2003-03-19 16:26:18 +0000751 /* Draw inactive widgets. */
752 for(w = dialog->inactive; w != NULL; w = w->next) {
753 draw_widget(w, x1, y1,
754 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG);
755 }
756
757
758 /* Draw active widgets. */
759 for(w = dialog->active; w != NULL; w = w->next) {
760 wfocus = CTK_FOCUS_DIALOG;
761 if(w == dialog->focused) {
762 wfocus |= CTK_FOCUS_WIDGET;
763 }
764 draw_widget(w, x1, y1,
765 0, SCREEN_HEIGHT, wfocus);
766 }
767
768}
769/*-----------------------------------------------------------------------------------*/
770void
771ctk_draw_clear(unsigned char y1, unsigned char y2)
772{
773 for(i = y1; i < y2; ++i) {
774 clear_line(i);
775 }
776}
777/*-----------------------------------------------------------------------------------*/
778static void
adamdunkelsd7422082003-08-05 13:57:01 +0000779draw_menu(register struct ctk_menu *m)
adamdunkels7e4982c2003-03-19 16:26:18 +0000780{
adamdunkels23b30d52003-08-15 18:46:25 +0000781 static unsigned char x, x2, y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000782
adamdunkels77e47062003-04-17 15:09:31 +0000783 hires_color(ctk_hires_theme.openmenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000784 x = hires_wherex();
adamdunkels77e47062003-04-17 15:09:31 +0000785 ctk_hires_cputsn(m->title, m->titlelen);
786 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000787 x2 = hires_wherex();
788 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
789 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
790 }
791 for(y = 0; y < m->nitems; ++y) {
792 if(y == m->active) {
adamdunkels77e47062003-04-17 15:09:31 +0000793 hires_color(ctk_hires_theme.activemenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000794 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000795 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000796 }
797 hires_gotoxy(x, y + 1);
798 if(m->items[y].title[0] == '-') {
adamdunkels77e47062003-04-17 15:09:31 +0000799 ctk_hires_chline(CTK_CONF_MENUWIDTH);
adamdunkels7e4982c2003-03-19 16:26:18 +0000800 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000801 ctk_hires_cputsn(m->items[y].title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000802 strlen(m->items[y].title));
803 }
adamdunkels77e47062003-04-17 15:09:31 +0000804 ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex());
adamdunkels7e4982c2003-03-19 16:26:18 +0000805 hires_revers(0);
806 }
807 hires_gotoxy(x2, 0);
adamdunkels77e47062003-04-17 15:09:31 +0000808 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000809}
810/*-----------------------------------------------------------------------------------*/
811void
812ctk_draw_menus(struct ctk_menus *menus)
813{
814 struct ctk_menu *m;
adamdunkels23b30d52003-08-15 18:46:25 +0000815
adamdunkels7e4982c2003-03-19 16:26:18 +0000816 /* Draw menus */
adamdunkels77e47062003-04-17 15:09:31 +0000817 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000818 hires_gotoxy(0, 0);
819 hires_revers(0);
adamdunkels77e47062003-04-17 15:09:31 +0000820 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000821 for(m = menus->menus->next; m != NULL; m = m->next) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000822 if(m != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000823 ctk_hires_cputsn(m->title, m->titlelen);
824 ctk_hires_cputc(' ');
adamdunkels41343612003-07-31 23:23:25 +0000825 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000826 draw_menu(m);
827 }
828 }
adamdunkels77e47062003-04-17 15:09:31 +0000829 ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() -
adamdunkels7e4982c2003-03-19 16:26:18 +0000830 strlen(menus->desktopmenu->title) - 1);
831
832 /* Draw desktopmenu */
833 if(menus->desktopmenu != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000834 ctk_hires_cputsn(menus->desktopmenu->title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000835 menus->desktopmenu->titlelen);
adamdunkels77e47062003-04-17 15:09:31 +0000836 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000837 } else {
838 draw_menu(menus->desktopmenu);
839 }
840
841}
842/*-----------------------------------------------------------------------------------*/
843unsigned char
844ctk_draw_height(void)
845{
846 return SCREEN_HEIGHT;
847}
848/*-----------------------------------------------------------------------------------*/
849unsigned char
850ctk_draw_width(void)
851{
852 return SCREEN_WIDTH;
853}
854/*-----------------------------------------------------------------------------------*/
adamdunkels0a08fda2004-07-04 18:33:07 +0000855unsigned char
856ctk_arch_isprint(char c)
857{
858 return isprint(c);
859}