blob: 1c7a843b5dcaab61dbec51fdf6b9f3465f409fa0 [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 *
adamdunkels1de1f842004-02-16 20:57:36 +000035 * $Id: ctk-hires.c,v 1.9 2004/02/16 20:57:36 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
adamdunkelsc1c84be2003-08-09 13:26:22 +000065/*static unsigned char cchar;
adamdunkels7e4982c2003-03-19 16:26:18 +000066
67static unsigned char tmp01;
68static unsigned char tmph, tmpl, tmpborder;
adamdunkelsc1c84be2003-08-09 13:26:22 +000069static unsigned char *tmpptr;*/
adamdunkels7e4982c2003-03-19 16:26:18 +000070
71
72static unsigned char x, y, i;
adamdunkelsc1c84be2003-08-09 13:26:22 +000073/*static unsigned char h;*/
adamdunkels7e4982c2003-03-19 16:26:18 +000074static 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;
adamdunkels97c19b72003-08-24 22:29:41 +000079
adamdunkels7e4982c2003-03-19 16:26:18 +000080/*-----------------------------------------------------------------------------------*/
81/* Tables. */
82
adamdunkels77e47062003-04-17 15:09:31 +000083unsigned short ctk_hires_yscreenaddr[25] =
adamdunkels7e4982c2003-03-19 16:26:18 +000084 {0 * SCREEN_WIDTH + SCREENADDR, 1 * SCREEN_WIDTH + SCREENADDR,
85 2 * SCREEN_WIDTH + SCREENADDR, 3 * SCREEN_WIDTH + SCREENADDR,
86 4 * SCREEN_WIDTH + SCREENADDR, 5 * SCREEN_WIDTH + SCREENADDR,
87 6 * SCREEN_WIDTH + SCREENADDR, 7 * SCREEN_WIDTH + SCREENADDR,
88 8 * SCREEN_WIDTH + SCREENADDR, 9 * SCREEN_WIDTH + SCREENADDR,
89 10 * SCREEN_WIDTH + SCREENADDR, 11 * SCREEN_WIDTH + SCREENADDR,
90 12 * SCREEN_WIDTH + SCREENADDR, 13 * SCREEN_WIDTH + SCREENADDR,
91 14 * SCREEN_WIDTH + SCREENADDR, 15 * SCREEN_WIDTH + SCREENADDR,
92 16 * SCREEN_WIDTH + SCREENADDR, 17 * SCREEN_WIDTH + SCREENADDR,
93 18 * SCREEN_WIDTH + SCREENADDR, 19 * SCREEN_WIDTH + SCREENADDR,
94 20 * SCREEN_WIDTH + SCREENADDR, 21 * SCREEN_WIDTH + SCREENADDR,
95 22 * SCREEN_WIDTH + SCREENADDR, 23 * SCREEN_WIDTH + SCREENADDR,
96 24 * SCREEN_WIDTH + SCREENADDR};
97
adamdunkels77e47062003-04-17 15:09:31 +000098unsigned short ctk_hires_yhiresaddr[25] =
adamdunkels7e4982c2003-03-19 16:26:18 +000099 {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR,
100 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR,
101 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR,
102 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR,
103 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR,
104 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR,
105 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR,
106 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR,
107 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR,
108 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR,
109 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR,
110 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR,
111 24 * 320 + HIRESADDR};
adamdunkels77e47062003-04-17 15:09:31 +0000112extern struct ctk_hires_theme ctk_hires_theme;
113struct ctk_hires_theme *ctk_hires_theme_ptr = &ctk_hires_theme;
adamdunkels7e4982c2003-03-19 16:26:18 +0000114/*-----------------------------------------------------------------------------------*/
adamdunkels77e47062003-04-17 15:09:31 +0000115#define hires_wherex() ctk_hires_cursx
116#define hires_revers(c) ctk_hires_reversed = c
117#define hires_color(c) ctk_hires_color = c
118#define hires_underline(c) ctk_hires_underline = c
adamdunkels7e4982c2003-03-19 16:26:18 +0000119/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000120static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000121hires_cvline(unsigned char length)
122{
adamdunkels23b30d52003-08-15 18:46:25 +0000123 static unsigned char i;
adamdunkels7e4982c2003-03-19 16:26:18 +0000124
125 for(i = 0; i < length; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000126 ctk_hires_cputc('|');
127 --ctk_hires_cursx;
128 ++ctk_hires_cursy;
adamdunkels7e4982c2003-03-19 16:26:18 +0000129 }
130}
131/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000132static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000133hires_gotoxy(unsigned char x, unsigned char y)
134{
adamdunkels77e47062003-04-17 15:09:31 +0000135 ctk_hires_cursx = x;
136 ctk_hires_cursy = y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000137}
138/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000139static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000140hires_cclearxy(unsigned char x, unsigned char y, unsigned char length)
141{
142 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000143 ctk_hires_cclear(length);
adamdunkels7e4982c2003-03-19 16:26:18 +0000144}
145/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000146static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000147hires_chlinexy(unsigned char x, unsigned char y, unsigned char length)
148{
149 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000150 ctk_hires_chline(length);
adamdunkels7e4982c2003-03-19 16:26:18 +0000151}
152/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000153static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000154hires_cvlinexy(unsigned char x, unsigned char y, unsigned char length)
155{
156 hires_gotoxy(x, y);
157 hires_cvline(length);
158}
159/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000160static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000161hires_cputcxy(unsigned char x, unsigned char y, char c)
162{
163 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000164 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000165}
166/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000167static void
adamdunkels7e4982c2003-03-19 16:26:18 +0000168clear_line(unsigned char line)
169{
170 lineptr = line;
adamdunkels77e47062003-04-17 15:09:31 +0000171 asm("lda %v", lineptr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000172 asm("asl");
173 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000174 asm("lda %v,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000175 asm("sta ptr2");
adamdunkels77e47062003-04-17 15:09:31 +0000176 asm("lda %v+1,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000177 asm("sta ptr2+1");
adamdunkels77e47062003-04-17 15:09:31 +0000178 asm("lda %v,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000179 asm("sta ptr1");
adamdunkels77e47062003-04-17 15:09:31 +0000180 asm("lda %v+1,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000181 asm("sta ptr1+1");
182
183
184 asm("sei");
185 asm("lda $01");
186 asm("pha");
187 asm("lda #$30");
188 asm("sta $01");
189 asm("ldy #39");
adamdunkels77e47062003-04-17 15:09:31 +0000190 asm("ldx %v", lineptr);
191 asm("lda %v+%w,x", ctk_hires_theme,
192 offsetof(struct ctk_hires_theme, backgroundpatterncolors));
adamdunkels7e4982c2003-03-19 16:26:18 +0000193 asm("clearlineloop1:");
194 asm("sta (ptr1),y");
195 asm("dey");
196 asm("bpl clearlineloop1");
197 asm("pla");
198 asm("sta $01");
199 asm("cli");
200
201
adamdunkels77e47062003-04-17 15:09:31 +0000202 asm("lda %v", lineptr);
203 /* asm("and #7");*/
adamdunkels7e4982c2003-03-19 16:26:18 +0000204 asm("asl");
adamdunkels77e47062003-04-17 15:09:31 +0000205 asm("asl");
adamdunkels7e4982c2003-03-19 16:26:18 +0000206 asm("asl");
207 asm("tax");
208 asm("ldy #0");
209 asm("clearlineloop2:");
adamdunkels77e47062003-04-17 15:09:31 +0000210 asm("lda %v+%w+0,x", ctk_hires_theme,
211 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000212 asm("sta (ptr2),y");
213 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000214 asm("lda %v+%w+1,x", ctk_hires_theme,
215 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000216 asm("sta (ptr2),y");
217 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000218 asm("lda %v+%w+2,x", ctk_hires_theme,
219 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000220 asm("sta (ptr2),y");
221 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000222 asm("lda %v+%w+3,x", ctk_hires_theme,
223 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000224 asm("sta (ptr2),y");
225 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000226 asm("lda %v+%w+4,x", ctk_hires_theme,
227 offsetof(struct ctk_hires_theme, backgroundpattern));
228 asm("sta (ptr2),y");
229 asm("iny");
230 asm("lda %v+%w+5,x", ctk_hires_theme,
231 offsetof(struct ctk_hires_theme, backgroundpattern));
232 asm("sta (ptr2),y");
233 asm("iny");
234 asm("lda %v+%w+6,x", ctk_hires_theme,
235 offsetof(struct ctk_hires_theme, backgroundpattern));
236 asm("sta (ptr2),y");
237 asm("iny");
238 asm("lda %v+%w+7,x", ctk_hires_theme,
239 offsetof(struct ctk_hires_theme, backgroundpattern));
240 asm("sta (ptr2),y");
241 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000242 asm("bne clearlineloop2");
243
244 asm("inc ptr2+1");
245
246 asm("ldy #0");
247 asm("clearlineloop3:");
adamdunkels77e47062003-04-17 15:09:31 +0000248 asm("lda %v+%w+0,x", ctk_hires_theme,
249 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000250 asm("sta (ptr2),y");
251 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000252 asm("lda %v+%w+1,x", ctk_hires_theme,
253 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000254 asm("sta (ptr2),y");
255 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000256 asm("lda %v+%w+2,x", ctk_hires_theme,
257 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000258 asm("sta (ptr2),y");
259 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000260 asm("lda %v+%w+3,x", ctk_hires_theme,
261 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000262 asm("sta (ptr2),y");
263 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000264 asm("lda %v+%w+4,x", ctk_hires_theme,
265 offsetof(struct ctk_hires_theme, backgroundpattern));
266 asm("sta (ptr2),y");
267 asm("iny");
268 asm("lda %v+%w+5,x", ctk_hires_theme,
269 offsetof(struct ctk_hires_theme, backgroundpattern));
270 asm("sta (ptr2),y");
271 asm("iny");
272 asm("lda %v+%w+6,x", ctk_hires_theme,
273 offsetof(struct ctk_hires_theme, backgroundpattern));
274 asm("sta (ptr2),y");
275 asm("iny");
276 asm("lda %v+%w+7,x", ctk_hires_theme,
277 offsetof(struct ctk_hires_theme, backgroundpattern));
278 asm("sta (ptr2),y");
279 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000280 asm("cpy #$40");
281 asm("bne clearlineloop3");
adamdunkels1de1f842004-02-16 20:57:36 +0000282
adamdunkels7e4982c2003-03-19 16:26:18 +0000283
adamdunkels1de1f842004-02-16 20:57:36 +0000284 if(lineptr == 24) {
285#define CONTIKI_VERSION_STRING "Contiki 1.2-pre0"
286 hires_color(ctk_hires_theme.backgroundpatterncolors[24]);
287 hires_gotoxy(0, 24);
288 ctk_hires_cputsn(CONTIKI_VERSION_STRING,
289 sizeof(CONTIKI_VERSION_STRING) - 1);
290 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000291}
292/*-----------------------------------------------------------------------------------*/
293static void
294nmi2(void)
295{
296 asm("pla");
297 asm("sta $01");
298 asm("pla");
299 asm("rti");
300}
301/*-----------------------------------------------------------------------------------*/
302static void
303nmi(void)
304{
305 asm("sei");
306 asm("pha");
307 asm("inc $d020");
308 asm("lda $01");
309 asm("pha");
310 asm("lda #$36");
311 asm("sta $01");
312 asm("lda #>_nmi2");
313 asm("pha");
314 asm("lda #<_nmi2");
315 asm("pha");
316 asm("php");
317 asm("jmp ($0318)");
318
319 nmi2();
320}
321/*-----------------------------------------------------------------------------------*/
322static void
323setup_nmi(void)
324{
325 asm("lda #<_nmi");
326 asm("sta $fffa");
327 asm("lda #>_nmi");
328 asm("sta $fffb");
329 return;
330 nmi();
331}
332/*-----------------------------------------------------------------------------------*/
333void
334ctk_draw_init(void)
335{
adamdunkels77e47062003-04-17 15:09:31 +0000336 unsigned char i, *ptr1, *ptr2;
337
adamdunkels7e4982c2003-03-19 16:26:18 +0000338 setup_nmi();
339
340 /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for
341 hires/colors. */
342 VIC.ctrl1 = 0x3b; /* $D011 */
343 VIC.addr = 0x78; /* $D018 */
344 VIC.ctrl2 = 0xc8; /* $D016 */
adamdunkels7e4982c2003-03-19 16:26:18 +0000345 CIA2.pra = 0x00; /* $DD00 */
346
adamdunkels77e47062003-04-17 15:09:31 +0000347 VIC.bordercolor = ctk_hires_theme.bordercolor; /* $D020 */
348 VIC.bgcolor0 = ctk_hires_theme.screencolor; /* $D021 */
349
adamdunkels7e4982c2003-03-19 16:26:18 +0000350 /* Fill color memory. */
351 asm("sei");
352 asm("lda $01");
353 asm("pha");
354 asm("lda #$30");
355 asm("sta $01");
356 asm("ldx #0");
357 asm("lda #$c0");
358 asm("fillcolorloop:");
359 asm("sta $dc00,x");
360 asm("sta $dd00,x");
361 asm("sta $de00,x");
362 asm("sta $df00,x");
363 asm("inx");
364 asm("bne fillcolorloop");
adamdunkels77e47062003-04-17 15:09:31 +0000365
366 /* Setup sprite pointers */
367 asm("ldx #$fd");
368 asm("stx $dff8");
369 asm("inx");
370 asm("stx $dff9");
adamdunkels7e4982c2003-03-19 16:26:18 +0000371 asm("pla");
372 asm("sta $01");
373 asm("cli");
374
375 /* Fill hires memory with 0. */
376
377 asm("lda $fd");
378 asm("pha");
379 asm("lda $fe");
380 asm("pha");
381 asm("lda #0");
382 asm("sta $fd");
383 asm("lda #$e0");
384 asm("sta $fe");
385 asm("ldy #0");
386 asm("lda #0");
387 asm("clrscrnloop:");
388 asm("lda #$55");
389 asm("sta ($fd),y");
390 asm("iny");
391 asm("lda #$aa");
392 asm("sta ($fd),y");
393 asm("iny");
394 asm("bne clrscrnloop");
395 asm("inc $fe");
396 asm("lda $fe");
397 asm("cmp #$ff");
398 asm("bne clrscrnloop");
399
400 asm("ldy #$00");
401 asm("clrscrnloop2:");
402 asm("lda #$55");
403 asm("sta $ff00,y");
404 asm("iny");
405 asm("lda #$aa");
406 asm("sta $ff00,y");
407 asm("iny");
408 asm("cpy #$40");
409 asm("bne clrscrnloop2");
410
411
412 asm("pla");
413 asm("sta $fe");
414 asm("pla");
415 asm("sta $fd");
416
adamdunkels7e4982c2003-03-19 16:26:18 +0000417
adamdunkels77e47062003-04-17 15:09:31 +0000418 ctk_draw_clear(0, SCREEN_HEIGHT);
419
420 /* Setup mouse pointer sprite. */
421 asm("lda %v+%w", ctk_hires_theme,
422 offsetof(struct ctk_hires_theme, pointermaskcolor));
423 asm("sta $d027");
424 asm("lda %v+%w", ctk_hires_theme,
425 offsetof(struct ctk_hires_theme, pointercolor));
426 asm("sta $d028");
427
428 ptr1 = ctk_hires_theme.pointer;
429 ptr2 = (unsigned char *)0xff40;
430
431 for(i = 0; i < 0x80; ++i) {
432 *ptr2++ = *ptr1++;
433 }
434
adamdunkels7e4982c2003-03-19 16:26:18 +0000435 return;
436}
437/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000438static void __fastcall__
adamdunkelsd7422082003-08-05 13:57:01 +0000439draw_widget(register struct ctk_widget *w,
adamdunkels7e4982c2003-03-19 16:26:18 +0000440 unsigned char x, unsigned char y,
441 unsigned char clipy1, unsigned char clipy2,
adamdunkels97c19b72003-08-24 22:29:41 +0000442 unsigned char afocus)
adamdunkels7e4982c2003-03-19 16:26:18 +0000443{
adamdunkels23b30d52003-08-15 18:46:25 +0000444 static unsigned char xpos, ypos, xscroll;
445 static unsigned char i;
446 static char c;
447 static unsigned char len;
adamdunkelsd388da12003-08-20 19:55:25 +0000448 static unsigned char tmp;
adamdunkels97c19b72003-08-24 22:29:41 +0000449 static unsigned char yclipped;
450 static unsigned char focus;
adamdunkels23b30d52003-08-15 18:46:25 +0000451 char *text;
452
adamdunkels7e4982c2003-03-19 16:26:18 +0000453 xpos = x + w->x;
adamdunkelsd388da12003-08-20 19:55:25 +0000454 ypos = y + w->y;
adamdunkels97c19b72003-08-24 22:29:41 +0000455
456 yclipped = 0;
457 if(ypos >= clipy1 && ypos < clipy2) {
458 yclipped = 1;
459 }
460 focus = afocus;
461
adamdunkels7e4982c2003-03-19 16:26:18 +0000462
463 switch(w->type) {
464 case CTK_WIDGET_SEPARATOR:
adamdunkels77e47062003-04-17 15:09:31 +0000465 hires_color(ctk_hires_theme.separatorcolors[focus]);
adamdunkels97c19b72003-08-24 22:29:41 +0000466 if(yclipped) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000467 hires_chlinexy(xpos, ypos, w->w);
468 }
469 break;
470 case CTK_WIDGET_LABEL:
adamdunkels77e47062003-04-17 15:09:31 +0000471 hires_color(ctk_hires_theme.labelcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000472 text = w->widget.label.text;
adamdunkels41343612003-07-31 23:23:25 +0000473 for(i = 0; i < w->h; ++i) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000474 if(ypos >= clipy1 && ypos < clipy2) {
475 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000476 ctk_hires_cputsn(text, w->w);
adamdunkels97c19b72003-08-24 22:29:41 +0000477 tmp = w->w - (hires_wherex() - xpos);
478 if(tmp > 0) {
479 ctk_hires_cclear(tmp);
adamdunkels7e4982c2003-03-19 16:26:18 +0000480 }
481 }
482 ++ypos;
483 text += w->w;
484 }
485 break;
486 case CTK_WIDGET_BUTTON:
adamdunkels97c19b72003-08-24 22:29:41 +0000487 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000488 hires_color(ctk_hires_theme.buttonleftcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000489 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000490 ctk_hires_draw_buttonleft();
491 hires_color(ctk_hires_theme.buttoncolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000492 hires_gotoxy(xpos + 1, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000493 ctk_hires_cputsn(w->widget.button.text, w->w);
494 hires_color(ctk_hires_theme.buttonrightcolors[focus]);
495 ctk_hires_draw_buttonright();
adamdunkels7e4982c2003-03-19 16:26:18 +0000496 }
497 break;
498 case CTK_WIDGET_HYPERLINK:
adamdunkels97c19b72003-08-24 22:29:41 +0000499 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000500 hires_color(ctk_hires_theme.hyperlinkcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000501 hires_underline(1);
502 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000503 ctk_hires_cputsn(w->widget.button.text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000504 hires_underline(0);
505 }
506 break;
507 case CTK_WIDGET_TEXTENTRY:
adamdunkels97c19b72003-08-24 22:29:41 +0000508 if(yclipped) {
509 hires_color(ctk_hires_theme.textentrycolors[focus]);
510
511 if((focus & CTK_FOCUS_WIDGET) &&
512 w->widget.textentry.state != CTK_TEXTENTRY_EDIT) {
513 hires_revers(1);
514 } else {
515 hires_revers(0);
516 }
517 xscroll = 0;
518 tmp = w->w - 1;
519 if(w->widget.textentry.xpos >= tmp) {
520 xscroll = w->widget.textentry.xpos - tmp;
521 }
522 text = w->widget.textentry.text;
adamdunkels77e47062003-04-17 15:09:31 +0000523 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) {
524 hires_revers(0);
525 hires_cputcxy(xpos, ypos, '>');
adamdunkels97c19b72003-08-24 22:29:41 +0000526 text += xscroll;
adamdunkels77e47062003-04-17 15:09:31 +0000527 for(i = 0; i < w->w; ++i) {
adamdunkels97c19b72003-08-24 22:29:41 +0000528 c = *text;
adamdunkels77e47062003-04-17 15:09:31 +0000529 if(i == w->widget.textentry.xpos - xscroll) {
530 hires_revers(1);
531 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000532 hires_revers(0);
533 }
adamdunkels77e47062003-04-17 15:09:31 +0000534 if(c == 0) {
535 ctk_hires_cputc(' ');
536 } else {
537 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000538 }
adamdunkels77e47062003-04-17 15:09:31 +0000539 hires_revers(0);
adamdunkels97c19b72003-08-24 22:29:41 +0000540 ++text;
adamdunkels7e4982c2003-03-19 16:26:18 +0000541 }
adamdunkels77e47062003-04-17 15:09:31 +0000542 ctk_hires_cputc('<');
543 } else {
544 hires_cputcxy(xpos, ypos, '|');
545 /* hires_gotoxy(xpos + 1, ypos); */
546 ctk_hires_cputsn(text, w->w);
547 i = hires_wherex();
adamdunkelsd388da12003-08-20 19:55:25 +0000548 tmp = i - xpos - 1;
549 if(tmp < w->w) {
550 ctk_hires_cclear(w->w - tmp);
adamdunkels77e47062003-04-17 15:09:31 +0000551 }
552 ctk_hires_cputc('|');
adamdunkels7e4982c2003-03-19 16:26:18 +0000553 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000554 }
555 hires_revers(0);
556 break;
557 case CTK_WIDGET_ICON:
adamdunkels97c19b72003-08-24 22:29:41 +0000558 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000559 hires_color(ctk_hires_theme.iconcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000560
adamdunkels9e046b42003-04-24 17:05:41 +0000561 x = xpos;
adamdunkels7e4982c2003-03-19 16:26:18 +0000562 len = strlen(w->widget.icon.title);
563 if(x + len >= SCREEN_WIDTH) {
564 x = SCREEN_WIDTH - len;
565 }
adamdunkelsd388da12003-08-20 19:55:25 +0000566
567 tmp = ypos + 3;
568
569 if(tmp < clipy2) {
570 hires_gotoxy(x, tmp);
adamdunkels9e046b42003-04-24 17:05:41 +0000571 ctk_hires_cputsn(w->widget.icon.title, len);
572 }
573
574 hires_gotoxy(xpos, ypos);
575 if(w->widget.icon.bitmap != NULL) {
576 ctk_hires_bitmapptr = w->widget.icon.bitmap;
577 for(i = 0; i < 3; ++i) {
578 if(ypos >= clipy1 && ypos < clipy2) {
579 hires_gotoxy(xpos, ypos);
580 ctk_hires_draw_bitmapline(3);
581 }
582 ctk_hires_bitmapptr += 3 * 8;
583 ++ypos;
584 }
585
586 /* draw_bitmap_icon(w->widget.icon.bitmap);*/
587 }
588
adamdunkels7e4982c2003-03-19 16:26:18 +0000589 }
590 break;
adamdunkels77e47062003-04-17 15:09:31 +0000591 case CTK_WIDGET_BITMAP:
592 hires_color(ctk_hires_theme.bitmapcolors[focus]);
593 ctk_hires_bitmapptr = w->widget.bitmap.bitmap;
adamdunkels41343612003-07-31 23:23:25 +0000594 for(i = 0; i < w->h; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000595 if(ypos >= clipy1 && ypos < clipy2) {
596 hires_gotoxy(xpos, ypos);
597 ctk_hires_draw_bitmapline(w->w);
598 }
599 ctk_hires_bitmapptr += w->w * 8;
600 ++ypos;
601 }
602 break;
603
adamdunkels7e4982c2003-03-19 16:26:18 +0000604 default:
605 break;
606 }
607}
608/*-----------------------------------------------------------------------------------*/
609void
610ctk_draw_widget(struct ctk_widget *w,
611 unsigned char focus,
612 unsigned char clipy1,
613 unsigned char clipy2)
614{
615 struct ctk_window *win = w->window;
616 unsigned char posx, posy;
617
618 posx = win->x + 1;
619 posy = win->y + 2;
620
621 if(w == win->focused) {
622 focus |= CTK_FOCUS_WIDGET;
623 }
624
625 draw_widget(w, posx, posy,
626 clipy1, clipy2,
627 focus);
628}
629/*-----------------------------------------------------------------------------------*/
630void
adamdunkelsd7422082003-08-05 13:57:01 +0000631ctk_draw_clear_window(register struct ctk_window *window,
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000632 unsigned char focus,
633 unsigned char clipy1,
634 unsigned char clipy2)
635{
adamdunkels23b30d52003-08-15 18:46:25 +0000636 static unsigned char h;
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000637
adamdunkels77e47062003-04-17 15:09:31 +0000638 hires_color(ctk_hires_theme.windowcolors[focus]);
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000639
640 h = window->y + 2 + window->h;
641 /* Clear window contents. */
642 for(i = window->y + 2; i < h; ++i) {
adamdunkels9e046b42003-04-24 17:05:41 +0000643 if(i >= clipy1 && i <= clipy2) {
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000644 hires_cclearxy(window->x + 1, i, window->w);
645 }
646 }
647}
648/*-----------------------------------------------------------------------------------*/
649void
adamdunkels7e4982c2003-03-19 16:26:18 +0000650ctk_draw_window(register struct ctk_window *window,
651 unsigned char focus,
652 unsigned char clipy1, unsigned char clipy2)
653{
654 register struct ctk_widget *w;
adamdunkels7e4982c2003-03-19 16:26:18 +0000655 x = window->x;
656 y = window->y + 1;
657
658 ++clipy2;
659
adamdunkels9e046b42003-04-24 17:05:41 +0000660 if(clipy2 <= y) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000661 return;
662 }
adamdunkels77e47062003-04-17 15:09:31 +0000663
adamdunkels9e046b42003-04-24 17:05:41 +0000664 /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/
adamdunkels77e47062003-04-17 15:09:31 +0000665
adamdunkels7e4982c2003-03-19 16:26:18 +0000666 x1 = x + 1;
667 y1 = y + 1;
adamdunkels9e046b42003-04-24 17:05:41 +0000668 /* x2 = x1 + window->w;
669 y2 = y1 + window->h;*/
adamdunkels77e47062003-04-17 15:09:31 +0000670
adamdunkels7e4982c2003-03-19 16:26:18 +0000671 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000672 ctk_hires_windowparams.w = window->w;
673 ctk_hires_windowparams.h = window->h;
adamdunkels7e4982c2003-03-19 16:26:18 +0000674 if(clipy1 < y) {
adamdunkels77e47062003-04-17 15:09:31 +0000675 ctk_hires_windowparams.clipy1 = 0;
adamdunkels7e4982c2003-03-19 16:26:18 +0000676 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000677 ctk_hires_windowparams.clipy1 = clipy1 - y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000678 }
adamdunkels77e47062003-04-17 15:09:31 +0000679 ctk_hires_windowparams.clipy2 = clipy2 - y;
680 ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1];
681 ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus];
682 ctk_hires_windowparams.title = window->title;
683 ctk_hires_windowparams.titlelen = window->titlelen;
adamdunkels7e4982c2003-03-19 16:26:18 +0000684
adamdunkels9e046b42003-04-24 17:05:41 +0000685 if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 &&
686 ctk_hires_windowparams.clipy2 > 0) {
687 ctk_hires_draw_windowborders();
adamdunkels7e4982c2003-03-19 16:26:18 +0000688 }
adamdunkels41343612003-07-31 23:23:25 +0000689
adamdunkels7e4982c2003-03-19 16:26:18 +0000690 focus = focus & CTK_FOCUS_WINDOW;
691
692 /* Draw inactive widgets. */
693 for(w = window->inactive; w != NULL; w = w->next) {
694 draw_widget(w, x1, y1,
695 clipy1, clipy2,
696 focus);
697 }
698
699 /* Draw active widgets. */
700 for(w = window->active; w != NULL; w = w->next) {
701 wfocus = focus;
702 if(w == window->focused) {
703 wfocus |= CTK_FOCUS_WIDGET;
704 }
705 draw_widget(w, x1, y1,
706 clipy1, clipy2,
707 wfocus);
708 }
709}
710/*-----------------------------------------------------------------------------------*/
711void
712ctk_draw_dialog(register struct ctk_window *dialog)
713{
714 register struct ctk_widget *w;
715
adamdunkels77e47062003-04-17 15:09:31 +0000716 hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000717
718 /* x = (SCREEN_WIDTH - dialog->w) / 2;
719 y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */
720 x = dialog->x;
721 y = dialog->y + 1;
722
723
724 x1 = x + 1;
725 y1 = y + 1;
726 x2 = x1 + dialog->w;
727 y2 = y1 + dialog->h;
728
729
730 /* Draw dialog frame. */
731
adamdunkels97c19b72003-08-24 22:29:41 +0000732 hires_cvlinexy(x, y1, dialog->h);
733 hires_cvlinexy(x2, y1, dialog->h);
adamdunkels7e4982c2003-03-19 16:26:18 +0000734
adamdunkels97c19b72003-08-24 22:29:41 +0000735 hires_chlinexy(x1, y, dialog->w);
736 hires_chlinexy(x1, y2, dialog->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000737
738 hires_cputcxy(x, y, CH_ULCORNER);
739 hires_cputcxy(x, y2, CH_LLCORNER);
740 hires_cputcxy(x2, y, CH_URCORNER);
741 hires_cputcxy(x2, y2, CH_LRCORNER);
742
743
744 /* Clear window contents. */
adamdunkels97c19b72003-08-24 22:29:41 +0000745 for(i = y1; i < y2; ++i) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000746 hires_cclearxy(x1, i, dialog->w);
747 }
748
adamdunkels7e4982c2003-03-19 16:26:18 +0000749 /* Draw inactive widgets. */
750 for(w = dialog->inactive; w != NULL; w = w->next) {
751 draw_widget(w, x1, y1,
752 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG);
753 }
754
755
756 /* Draw active widgets. */
757 for(w = dialog->active; w != NULL; w = w->next) {
758 wfocus = CTK_FOCUS_DIALOG;
759 if(w == dialog->focused) {
760 wfocus |= CTK_FOCUS_WIDGET;
761 }
762 draw_widget(w, x1, y1,
763 0, SCREEN_HEIGHT, wfocus);
764 }
765
766}
767/*-----------------------------------------------------------------------------------*/
768void
769ctk_draw_clear(unsigned char y1, unsigned char y2)
770{
771 for(i = y1; i < y2; ++i) {
772 clear_line(i);
773 }
774}
775/*-----------------------------------------------------------------------------------*/
776static void
adamdunkelsd7422082003-08-05 13:57:01 +0000777draw_menu(register struct ctk_menu *m)
adamdunkels7e4982c2003-03-19 16:26:18 +0000778{
adamdunkels23b30d52003-08-15 18:46:25 +0000779 static unsigned char x, x2, y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000780
adamdunkels77e47062003-04-17 15:09:31 +0000781 hires_color(ctk_hires_theme.openmenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000782 x = hires_wherex();
adamdunkels77e47062003-04-17 15:09:31 +0000783 ctk_hires_cputsn(m->title, m->titlelen);
784 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000785 x2 = hires_wherex();
786 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
787 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
788 }
789 for(y = 0; y < m->nitems; ++y) {
790 if(y == m->active) {
adamdunkels77e47062003-04-17 15:09:31 +0000791 hires_color(ctk_hires_theme.activemenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000792 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000793 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000794 }
795 hires_gotoxy(x, y + 1);
796 if(m->items[y].title[0] == '-') {
adamdunkels77e47062003-04-17 15:09:31 +0000797 ctk_hires_chline(CTK_CONF_MENUWIDTH);
adamdunkels7e4982c2003-03-19 16:26:18 +0000798 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000799 ctk_hires_cputsn(m->items[y].title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000800 strlen(m->items[y].title));
801 }
adamdunkels77e47062003-04-17 15:09:31 +0000802 ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex());
adamdunkels7e4982c2003-03-19 16:26:18 +0000803 hires_revers(0);
804 }
805 hires_gotoxy(x2, 0);
adamdunkels77e47062003-04-17 15:09:31 +0000806 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000807}
808/*-----------------------------------------------------------------------------------*/
809void
810ctk_draw_menus(struct ctk_menus *menus)
811{
812 struct ctk_menu *m;
adamdunkels23b30d52003-08-15 18:46:25 +0000813
adamdunkels7e4982c2003-03-19 16:26:18 +0000814 /* Draw menus */
adamdunkels77e47062003-04-17 15:09:31 +0000815 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000816 hires_gotoxy(0, 0);
817 hires_revers(0);
adamdunkels77e47062003-04-17 15:09:31 +0000818 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000819 for(m = menus->menus->next; m != NULL; m = m->next) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000820 if(m != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000821 ctk_hires_cputsn(m->title, m->titlelen);
822 ctk_hires_cputc(' ');
adamdunkels41343612003-07-31 23:23:25 +0000823 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000824 draw_menu(m);
825 }
826 }
adamdunkels77e47062003-04-17 15:09:31 +0000827 ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() -
adamdunkels7e4982c2003-03-19 16:26:18 +0000828 strlen(menus->desktopmenu->title) - 1);
829
830 /* Draw desktopmenu */
831 if(menus->desktopmenu != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000832 ctk_hires_cputsn(menus->desktopmenu->title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000833 menus->desktopmenu->titlelen);
adamdunkels77e47062003-04-17 15:09:31 +0000834 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000835 } else {
836 draw_menu(menus->desktopmenu);
837 }
838
839}
840/*-----------------------------------------------------------------------------------*/
841unsigned char
842ctk_draw_height(void)
843{
844 return SCREEN_HEIGHT;
845}
846/*-----------------------------------------------------------------------------------*/
847unsigned char
848ctk_draw_width(void)
849{
850 return SCREEN_WIDTH;
851}
852/*-----------------------------------------------------------------------------------*/