blob: 411d927d9cbbc7e97c7189b6a3b1b62e9be2c284 [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 *
adamdunkelsd388da12003-08-20 19:55:25 +000035 * $Id: ctk-hires.c,v 1.7 2003/08/20 19:55:25 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;
adamdunkels7e4982c2003-03-19 16:26:18 +000079/*-----------------------------------------------------------------------------------*/
80/* Tables. */
81
adamdunkels77e47062003-04-17 15:09:31 +000082unsigned short ctk_hires_yscreenaddr[25] =
adamdunkels7e4982c2003-03-19 16:26:18 +000083 {0 * SCREEN_WIDTH + SCREENADDR, 1 * SCREEN_WIDTH + SCREENADDR,
84 2 * SCREEN_WIDTH + SCREENADDR, 3 * SCREEN_WIDTH + SCREENADDR,
85 4 * SCREEN_WIDTH + SCREENADDR, 5 * SCREEN_WIDTH + SCREENADDR,
86 6 * SCREEN_WIDTH + SCREENADDR, 7 * SCREEN_WIDTH + SCREENADDR,
87 8 * SCREEN_WIDTH + SCREENADDR, 9 * SCREEN_WIDTH + SCREENADDR,
88 10 * SCREEN_WIDTH + SCREENADDR, 11 * SCREEN_WIDTH + SCREENADDR,
89 12 * SCREEN_WIDTH + SCREENADDR, 13 * SCREEN_WIDTH + SCREENADDR,
90 14 * SCREEN_WIDTH + SCREENADDR, 15 * SCREEN_WIDTH + SCREENADDR,
91 16 * SCREEN_WIDTH + SCREENADDR, 17 * SCREEN_WIDTH + SCREENADDR,
92 18 * SCREEN_WIDTH + SCREENADDR, 19 * SCREEN_WIDTH + SCREENADDR,
93 20 * SCREEN_WIDTH + SCREENADDR, 21 * SCREEN_WIDTH + SCREENADDR,
94 22 * SCREEN_WIDTH + SCREENADDR, 23 * SCREEN_WIDTH + SCREENADDR,
95 24 * SCREEN_WIDTH + SCREENADDR};
96
adamdunkels77e47062003-04-17 15:09:31 +000097unsigned short ctk_hires_yhiresaddr[25] =
adamdunkels7e4982c2003-03-19 16:26:18 +000098 {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR,
99 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR,
100 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR,
101 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR,
102 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR,
103 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR,
104 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR,
105 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR,
106 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR,
107 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR,
108 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR,
109 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR,
110 24 * 320 + HIRESADDR};
adamdunkels77e47062003-04-17 15:09:31 +0000111extern struct ctk_hires_theme ctk_hires_theme;
112struct ctk_hires_theme *ctk_hires_theme_ptr = &ctk_hires_theme;
adamdunkels7e4982c2003-03-19 16:26:18 +0000113/*-----------------------------------------------------------------------------------*/
adamdunkels77e47062003-04-17 15:09:31 +0000114#define hires_wherex() ctk_hires_cursx
115#define hires_revers(c) ctk_hires_reversed = c
116#define hires_color(c) ctk_hires_color = c
117#define hires_underline(c) ctk_hires_underline = c
adamdunkels7e4982c2003-03-19 16:26:18 +0000118/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000119static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000120hires_cvline(unsigned char length)
121{
adamdunkels23b30d52003-08-15 18:46:25 +0000122 static unsigned char i;
adamdunkels7e4982c2003-03-19 16:26:18 +0000123
124 for(i = 0; i < length; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000125 ctk_hires_cputc('|');
126 --ctk_hires_cursx;
127 ++ctk_hires_cursy;
adamdunkels7e4982c2003-03-19 16:26:18 +0000128 }
129}
130/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000131static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000132hires_gotoxy(unsigned char x, unsigned char y)
133{
adamdunkels77e47062003-04-17 15:09:31 +0000134 ctk_hires_cursx = x;
135 ctk_hires_cursy = y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000136}
137/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000138static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000139hires_cclearxy(unsigned char x, unsigned char y, unsigned char length)
140{
141 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000142 ctk_hires_cclear(length);
adamdunkels7e4982c2003-03-19 16:26:18 +0000143}
144/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000145static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000146hires_chlinexy(unsigned char x, unsigned char y, unsigned char length)
147{
148 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000149 ctk_hires_chline(length);
adamdunkels7e4982c2003-03-19 16:26:18 +0000150}
151/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000152static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000153hires_cvlinexy(unsigned char x, unsigned char y, unsigned char length)
154{
155 hires_gotoxy(x, y);
156 hires_cvline(length);
157}
158/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000159static void __fastcall__
adamdunkels7e4982c2003-03-19 16:26:18 +0000160hires_cputcxy(unsigned char x, unsigned char y, char c)
161{
162 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000163 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000164}
165/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000166static void
adamdunkels7e4982c2003-03-19 16:26:18 +0000167clear_line(unsigned char line)
168{
169 lineptr = line;
adamdunkels77e47062003-04-17 15:09:31 +0000170 asm("lda %v", lineptr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000171 asm("asl");
172 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000173 asm("lda %v,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000174 asm("sta ptr2");
adamdunkels77e47062003-04-17 15:09:31 +0000175 asm("lda %v+1,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000176 asm("sta ptr2+1");
adamdunkels77e47062003-04-17 15:09:31 +0000177 asm("lda %v,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000178 asm("sta ptr1");
adamdunkels77e47062003-04-17 15:09:31 +0000179 asm("lda %v+1,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000180 asm("sta ptr1+1");
181
182
183 asm("sei");
184 asm("lda $01");
185 asm("pha");
186 asm("lda #$30");
187 asm("sta $01");
188 asm("ldy #39");
adamdunkels77e47062003-04-17 15:09:31 +0000189 asm("ldx %v", lineptr);
190 asm("lda %v+%w,x", ctk_hires_theme,
191 offsetof(struct ctk_hires_theme, backgroundpatterncolors));
adamdunkels7e4982c2003-03-19 16:26:18 +0000192 asm("clearlineloop1:");
193 asm("sta (ptr1),y");
194 asm("dey");
195 asm("bpl clearlineloop1");
196 asm("pla");
197 asm("sta $01");
198 asm("cli");
199
200
adamdunkels77e47062003-04-17 15:09:31 +0000201 asm("lda %v", lineptr);
202 /* asm("and #7");*/
adamdunkels7e4982c2003-03-19 16:26:18 +0000203 asm("asl");
adamdunkels77e47062003-04-17 15:09:31 +0000204 asm("asl");
adamdunkels7e4982c2003-03-19 16:26:18 +0000205 asm("asl");
206 asm("tax");
207 asm("ldy #0");
208 asm("clearlineloop2:");
adamdunkels77e47062003-04-17 15:09:31 +0000209 asm("lda %v+%w+0,x", ctk_hires_theme,
210 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000211 asm("sta (ptr2),y");
212 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000213 asm("lda %v+%w+1,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+2,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+3,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+4,x", ctk_hires_theme,
226 offsetof(struct ctk_hires_theme, backgroundpattern));
227 asm("sta (ptr2),y");
228 asm("iny");
229 asm("lda %v+%w+5,x", ctk_hires_theme,
230 offsetof(struct ctk_hires_theme, backgroundpattern));
231 asm("sta (ptr2),y");
232 asm("iny");
233 asm("lda %v+%w+6,x", ctk_hires_theme,
234 offsetof(struct ctk_hires_theme, backgroundpattern));
235 asm("sta (ptr2),y");
236 asm("iny");
237 asm("lda %v+%w+7,x", ctk_hires_theme,
238 offsetof(struct ctk_hires_theme, backgroundpattern));
239 asm("sta (ptr2),y");
240 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000241 asm("bne clearlineloop2");
242
243 asm("inc ptr2+1");
244
245 asm("ldy #0");
246 asm("clearlineloop3:");
adamdunkels77e47062003-04-17 15:09:31 +0000247 asm("lda %v+%w+0,x", ctk_hires_theme,
248 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000249 asm("sta (ptr2),y");
250 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000251 asm("lda %v+%w+1,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+2,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+3,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+4,x", ctk_hires_theme,
264 offsetof(struct ctk_hires_theme, backgroundpattern));
265 asm("sta (ptr2),y");
266 asm("iny");
267 asm("lda %v+%w+5,x", ctk_hires_theme,
268 offsetof(struct ctk_hires_theme, backgroundpattern));
269 asm("sta (ptr2),y");
270 asm("iny");
271 asm("lda %v+%w+6,x", ctk_hires_theme,
272 offsetof(struct ctk_hires_theme, backgroundpattern));
273 asm("sta (ptr2),y");
274 asm("iny");
275 asm("lda %v+%w+7,x", ctk_hires_theme,
276 offsetof(struct ctk_hires_theme, backgroundpattern));
277 asm("sta (ptr2),y");
278 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000279 asm("cpy #$40");
280 asm("bne clearlineloop3");
281
282}
283/*-----------------------------------------------------------------------------------*/
284static void
285nmi2(void)
286{
287 asm("pla");
288 asm("sta $01");
289 asm("pla");
290 asm("rti");
291}
292/*-----------------------------------------------------------------------------------*/
293static void
294nmi(void)
295{
296 asm("sei");
297 asm("pha");
298 asm("inc $d020");
299 asm("lda $01");
300 asm("pha");
301 asm("lda #$36");
302 asm("sta $01");
303 asm("lda #>_nmi2");
304 asm("pha");
305 asm("lda #<_nmi2");
306 asm("pha");
307 asm("php");
308 asm("jmp ($0318)");
309
310 nmi2();
311}
312/*-----------------------------------------------------------------------------------*/
313static void
314setup_nmi(void)
315{
316 asm("lda #<_nmi");
317 asm("sta $fffa");
318 asm("lda #>_nmi");
319 asm("sta $fffb");
320 return;
321 nmi();
322}
323/*-----------------------------------------------------------------------------------*/
324void
325ctk_draw_init(void)
326{
adamdunkels77e47062003-04-17 15:09:31 +0000327 unsigned char i, *ptr1, *ptr2;
328
adamdunkels7e4982c2003-03-19 16:26:18 +0000329 setup_nmi();
330
331 /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for
332 hires/colors. */
333 VIC.ctrl1 = 0x3b; /* $D011 */
334 VIC.addr = 0x78; /* $D018 */
335 VIC.ctrl2 = 0xc8; /* $D016 */
adamdunkels7e4982c2003-03-19 16:26:18 +0000336 CIA2.pra = 0x00; /* $DD00 */
337
adamdunkels77e47062003-04-17 15:09:31 +0000338 VIC.bordercolor = ctk_hires_theme.bordercolor; /* $D020 */
339 VIC.bgcolor0 = ctk_hires_theme.screencolor; /* $D021 */
340
adamdunkels7e4982c2003-03-19 16:26:18 +0000341 /* Fill color memory. */
342 asm("sei");
343 asm("lda $01");
344 asm("pha");
345 asm("lda #$30");
346 asm("sta $01");
347 asm("ldx #0");
348 asm("lda #$c0");
349 asm("fillcolorloop:");
350 asm("sta $dc00,x");
351 asm("sta $dd00,x");
352 asm("sta $de00,x");
353 asm("sta $df00,x");
354 asm("inx");
355 asm("bne fillcolorloop");
adamdunkels77e47062003-04-17 15:09:31 +0000356
357 /* Setup sprite pointers */
358 asm("ldx #$fd");
359 asm("stx $dff8");
360 asm("inx");
361 asm("stx $dff9");
adamdunkels7e4982c2003-03-19 16:26:18 +0000362 asm("pla");
363 asm("sta $01");
364 asm("cli");
365
366 /* Fill hires memory with 0. */
367
368 asm("lda $fd");
369 asm("pha");
370 asm("lda $fe");
371 asm("pha");
372 asm("lda #0");
373 asm("sta $fd");
374 asm("lda #$e0");
375 asm("sta $fe");
376 asm("ldy #0");
377 asm("lda #0");
378 asm("clrscrnloop:");
379 asm("lda #$55");
380 asm("sta ($fd),y");
381 asm("iny");
382 asm("lda #$aa");
383 asm("sta ($fd),y");
384 asm("iny");
385 asm("bne clrscrnloop");
386 asm("inc $fe");
387 asm("lda $fe");
388 asm("cmp #$ff");
389 asm("bne clrscrnloop");
390
391 asm("ldy #$00");
392 asm("clrscrnloop2:");
393 asm("lda #$55");
394 asm("sta $ff00,y");
395 asm("iny");
396 asm("lda #$aa");
397 asm("sta $ff00,y");
398 asm("iny");
399 asm("cpy #$40");
400 asm("bne clrscrnloop2");
401
402
403 asm("pla");
404 asm("sta $fe");
405 asm("pla");
406 asm("sta $fd");
407
adamdunkels7e4982c2003-03-19 16:26:18 +0000408
adamdunkels77e47062003-04-17 15:09:31 +0000409 ctk_draw_clear(0, SCREEN_HEIGHT);
410
411 /* Setup mouse pointer sprite. */
412 asm("lda %v+%w", ctk_hires_theme,
413 offsetof(struct ctk_hires_theme, pointermaskcolor));
414 asm("sta $d027");
415 asm("lda %v+%w", ctk_hires_theme,
416 offsetof(struct ctk_hires_theme, pointercolor));
417 asm("sta $d028");
418
419 ptr1 = ctk_hires_theme.pointer;
420 ptr2 = (unsigned char *)0xff40;
421
422 for(i = 0; i < 0x80; ++i) {
423 *ptr2++ = *ptr1++;
424 }
425
adamdunkels7e4982c2003-03-19 16:26:18 +0000426 return;
427}
428/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000429static void __fastcall__
adamdunkelsd7422082003-08-05 13:57:01 +0000430draw_widget(register struct ctk_widget *w,
adamdunkels7e4982c2003-03-19 16:26:18 +0000431 unsigned char x, unsigned char y,
432 unsigned char clipy1, unsigned char clipy2,
433 unsigned char focus)
434{
adamdunkels23b30d52003-08-15 18:46:25 +0000435 static unsigned char xpos, ypos, xscroll;
436 static unsigned char i;
437 static char c;
438 static unsigned char len;
adamdunkelsd388da12003-08-20 19:55:25 +0000439 static unsigned char tmp;
adamdunkels23b30d52003-08-15 18:46:25 +0000440 char *text;
441
adamdunkels7e4982c2003-03-19 16:26:18 +0000442 xpos = x + w->x;
adamdunkelsd388da12003-08-20 19:55:25 +0000443 ypos = y + w->y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000444
445 switch(w->type) {
446 case CTK_WIDGET_SEPARATOR:
adamdunkels77e47062003-04-17 15:09:31 +0000447 hires_color(ctk_hires_theme.separatorcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000448 if(ypos >= clipy1 && ypos < clipy2) {
449 hires_chlinexy(xpos, ypos, w->w);
450 }
451 break;
452 case CTK_WIDGET_LABEL:
adamdunkels77e47062003-04-17 15:09:31 +0000453 hires_color(ctk_hires_theme.labelcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000454 text = w->widget.label.text;
adamdunkels41343612003-07-31 23:23:25 +0000455 for(i = 0; i < w->h; ++i) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000456 if(ypos >= clipy1 && ypos < clipy2) {
457 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000458 ctk_hires_cputsn(text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000459 if(w->w - (hires_wherex() - xpos) > 0) {
adamdunkels77e47062003-04-17 15:09:31 +0000460 ctk_hires_cclear(w->w - (hires_wherex() - xpos));
adamdunkels7e4982c2003-03-19 16:26:18 +0000461 }
462 }
463 ++ypos;
464 text += w->w;
465 }
466 break;
467 case CTK_WIDGET_BUTTON:
468 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000469 hires_color(ctk_hires_theme.buttonleftcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000470 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000471 ctk_hires_draw_buttonleft();
472 hires_color(ctk_hires_theme.buttoncolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000473 hires_gotoxy(xpos + 1, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000474 ctk_hires_cputsn(w->widget.button.text, w->w);
475 hires_color(ctk_hires_theme.buttonrightcolors[focus]);
476 ctk_hires_draw_buttonright();
adamdunkels7e4982c2003-03-19 16:26:18 +0000477 }
478 break;
479 case CTK_WIDGET_HYPERLINK:
480 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000481 hires_color(ctk_hires_theme.hyperlinkcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000482 hires_underline(1);
483 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000484 ctk_hires_cputsn(w->widget.button.text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000485 hires_underline(0);
486 }
487 break;
488 case CTK_WIDGET_TEXTENTRY:
adamdunkels77e47062003-04-17 15:09:31 +0000489 hires_color(ctk_hires_theme.textentrycolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000490 text = w->widget.textentry.text;
491 if(focus & CTK_FOCUS_WIDGET &&
492 w->widget.textentry.state != CTK_TEXTENTRY_EDIT) {
493 hires_revers(1);
494 } else {
495 hires_revers(0);
496 }
497 xscroll = 0;
adamdunkelsd388da12003-08-20 19:55:25 +0000498 tmp = w->w - 1;
499 if(w->widget.textentry.xpos >= tmp) {
500 xscroll = w->widget.textentry.xpos - tmp;
adamdunkels7e4982c2003-03-19 16:26:18 +0000501 }
adamdunkels77e47062003-04-17 15:09:31 +0000502 if(ypos >= clipy1 && ypos < clipy2) {
503 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) {
504 hires_revers(0);
505 hires_cputcxy(xpos, ypos, '>');
506 for(i = 0; i < w->w; ++i) {
507 c = text[i + xscroll];
508 if(i == w->widget.textentry.xpos - xscroll) {
509 hires_revers(1);
510 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000511 hires_revers(0);
512 }
adamdunkels77e47062003-04-17 15:09:31 +0000513 if(c == 0) {
514 ctk_hires_cputc(' ');
515 } else {
516 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000517 }
adamdunkels77e47062003-04-17 15:09:31 +0000518 hires_revers(0);
adamdunkels7e4982c2003-03-19 16:26:18 +0000519 }
adamdunkels77e47062003-04-17 15:09:31 +0000520 ctk_hires_cputc('<');
521 } else {
522 hires_cputcxy(xpos, ypos, '|');
523 /* hires_gotoxy(xpos + 1, ypos); */
524 ctk_hires_cputsn(text, w->w);
525 i = hires_wherex();
adamdunkelsd388da12003-08-20 19:55:25 +0000526 tmp = i - xpos - 1;
527 if(tmp < w->w) {
528 ctk_hires_cclear(w->w - tmp);
adamdunkels77e47062003-04-17 15:09:31 +0000529 }
530 ctk_hires_cputc('|');
adamdunkels7e4982c2003-03-19 16:26:18 +0000531 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000532 }
533 hires_revers(0);
534 break;
535 case CTK_WIDGET_ICON:
536 if(ypos >= clipy1 && ypos < clipy2) {
adamdunkels77e47062003-04-17 15:09:31 +0000537 hires_color(ctk_hires_theme.iconcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000538
adamdunkels9e046b42003-04-24 17:05:41 +0000539 x = xpos;
adamdunkels7e4982c2003-03-19 16:26:18 +0000540 len = strlen(w->widget.icon.title);
541 if(x + len >= SCREEN_WIDTH) {
542 x = SCREEN_WIDTH - len;
543 }
adamdunkelsd388da12003-08-20 19:55:25 +0000544
545 tmp = ypos + 3;
546
547 if(tmp < clipy2) {
548 hires_gotoxy(x, tmp);
adamdunkels9e046b42003-04-24 17:05:41 +0000549 ctk_hires_cputsn(w->widget.icon.title, len);
550 }
551
552 hires_gotoxy(xpos, ypos);
553 if(w->widget.icon.bitmap != NULL) {
554 ctk_hires_bitmapptr = w->widget.icon.bitmap;
555 for(i = 0; i < 3; ++i) {
556 if(ypos >= clipy1 && ypos < clipy2) {
557 hires_gotoxy(xpos, ypos);
558 ctk_hires_draw_bitmapline(3);
559 }
560 ctk_hires_bitmapptr += 3 * 8;
561 ++ypos;
562 }
563
564 /* draw_bitmap_icon(w->widget.icon.bitmap);*/
565 }
566
adamdunkels7e4982c2003-03-19 16:26:18 +0000567 }
568 break;
adamdunkels77e47062003-04-17 15:09:31 +0000569 case CTK_WIDGET_BITMAP:
570 hires_color(ctk_hires_theme.bitmapcolors[focus]);
571 ctk_hires_bitmapptr = w->widget.bitmap.bitmap;
adamdunkels41343612003-07-31 23:23:25 +0000572 for(i = 0; i < w->h; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000573 if(ypos >= clipy1 && ypos < clipy2) {
574 hires_gotoxy(xpos, ypos);
575 ctk_hires_draw_bitmapline(w->w);
576 }
577 ctk_hires_bitmapptr += w->w * 8;
578 ++ypos;
579 }
580 break;
581
adamdunkels7e4982c2003-03-19 16:26:18 +0000582 default:
583 break;
584 }
585}
586/*-----------------------------------------------------------------------------------*/
587void
588ctk_draw_widget(struct ctk_widget *w,
589 unsigned char focus,
590 unsigned char clipy1,
591 unsigned char clipy2)
592{
593 struct ctk_window *win = w->window;
594 unsigned char posx, posy;
595
596 posx = win->x + 1;
597 posy = win->y + 2;
598
599 if(w == win->focused) {
600 focus |= CTK_FOCUS_WIDGET;
601 }
602
603 draw_widget(w, posx, posy,
604 clipy1, clipy2,
605 focus);
606}
607/*-----------------------------------------------------------------------------------*/
608void
adamdunkelsd7422082003-08-05 13:57:01 +0000609ctk_draw_clear_window(register struct ctk_window *window,
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000610 unsigned char focus,
611 unsigned char clipy1,
612 unsigned char clipy2)
613{
adamdunkels23b30d52003-08-15 18:46:25 +0000614 static unsigned char h;
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000615
adamdunkels77e47062003-04-17 15:09:31 +0000616 hires_color(ctk_hires_theme.windowcolors[focus]);
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000617
618 h = window->y + 2 + window->h;
619 /* Clear window contents. */
620 for(i = window->y + 2; i < h; ++i) {
adamdunkels9e046b42003-04-24 17:05:41 +0000621 if(i >= clipy1 && i <= clipy2) {
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000622 hires_cclearxy(window->x + 1, i, window->w);
623 }
624 }
625}
626/*-----------------------------------------------------------------------------------*/
627void
adamdunkels7e4982c2003-03-19 16:26:18 +0000628ctk_draw_window(register struct ctk_window *window,
629 unsigned char focus,
630 unsigned char clipy1, unsigned char clipy2)
631{
632 register struct ctk_widget *w;
adamdunkels7e4982c2003-03-19 16:26:18 +0000633 x = window->x;
634 y = window->y + 1;
635
636 ++clipy2;
637
adamdunkels9e046b42003-04-24 17:05:41 +0000638 if(clipy2 <= y) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000639 return;
640 }
adamdunkels77e47062003-04-17 15:09:31 +0000641
adamdunkels9e046b42003-04-24 17:05:41 +0000642 /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/
adamdunkels77e47062003-04-17 15:09:31 +0000643
adamdunkels7e4982c2003-03-19 16:26:18 +0000644 x1 = x + 1;
645 y1 = y + 1;
adamdunkels9e046b42003-04-24 17:05:41 +0000646 /* x2 = x1 + window->w;
647 y2 = y1 + window->h;*/
adamdunkels77e47062003-04-17 15:09:31 +0000648
adamdunkels7e4982c2003-03-19 16:26:18 +0000649 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000650 ctk_hires_windowparams.w = window->w;
651 ctk_hires_windowparams.h = window->h;
adamdunkels7e4982c2003-03-19 16:26:18 +0000652 if(clipy1 < y) {
adamdunkels77e47062003-04-17 15:09:31 +0000653 ctk_hires_windowparams.clipy1 = 0;
adamdunkels7e4982c2003-03-19 16:26:18 +0000654 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000655 ctk_hires_windowparams.clipy1 = clipy1 - y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000656 }
adamdunkels77e47062003-04-17 15:09:31 +0000657 ctk_hires_windowparams.clipy2 = clipy2 - y;
658 ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1];
659 ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus];
660 ctk_hires_windowparams.title = window->title;
661 ctk_hires_windowparams.titlelen = window->titlelen;
adamdunkels7e4982c2003-03-19 16:26:18 +0000662
adamdunkels9e046b42003-04-24 17:05:41 +0000663 if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 &&
664 ctk_hires_windowparams.clipy2 > 0) {
665 ctk_hires_draw_windowborders();
adamdunkels7e4982c2003-03-19 16:26:18 +0000666 }
adamdunkels41343612003-07-31 23:23:25 +0000667
adamdunkels7e4982c2003-03-19 16:26:18 +0000668 focus = focus & CTK_FOCUS_WINDOW;
669
670 /* Draw inactive widgets. */
671 for(w = window->inactive; w != NULL; w = w->next) {
672 draw_widget(w, x1, y1,
673 clipy1, clipy2,
674 focus);
675 }
676
677 /* Draw active widgets. */
678 for(w = window->active; w != NULL; w = w->next) {
679 wfocus = focus;
680 if(w == window->focused) {
681 wfocus |= CTK_FOCUS_WIDGET;
682 }
683 draw_widget(w, x1, y1,
684 clipy1, clipy2,
685 wfocus);
686 }
687}
688/*-----------------------------------------------------------------------------------*/
689void
690ctk_draw_dialog(register struct ctk_window *dialog)
691{
692 register struct ctk_widget *w;
693
adamdunkels77e47062003-04-17 15:09:31 +0000694 hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000695
696 /* x = (SCREEN_WIDTH - dialog->w) / 2;
697 y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */
698 x = dialog->x;
699 y = dialog->y + 1;
700
701
702 x1 = x + 1;
703 y1 = y + 1;
704 x2 = x1 + dialog->w;
705 y2 = y1 + dialog->h;
706
707
708 /* Draw dialog frame. */
709
710 hires_cvlinexy(x, y1,
711 dialog->h);
712 hires_cvlinexy(x2, y1,
713 dialog->h);
714
715 hires_chlinexy(x1, y,
716 dialog->w);
717 hires_chlinexy(x1, y2,
718 dialog->w);
719
720 hires_cputcxy(x, y, CH_ULCORNER);
721 hires_cputcxy(x, y2, CH_LLCORNER);
722 hires_cputcxy(x2, y, CH_URCORNER);
723 hires_cputcxy(x2, y2, CH_LRCORNER);
724
725
726 /* Clear window contents. */
727 for(i = y1; i < y2; ++i) {
728 hires_cclearxy(x1, i, dialog->w);
729 }
730
adamdunkels7e4982c2003-03-19 16:26:18 +0000731 /* Draw inactive widgets. */
732 for(w = dialog->inactive; w != NULL; w = w->next) {
733 draw_widget(w, x1, y1,
734 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG);
735 }
736
737
738 /* Draw active widgets. */
739 for(w = dialog->active; w != NULL; w = w->next) {
740 wfocus = CTK_FOCUS_DIALOG;
741 if(w == dialog->focused) {
742 wfocus |= CTK_FOCUS_WIDGET;
743 }
744 draw_widget(w, x1, y1,
745 0, SCREEN_HEIGHT, wfocus);
746 }
747
748}
749/*-----------------------------------------------------------------------------------*/
750void
751ctk_draw_clear(unsigned char y1, unsigned char y2)
752{
753 for(i = y1; i < y2; ++i) {
754 clear_line(i);
755 }
756}
757/*-----------------------------------------------------------------------------------*/
758static void
adamdunkelsd7422082003-08-05 13:57:01 +0000759draw_menu(register struct ctk_menu *m)
adamdunkels7e4982c2003-03-19 16:26:18 +0000760{
adamdunkels23b30d52003-08-15 18:46:25 +0000761 static unsigned char x, x2, y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000762
adamdunkels77e47062003-04-17 15:09:31 +0000763 hires_color(ctk_hires_theme.openmenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000764 x = hires_wherex();
adamdunkels77e47062003-04-17 15:09:31 +0000765 ctk_hires_cputsn(m->title, m->titlelen);
766 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000767 x2 = hires_wherex();
768 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
769 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
770 }
771 for(y = 0; y < m->nitems; ++y) {
772 if(y == m->active) {
adamdunkels77e47062003-04-17 15:09:31 +0000773 hires_color(ctk_hires_theme.activemenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000774 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000775 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000776 }
777 hires_gotoxy(x, y + 1);
778 if(m->items[y].title[0] == '-') {
adamdunkels77e47062003-04-17 15:09:31 +0000779 ctk_hires_chline(CTK_CONF_MENUWIDTH);
adamdunkels7e4982c2003-03-19 16:26:18 +0000780 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000781 ctk_hires_cputsn(m->items[y].title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000782 strlen(m->items[y].title));
783 }
adamdunkels77e47062003-04-17 15:09:31 +0000784 ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex());
adamdunkels7e4982c2003-03-19 16:26:18 +0000785 hires_revers(0);
786 }
787 hires_gotoxy(x2, 0);
adamdunkels77e47062003-04-17 15:09:31 +0000788 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000789}
790/*-----------------------------------------------------------------------------------*/
791void
792ctk_draw_menus(struct ctk_menus *menus)
793{
794 struct ctk_menu *m;
adamdunkels23b30d52003-08-15 18:46:25 +0000795
adamdunkels7e4982c2003-03-19 16:26:18 +0000796 /* Draw menus */
adamdunkels77e47062003-04-17 15:09:31 +0000797 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000798 hires_gotoxy(0, 0);
799 hires_revers(0);
adamdunkels77e47062003-04-17 15:09:31 +0000800 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000801 for(m = menus->menus->next; m != NULL; m = m->next) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000802 if(m != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000803 ctk_hires_cputsn(m->title, m->titlelen);
804 ctk_hires_cputc(' ');
adamdunkels41343612003-07-31 23:23:25 +0000805 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000806 draw_menu(m);
807 }
808 }
adamdunkels77e47062003-04-17 15:09:31 +0000809 ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() -
adamdunkels7e4982c2003-03-19 16:26:18 +0000810 strlen(menus->desktopmenu->title) - 1);
811
812 /* Draw desktopmenu */
813 if(menus->desktopmenu != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000814 ctk_hires_cputsn(menus->desktopmenu->title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000815 menus->desktopmenu->titlelen);
adamdunkels77e47062003-04-17 15:09:31 +0000816 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000817 } else {
818 draw_menu(menus->desktopmenu);
819 }
820
821}
822/*-----------------------------------------------------------------------------------*/
823unsigned char
824ctk_draw_height(void)
825{
826 return SCREEN_HEIGHT;
827}
828/*-----------------------------------------------------------------------------------*/
829unsigned char
830ctk_draw_width(void)
831{
832 return SCREEN_WIDTH;
833}
834/*-----------------------------------------------------------------------------------*/