blob: c20ed6d69bc43588551d9604c73ab0400dda112b [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 *
oliverschmidta8240ea2004-07-18 13:19:47 +000032 * $Id: ctk-hires.c,v 1.12 2004/07/18 13:19:47 oliverschmidt 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/*-----------------------------------------------------------------------------------*/
oliverschmidta8240ea2004-07-18 13:19:47 +0000170#pragma optimize(push, off)
adamdunkelsc1c84be2003-08-09 13:26:22 +0000171static void
adamdunkels7e4982c2003-03-19 16:26:18 +0000172clear_line(unsigned char line)
173{
174 lineptr = line;
adamdunkels77e47062003-04-17 15:09:31 +0000175 asm("lda %v", lineptr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000176 asm("asl");
177 asm("tax");
adamdunkels77e47062003-04-17 15:09:31 +0000178 asm("lda %v,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000179 asm("sta ptr2");
adamdunkels77e47062003-04-17 15:09:31 +0000180 asm("lda %v+1,x", ctk_hires_yhiresaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000181 asm("sta ptr2+1");
adamdunkels77e47062003-04-17 15:09:31 +0000182 asm("lda %v,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000183 asm("sta ptr1");
adamdunkels77e47062003-04-17 15:09:31 +0000184 asm("lda %v+1,x", ctk_hires_yscreenaddr);
adamdunkels7e4982c2003-03-19 16:26:18 +0000185 asm("sta ptr1+1");
186
187
188 asm("sei");
189 asm("lda $01");
190 asm("pha");
191 asm("lda #$30");
192 asm("sta $01");
193 asm("ldy #39");
adamdunkels77e47062003-04-17 15:09:31 +0000194 asm("ldx %v", lineptr);
195 asm("lda %v+%w,x", ctk_hires_theme,
196 offsetof(struct ctk_hires_theme, backgroundpatterncolors));
adamdunkels7e4982c2003-03-19 16:26:18 +0000197 asm("clearlineloop1:");
198 asm("sta (ptr1),y");
199 asm("dey");
200 asm("bpl clearlineloop1");
201 asm("pla");
202 asm("sta $01");
203 asm("cli");
204
205
adamdunkels77e47062003-04-17 15:09:31 +0000206 asm("lda %v", lineptr);
207 /* asm("and #7");*/
adamdunkels7e4982c2003-03-19 16:26:18 +0000208 asm("asl");
adamdunkels77e47062003-04-17 15:09:31 +0000209 asm("asl");
adamdunkels7e4982c2003-03-19 16:26:18 +0000210 asm("asl");
211 asm("tax");
212 asm("ldy #0");
213 asm("clearlineloop2:");
adamdunkels77e47062003-04-17 15:09:31 +0000214 asm("lda %v+%w+0,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+1,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+2,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+3,x", ctk_hires_theme,
227 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000228 asm("sta (ptr2),y");
229 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000230 asm("lda %v+%w+4,x", ctk_hires_theme,
231 offsetof(struct ctk_hires_theme, backgroundpattern));
232 asm("sta (ptr2),y");
233 asm("iny");
234 asm("lda %v+%w+5,x", ctk_hires_theme,
235 offsetof(struct ctk_hires_theme, backgroundpattern));
236 asm("sta (ptr2),y");
237 asm("iny");
238 asm("lda %v+%w+6,x", ctk_hires_theme,
239 offsetof(struct ctk_hires_theme, backgroundpattern));
240 asm("sta (ptr2),y");
241 asm("iny");
242 asm("lda %v+%w+7,x", ctk_hires_theme,
243 offsetof(struct ctk_hires_theme, backgroundpattern));
244 asm("sta (ptr2),y");
245 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000246 asm("bne clearlineloop2");
247
248 asm("inc ptr2+1");
249
250 asm("ldy #0");
251 asm("clearlineloop3:");
adamdunkels77e47062003-04-17 15:09:31 +0000252 asm("lda %v+%w+0,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+1,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+2,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+3,x", ctk_hires_theme,
265 offsetof(struct ctk_hires_theme, backgroundpattern));
adamdunkels7e4982c2003-03-19 16:26:18 +0000266 asm("sta (ptr2),y");
267 asm("iny");
adamdunkels77e47062003-04-17 15:09:31 +0000268 asm("lda %v+%w+4,x", ctk_hires_theme,
269 offsetof(struct ctk_hires_theme, backgroundpattern));
270 asm("sta (ptr2),y");
271 asm("iny");
272 asm("lda %v+%w+5,x", ctk_hires_theme,
273 offsetof(struct ctk_hires_theme, backgroundpattern));
274 asm("sta (ptr2),y");
275 asm("iny");
276 asm("lda %v+%w+6,x", ctk_hires_theme,
277 offsetof(struct ctk_hires_theme, backgroundpattern));
278 asm("sta (ptr2),y");
279 asm("iny");
280 asm("lda %v+%w+7,x", ctk_hires_theme,
281 offsetof(struct ctk_hires_theme, backgroundpattern));
282 asm("sta (ptr2),y");
283 asm("iny");
adamdunkels7e4982c2003-03-19 16:26:18 +0000284 asm("cpy #$40");
285 asm("bne clearlineloop3");
adamdunkels1de1f842004-02-16 20:57:36 +0000286
adamdunkels7e4982c2003-03-19 16:26:18 +0000287
adamdunkels1de1f842004-02-16 20:57:36 +0000288 if(lineptr == 24) {
adamdunkels1de1f842004-02-16 20:57:36 +0000289 hires_color(ctk_hires_theme.backgroundpatterncolors[24]);
290 hires_gotoxy(0, 24);
291 ctk_hires_cputsn(CONTIKI_VERSION_STRING,
292 sizeof(CONTIKI_VERSION_STRING) - 1);
293 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000294}
oliverschmidta8240ea2004-07-18 13:19:47 +0000295#pragma optimize(pop)
adamdunkels7e4982c2003-03-19 16:26:18 +0000296/*-----------------------------------------------------------------------------------*/
oliverschmidta8240ea2004-07-18 13:19:47 +0000297#pragma optimize(push, off)
adamdunkels7e4982c2003-03-19 16:26:18 +0000298static void
299nmi2(void)
300{
301 asm("pla");
302 asm("sta $01");
303 asm("pla");
304 asm("rti");
305}
oliverschmidta8240ea2004-07-18 13:19:47 +0000306#pragma optimize(pop)
adamdunkels7e4982c2003-03-19 16:26:18 +0000307/*-----------------------------------------------------------------------------------*/
oliverschmidta8240ea2004-07-18 13:19:47 +0000308#pragma optimize(push, off)
adamdunkels7e4982c2003-03-19 16:26:18 +0000309static void
310nmi(void)
311{
312 asm("sei");
313 asm("pha");
314 asm("inc $d020");
315 asm("lda $01");
316 asm("pha");
317 asm("lda #$36");
318 asm("sta $01");
319 asm("lda #>_nmi2");
320 asm("pha");
321 asm("lda #<_nmi2");
322 asm("pha");
323 asm("php");
324 asm("jmp ($0318)");
325
326 nmi2();
327}
oliverschmidta8240ea2004-07-18 13:19:47 +0000328#pragma optimize(pop)
adamdunkels7e4982c2003-03-19 16:26:18 +0000329/*-----------------------------------------------------------------------------------*/
oliverschmidta8240ea2004-07-18 13:19:47 +0000330#pragma optimize(push, off)
adamdunkels7e4982c2003-03-19 16:26:18 +0000331static void
332setup_nmi(void)
333{
334 asm("lda #<_nmi");
335 asm("sta $fffa");
336 asm("lda #>_nmi");
337 asm("sta $fffb");
338 return;
339 nmi();
340}
oliverschmidta8240ea2004-07-18 13:19:47 +0000341#pragma optimize(pop)
adamdunkels7e4982c2003-03-19 16:26:18 +0000342/*-----------------------------------------------------------------------------------*/
oliverschmidta8240ea2004-07-18 13:19:47 +0000343#pragma optimize(push, off)
adamdunkels7e4982c2003-03-19 16:26:18 +0000344void
345ctk_draw_init(void)
346{
adamdunkels77e47062003-04-17 15:09:31 +0000347 unsigned char i, *ptr1, *ptr2;
348
adamdunkels7e4982c2003-03-19 16:26:18 +0000349 setup_nmi();
350
351 /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for
352 hires/colors. */
353 VIC.ctrl1 = 0x3b; /* $D011 */
354 VIC.addr = 0x78; /* $D018 */
355 VIC.ctrl2 = 0xc8; /* $D016 */
adamdunkels7e4982c2003-03-19 16:26:18 +0000356 CIA2.pra = 0x00; /* $DD00 */
357
adamdunkels77e47062003-04-17 15:09:31 +0000358 VIC.bordercolor = ctk_hires_theme.bordercolor; /* $D020 */
359 VIC.bgcolor0 = ctk_hires_theme.screencolor; /* $D021 */
360
adamdunkels7e4982c2003-03-19 16:26:18 +0000361 /* Fill color memory. */
362 asm("sei");
363 asm("lda $01");
364 asm("pha");
365 asm("lda #$30");
366 asm("sta $01");
367 asm("ldx #0");
368 asm("lda #$c0");
369 asm("fillcolorloop:");
370 asm("sta $dc00,x");
371 asm("sta $dd00,x");
372 asm("sta $de00,x");
373 asm("sta $df00,x");
374 asm("inx");
375 asm("bne fillcolorloop");
adamdunkels77e47062003-04-17 15:09:31 +0000376
377 /* Setup sprite pointers */
378 asm("ldx #$fd");
379 asm("stx $dff8");
380 asm("inx");
381 asm("stx $dff9");
adamdunkels7e4982c2003-03-19 16:26:18 +0000382 asm("pla");
383 asm("sta $01");
384 asm("cli");
385
386 /* Fill hires memory with 0. */
387
388 asm("lda $fd");
389 asm("pha");
390 asm("lda $fe");
391 asm("pha");
392 asm("lda #0");
393 asm("sta $fd");
394 asm("lda #$e0");
395 asm("sta $fe");
396 asm("ldy #0");
397 asm("lda #0");
398 asm("clrscrnloop:");
399 asm("lda #$55");
400 asm("sta ($fd),y");
401 asm("iny");
402 asm("lda #$aa");
403 asm("sta ($fd),y");
404 asm("iny");
405 asm("bne clrscrnloop");
406 asm("inc $fe");
407 asm("lda $fe");
408 asm("cmp #$ff");
409 asm("bne clrscrnloop");
410
411 asm("ldy #$00");
412 asm("clrscrnloop2:");
413 asm("lda #$55");
414 asm("sta $ff00,y");
415 asm("iny");
416 asm("lda #$aa");
417 asm("sta $ff00,y");
418 asm("iny");
419 asm("cpy #$40");
420 asm("bne clrscrnloop2");
421
422
423 asm("pla");
424 asm("sta $fe");
425 asm("pla");
426 asm("sta $fd");
427
adamdunkels7e4982c2003-03-19 16:26:18 +0000428
adamdunkels77e47062003-04-17 15:09:31 +0000429 ctk_draw_clear(0, SCREEN_HEIGHT);
430
431 /* Setup mouse pointer sprite. */
432 asm("lda %v+%w", ctk_hires_theme,
433 offsetof(struct ctk_hires_theme, pointermaskcolor));
434 asm("sta $d027");
435 asm("lda %v+%w", ctk_hires_theme,
436 offsetof(struct ctk_hires_theme, pointercolor));
437 asm("sta $d028");
438
439 ptr1 = ctk_hires_theme.pointer;
440 ptr2 = (unsigned char *)0xff40;
441
442 for(i = 0; i < 0x80; ++i) {
443 *ptr2++ = *ptr1++;
444 }
445
adamdunkels7e4982c2003-03-19 16:26:18 +0000446 return;
447}
oliverschmidta8240ea2004-07-18 13:19:47 +0000448#pragma optimize(pop)
adamdunkels7e4982c2003-03-19 16:26:18 +0000449/*-----------------------------------------------------------------------------------*/
adamdunkelsc1c84be2003-08-09 13:26:22 +0000450static void __fastcall__
adamdunkelsd7422082003-08-05 13:57:01 +0000451draw_widget(register struct ctk_widget *w,
adamdunkels7e4982c2003-03-19 16:26:18 +0000452 unsigned char x, unsigned char y,
453 unsigned char clipy1, unsigned char clipy2,
adamdunkels97c19b72003-08-24 22:29:41 +0000454 unsigned char afocus)
adamdunkels7e4982c2003-03-19 16:26:18 +0000455{
adamdunkels23b30d52003-08-15 18:46:25 +0000456 static unsigned char xpos, ypos, xscroll;
457 static unsigned char i;
458 static char c;
459 static unsigned char len;
adamdunkelsd388da12003-08-20 19:55:25 +0000460 static unsigned char tmp;
adamdunkels97c19b72003-08-24 22:29:41 +0000461 static unsigned char yclipped;
462 static unsigned char focus;
adamdunkels23b30d52003-08-15 18:46:25 +0000463 char *text;
464
adamdunkels7e4982c2003-03-19 16:26:18 +0000465 xpos = x + w->x;
adamdunkelsd388da12003-08-20 19:55:25 +0000466 ypos = y + w->y;
adamdunkels97c19b72003-08-24 22:29:41 +0000467
468 yclipped = 0;
469 if(ypos >= clipy1 && ypos < clipy2) {
470 yclipped = 1;
471 }
472 focus = afocus;
473
adamdunkels7e4982c2003-03-19 16:26:18 +0000474
475 switch(w->type) {
476 case CTK_WIDGET_SEPARATOR:
adamdunkels77e47062003-04-17 15:09:31 +0000477 hires_color(ctk_hires_theme.separatorcolors[focus]);
adamdunkels97c19b72003-08-24 22:29:41 +0000478 if(yclipped) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000479 hires_chlinexy(xpos, ypos, w->w);
480 }
481 break;
482 case CTK_WIDGET_LABEL:
adamdunkels77e47062003-04-17 15:09:31 +0000483 hires_color(ctk_hires_theme.labelcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000484 text = w->widget.label.text;
adamdunkels41343612003-07-31 23:23:25 +0000485 for(i = 0; i < w->h; ++i) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000486 if(ypos >= clipy1 && ypos < clipy2) {
487 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000488 ctk_hires_cputsn(text, w->w);
adamdunkels97c19b72003-08-24 22:29:41 +0000489 tmp = w->w - (hires_wherex() - xpos);
490 if(tmp > 0) {
491 ctk_hires_cclear(tmp);
adamdunkels7e4982c2003-03-19 16:26:18 +0000492 }
493 }
494 ++ypos;
495 text += w->w;
496 }
497 break;
498 case CTK_WIDGET_BUTTON:
adamdunkels97c19b72003-08-24 22:29:41 +0000499 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000500 hires_color(ctk_hires_theme.buttonleftcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000501 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000502 ctk_hires_draw_buttonleft();
503 hires_color(ctk_hires_theme.buttoncolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000504 hires_gotoxy(xpos + 1, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000505 ctk_hires_cputsn(w->widget.button.text, w->w);
506 hires_color(ctk_hires_theme.buttonrightcolors[focus]);
507 ctk_hires_draw_buttonright();
adamdunkels7e4982c2003-03-19 16:26:18 +0000508 }
509 break;
510 case CTK_WIDGET_HYPERLINK:
adamdunkels97c19b72003-08-24 22:29:41 +0000511 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000512 hires_color(ctk_hires_theme.hyperlinkcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000513 hires_underline(1);
514 hires_gotoxy(xpos, ypos);
adamdunkels77e47062003-04-17 15:09:31 +0000515 ctk_hires_cputsn(w->widget.button.text, w->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000516 hires_underline(0);
517 }
518 break;
519 case CTK_WIDGET_TEXTENTRY:
adamdunkels97c19b72003-08-24 22:29:41 +0000520 if(yclipped) {
521 hires_color(ctk_hires_theme.textentrycolors[focus]);
522
523 if((focus & CTK_FOCUS_WIDGET) &&
524 w->widget.textentry.state != CTK_TEXTENTRY_EDIT) {
525 hires_revers(1);
526 } else {
527 hires_revers(0);
528 }
529 xscroll = 0;
530 tmp = w->w - 1;
531 if(w->widget.textentry.xpos >= tmp) {
532 xscroll = w->widget.textentry.xpos - tmp;
533 }
534 text = w->widget.textentry.text;
adamdunkels77e47062003-04-17 15:09:31 +0000535 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) {
536 hires_revers(0);
537 hires_cputcxy(xpos, ypos, '>');
adamdunkels97c19b72003-08-24 22:29:41 +0000538 text += xscroll;
adamdunkels77e47062003-04-17 15:09:31 +0000539 for(i = 0; i < w->w; ++i) {
adamdunkels97c19b72003-08-24 22:29:41 +0000540 c = *text;
adamdunkels77e47062003-04-17 15:09:31 +0000541 if(i == w->widget.textentry.xpos - xscroll) {
542 hires_revers(1);
543 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000544 hires_revers(0);
545 }
adamdunkels77e47062003-04-17 15:09:31 +0000546 if(c == 0) {
547 ctk_hires_cputc(' ');
548 } else {
549 ctk_hires_cputc(c);
adamdunkels7e4982c2003-03-19 16:26:18 +0000550 }
adamdunkels77e47062003-04-17 15:09:31 +0000551 hires_revers(0);
adamdunkels97c19b72003-08-24 22:29:41 +0000552 ++text;
adamdunkels7e4982c2003-03-19 16:26:18 +0000553 }
adamdunkels77e47062003-04-17 15:09:31 +0000554 ctk_hires_cputc('<');
555 } else {
556 hires_cputcxy(xpos, ypos, '|');
557 /* hires_gotoxy(xpos + 1, ypos); */
558 ctk_hires_cputsn(text, w->w);
559 i = hires_wherex();
adamdunkelsd388da12003-08-20 19:55:25 +0000560 tmp = i - xpos - 1;
561 if(tmp < w->w) {
562 ctk_hires_cclear(w->w - tmp);
adamdunkels77e47062003-04-17 15:09:31 +0000563 }
564 ctk_hires_cputc('|');
adamdunkels7e4982c2003-03-19 16:26:18 +0000565 }
adamdunkels7e4982c2003-03-19 16:26:18 +0000566 }
567 hires_revers(0);
568 break;
569 case CTK_WIDGET_ICON:
adamdunkels97c19b72003-08-24 22:29:41 +0000570 if(yclipped) {
adamdunkels77e47062003-04-17 15:09:31 +0000571 hires_color(ctk_hires_theme.iconcolors[focus]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000572
adamdunkels9e046b42003-04-24 17:05:41 +0000573 x = xpos;
adamdunkels7e4982c2003-03-19 16:26:18 +0000574 len = strlen(w->widget.icon.title);
575 if(x + len >= SCREEN_WIDTH) {
576 x = SCREEN_WIDTH - len;
577 }
adamdunkelsd388da12003-08-20 19:55:25 +0000578
579 tmp = ypos + 3;
580
581 if(tmp < clipy2) {
582 hires_gotoxy(x, tmp);
adamdunkels9e046b42003-04-24 17:05:41 +0000583 ctk_hires_cputsn(w->widget.icon.title, len);
584 }
585
586 hires_gotoxy(xpos, ypos);
587 if(w->widget.icon.bitmap != NULL) {
588 ctk_hires_bitmapptr = w->widget.icon.bitmap;
589 for(i = 0; i < 3; ++i) {
590 if(ypos >= clipy1 && ypos < clipy2) {
591 hires_gotoxy(xpos, ypos);
592 ctk_hires_draw_bitmapline(3);
593 }
594 ctk_hires_bitmapptr += 3 * 8;
595 ++ypos;
596 }
597
598 /* draw_bitmap_icon(w->widget.icon.bitmap);*/
599 }
600
adamdunkels7e4982c2003-03-19 16:26:18 +0000601 }
602 break;
adamdunkels77e47062003-04-17 15:09:31 +0000603 case CTK_WIDGET_BITMAP:
604 hires_color(ctk_hires_theme.bitmapcolors[focus]);
605 ctk_hires_bitmapptr = w->widget.bitmap.bitmap;
adamdunkels41343612003-07-31 23:23:25 +0000606 for(i = 0; i < w->h; ++i) {
adamdunkels77e47062003-04-17 15:09:31 +0000607 if(ypos >= clipy1 && ypos < clipy2) {
608 hires_gotoxy(xpos, ypos);
609 ctk_hires_draw_bitmapline(w->w);
610 }
611 ctk_hires_bitmapptr += w->w * 8;
612 ++ypos;
613 }
614 break;
615
adamdunkels7e4982c2003-03-19 16:26:18 +0000616 default:
617 break;
618 }
619}
620/*-----------------------------------------------------------------------------------*/
621void
622ctk_draw_widget(struct ctk_widget *w,
623 unsigned char focus,
624 unsigned char clipy1,
625 unsigned char clipy2)
626{
627 struct ctk_window *win = w->window;
628 unsigned char posx, posy;
629
630 posx = win->x + 1;
631 posy = win->y + 2;
632
633 if(w == win->focused) {
634 focus |= CTK_FOCUS_WIDGET;
635 }
636
637 draw_widget(w, posx, posy,
638 clipy1, clipy2,
639 focus);
640}
641/*-----------------------------------------------------------------------------------*/
642void
adamdunkelsd7422082003-08-05 13:57:01 +0000643ctk_draw_clear_window(register struct ctk_window *window,
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000644 unsigned char focus,
645 unsigned char clipy1,
646 unsigned char clipy2)
647{
adamdunkels23b30d52003-08-15 18:46:25 +0000648 static unsigned char h;
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000649
adamdunkels77e47062003-04-17 15:09:31 +0000650 hires_color(ctk_hires_theme.windowcolors[focus]);
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000651
652 h = window->y + 2 + window->h;
653 /* Clear window contents. */
654 for(i = window->y + 2; i < h; ++i) {
adamdunkels9e046b42003-04-24 17:05:41 +0000655 if(i >= clipy1 && i <= clipy2) {
adamdunkelsa6e7a8e2003-04-08 19:12:02 +0000656 hires_cclearxy(window->x + 1, i, window->w);
657 }
658 }
659}
660/*-----------------------------------------------------------------------------------*/
661void
adamdunkels7e4982c2003-03-19 16:26:18 +0000662ctk_draw_window(register struct ctk_window *window,
663 unsigned char focus,
664 unsigned char clipy1, unsigned char clipy2)
665{
666 register struct ctk_widget *w;
adamdunkels7e4982c2003-03-19 16:26:18 +0000667 x = window->x;
668 y = window->y + 1;
669
670 ++clipy2;
671
adamdunkels9e046b42003-04-24 17:05:41 +0000672 if(clipy2 <= y) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000673 return;
674 }
adamdunkels77e47062003-04-17 15:09:31 +0000675
adamdunkels9e046b42003-04-24 17:05:41 +0000676 /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/
adamdunkels77e47062003-04-17 15:09:31 +0000677
adamdunkels7e4982c2003-03-19 16:26:18 +0000678 x1 = x + 1;
679 y1 = y + 1;
adamdunkels9e046b42003-04-24 17:05:41 +0000680 /* x2 = x1 + window->w;
681 y2 = y1 + window->h;*/
adamdunkels77e47062003-04-17 15:09:31 +0000682
adamdunkels7e4982c2003-03-19 16:26:18 +0000683 hires_gotoxy(x, y);
adamdunkels77e47062003-04-17 15:09:31 +0000684 ctk_hires_windowparams.w = window->w;
685 ctk_hires_windowparams.h = window->h;
adamdunkels7e4982c2003-03-19 16:26:18 +0000686 if(clipy1 < y) {
adamdunkels77e47062003-04-17 15:09:31 +0000687 ctk_hires_windowparams.clipy1 = 0;
adamdunkels7e4982c2003-03-19 16:26:18 +0000688 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000689 ctk_hires_windowparams.clipy1 = clipy1 - y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000690 }
adamdunkels77e47062003-04-17 15:09:31 +0000691 ctk_hires_windowparams.clipy2 = clipy2 - y;
692 ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1];
693 ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus];
694 ctk_hires_windowparams.title = window->title;
695 ctk_hires_windowparams.titlelen = window->titlelen;
adamdunkels7e4982c2003-03-19 16:26:18 +0000696
adamdunkels9e046b42003-04-24 17:05:41 +0000697 if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 &&
698 ctk_hires_windowparams.clipy2 > 0) {
699 ctk_hires_draw_windowborders();
adamdunkels7e4982c2003-03-19 16:26:18 +0000700 }
adamdunkels41343612003-07-31 23:23:25 +0000701
adamdunkels7e4982c2003-03-19 16:26:18 +0000702 focus = focus & CTK_FOCUS_WINDOW;
703
704 /* Draw inactive widgets. */
705 for(w = window->inactive; w != NULL; w = w->next) {
706 draw_widget(w, x1, y1,
707 clipy1, clipy2,
708 focus);
709 }
710
711 /* Draw active widgets. */
712 for(w = window->active; w != NULL; w = w->next) {
713 wfocus = focus;
714 if(w == window->focused) {
715 wfocus |= CTK_FOCUS_WIDGET;
716 }
717 draw_widget(w, x1, y1,
718 clipy1, clipy2,
719 wfocus);
720 }
721}
722/*-----------------------------------------------------------------------------------*/
723void
724ctk_draw_dialog(register struct ctk_window *dialog)
725{
726 register struct ctk_widget *w;
727
adamdunkels77e47062003-04-17 15:09:31 +0000728 hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]);
adamdunkels7e4982c2003-03-19 16:26:18 +0000729
730 /* x = (SCREEN_WIDTH - dialog->w) / 2;
731 y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */
732 x = dialog->x;
733 y = dialog->y + 1;
734
735
736 x1 = x + 1;
737 y1 = y + 1;
738 x2 = x1 + dialog->w;
739 y2 = y1 + dialog->h;
740
741
742 /* Draw dialog frame. */
743
adamdunkels97c19b72003-08-24 22:29:41 +0000744 hires_cvlinexy(x, y1, dialog->h);
745 hires_cvlinexy(x2, y1, dialog->h);
adamdunkels7e4982c2003-03-19 16:26:18 +0000746
adamdunkels97c19b72003-08-24 22:29:41 +0000747 hires_chlinexy(x1, y, dialog->w);
748 hires_chlinexy(x1, y2, dialog->w);
adamdunkels7e4982c2003-03-19 16:26:18 +0000749
750 hires_cputcxy(x, y, CH_ULCORNER);
751 hires_cputcxy(x, y2, CH_LLCORNER);
752 hires_cputcxy(x2, y, CH_URCORNER);
753 hires_cputcxy(x2, y2, CH_LRCORNER);
754
755
756 /* Clear window contents. */
adamdunkels97c19b72003-08-24 22:29:41 +0000757 for(i = y1; i < y2; ++i) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000758 hires_cclearxy(x1, i, dialog->w);
759 }
760
adamdunkels7e4982c2003-03-19 16:26:18 +0000761 /* Draw inactive widgets. */
762 for(w = dialog->inactive; w != NULL; w = w->next) {
763 draw_widget(w, x1, y1,
764 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG);
765 }
766
767
768 /* Draw active widgets. */
769 for(w = dialog->active; w != NULL; w = w->next) {
770 wfocus = CTK_FOCUS_DIALOG;
771 if(w == dialog->focused) {
772 wfocus |= CTK_FOCUS_WIDGET;
773 }
774 draw_widget(w, x1, y1,
775 0, SCREEN_HEIGHT, wfocus);
776 }
777
778}
779/*-----------------------------------------------------------------------------------*/
780void
781ctk_draw_clear(unsigned char y1, unsigned char y2)
782{
783 for(i = y1; i < y2; ++i) {
784 clear_line(i);
785 }
786}
787/*-----------------------------------------------------------------------------------*/
788static void
adamdunkelsd7422082003-08-05 13:57:01 +0000789draw_menu(register struct ctk_menu *m)
adamdunkels7e4982c2003-03-19 16:26:18 +0000790{
adamdunkels23b30d52003-08-15 18:46:25 +0000791 static unsigned char x, x2, y;
adamdunkels7e4982c2003-03-19 16:26:18 +0000792
adamdunkels77e47062003-04-17 15:09:31 +0000793 hires_color(ctk_hires_theme.openmenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000794 x = hires_wherex();
adamdunkels77e47062003-04-17 15:09:31 +0000795 ctk_hires_cputsn(m->title, m->titlelen);
796 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000797 x2 = hires_wherex();
798 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
799 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
800 }
801 for(y = 0; y < m->nitems; ++y) {
802 if(y == m->active) {
adamdunkels77e47062003-04-17 15:09:31 +0000803 hires_color(ctk_hires_theme.activemenucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000804 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000805 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000806 }
807 hires_gotoxy(x, y + 1);
808 if(m->items[y].title[0] == '-') {
adamdunkels77e47062003-04-17 15:09:31 +0000809 ctk_hires_chline(CTK_CONF_MENUWIDTH);
adamdunkels7e4982c2003-03-19 16:26:18 +0000810 } else {
adamdunkels77e47062003-04-17 15:09:31 +0000811 ctk_hires_cputsn(m->items[y].title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000812 strlen(m->items[y].title));
813 }
adamdunkels77e47062003-04-17 15:09:31 +0000814 ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex());
adamdunkels7e4982c2003-03-19 16:26:18 +0000815 hires_revers(0);
816 }
817 hires_gotoxy(x2, 0);
adamdunkels77e47062003-04-17 15:09:31 +0000818 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000819}
820/*-----------------------------------------------------------------------------------*/
821void
822ctk_draw_menus(struct ctk_menus *menus)
823{
824 struct ctk_menu *m;
adamdunkels23b30d52003-08-15 18:46:25 +0000825
adamdunkels7e4982c2003-03-19 16:26:18 +0000826 /* Draw menus */
adamdunkels77e47062003-04-17 15:09:31 +0000827 hires_color(ctk_hires_theme.menucolor);
adamdunkels7e4982c2003-03-19 16:26:18 +0000828 hires_gotoxy(0, 0);
829 hires_revers(0);
adamdunkels77e47062003-04-17 15:09:31 +0000830 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000831 for(m = menus->menus->next; m != NULL; m = m->next) {
adamdunkels7e4982c2003-03-19 16:26:18 +0000832 if(m != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000833 ctk_hires_cputsn(m->title, m->titlelen);
834 ctk_hires_cputc(' ');
adamdunkels41343612003-07-31 23:23:25 +0000835 } else {
adamdunkels7e4982c2003-03-19 16:26:18 +0000836 draw_menu(m);
837 }
838 }
adamdunkels77e47062003-04-17 15:09:31 +0000839 ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() -
adamdunkels7e4982c2003-03-19 16:26:18 +0000840 strlen(menus->desktopmenu->title) - 1);
841
842 /* Draw desktopmenu */
843 if(menus->desktopmenu != menus->open) {
adamdunkels77e47062003-04-17 15:09:31 +0000844 ctk_hires_cputsn(menus->desktopmenu->title,
adamdunkels7e4982c2003-03-19 16:26:18 +0000845 menus->desktopmenu->titlelen);
adamdunkels77e47062003-04-17 15:09:31 +0000846 ctk_hires_cputc(' ');
adamdunkels7e4982c2003-03-19 16:26:18 +0000847 } else {
848 draw_menu(menus->desktopmenu);
849 }
850
851}
852/*-----------------------------------------------------------------------------------*/
853unsigned char
854ctk_draw_height(void)
855{
856 return SCREEN_HEIGHT;
857}
858/*-----------------------------------------------------------------------------------*/
859unsigned char
860ctk_draw_width(void)
861{
862 return SCREEN_WIDTH;
863}
864/*-----------------------------------------------------------------------------------*/
adamdunkels0a08fda2004-07-04 18:33:07 +0000865unsigned char
866ctk_arch_isprint(char c)
867{
868 return isprint(c);
869}