1 /* Public Domain Curses */
5 RCSID("$Id: pdcdisp.c,v 1.35 2008/07/14 04:24:52 wmcbrine Exp $")
12 # define A(x) ((chtype)x | A_ALTCHARSET)
16 A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8), A(9),
17 A(10), A(11), A(12), A(13), A(14), A(15), A(16), A(17), A(18),
18 A(19), A(20), A(21), A(22), A(23), A(24), A(25), A(26), A(27),
19 A(28), A(29), A(30), A(31), ' ', '!', '"', '#', '$', '%', '&',
22 A(0x1a), A(0x1b), A(0x18), A(0x19),
28 '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
29 '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
30 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
31 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
37 0xf8, 0xf1, 0xb0, A(0x0f), 0xd9, 0xbf, 0xda, 0xc0, 0xc5, 0x2d,
38 0x2d, 0xc4, 0x2d, 0x5f, 0xc3, 0xb4, 0xc1, 0xc2, 0xb3, 0xf3,
39 0xf2, 0xe3, 0xd8, 0x9c, 0xf9,
48 Uint32 pdc_lastupdate
= 0;
50 #define MAXRECT 200 /* maximum number of rects to queue up before
51 an update is forced; the number was chosen
54 static SDL_Rect uprect
[MAXRECT
]; /* table of rects to update */
55 static chtype oldch
= (chtype
)(-1); /* current attribute */
56 static int rectcount
= 0; /* index into uprect */
57 static short foregr
= -2, backgr
= -2; /* current foreground, background */
59 /* do the real updates on a delay */
61 void PDC_update_rects(void)
65 /* if the maximum number of rects has been reached, we're
66 probably better off doing a full screen update */
68 if (rectcount
== MAXRECT
)
71 SDL_UpdateRects(pdc_screen
, rectcount
, uprect
);
73 pdc_lastupdate
= SDL_GetTicks();
78 /* set the font colors to match the chtype's attribute */
80 static void _set_attr(chtype ch
)
82 ch
&= (A_COLOR
|A_BOLD
|A_BLINK
|A_REVERSE
);
91 PDC_pair_content(PAIR_NUMBER(ch
), &newfg
, &newbg
);
93 newfg
|= (ch
& A_BOLD
) ? 8 : 0;
94 newbg
|= (ch
& A_BLINK
) ? 8 : 0;
105 SDL_SetPalette(pdc_font
, SDL_LOGPAL
,
106 pdc_color
+ newfg
, pdc_flastc
, 1);
113 SDL_SetColorKey(pdc_font
, SDL_SRCCOLORKEY
, 0);
117 SDL_SetColorKey(pdc_font
, 0, 0);
119 SDL_SetPalette(pdc_font
, SDL_LOGPAL
,
120 pdc_color
+ newbg
, 0, 1);
130 /* draw a cursor at (y, x) */
132 void PDC_gotoyx(int row
, int col
)
138 PDC_LOG(("PDC_gotoyx() - called: row %d col %d from row %d col %d\n",
139 row
, col
, SP
->cursrow
, SP
->curscol
));
144 oldrow
= SP
->cursrow
;
145 oldcol
= SP
->curscol
;
147 /* clear the old cursor */
149 PDC_transform_line(oldrow
, oldcol
, 1, curscr
->_y
[oldrow
] + oldcol
);
154 /* draw a new cursor by overprinting the existing character in
155 reverse, either the full cell (when visibility == 2) or the
156 lowest quarter of it (when visibility == 1) */
158 ch
= curscr
->_y
[row
][col
] ^ A_REVERSE
;
163 if (ch
& A_ALTCHARSET
&& !(ch
& 0xff80))
164 ch
= acs_map
[ch
& 0x7f];
166 src
.h
= (SP
->visibility
== 1) ? pdc_fheight
>> 2 : pdc_fheight
;
169 dest
.y
= (row
+ 1) * pdc_fheight
- src
.h
+ pdc_yoffset
;
170 dest
.x
= col
* pdc_fwidth
+ pdc_xoffset
;
172 src
.x
= (ch
& 0xff) % 32 * pdc_fwidth
;
173 src
.y
= (ch
& 0xff) / 32 * pdc_fheight
+ (pdc_fheight
- src
.h
);
175 SDL_BlitSurface(pdc_font
, &src
, pdc_screen
, &dest
);
177 if (oldrow
!= row
|| oldcol
!= col
)
179 if (rectcount
== MAXRECT
)
182 uprect
[rectcount
++] = dest
;
186 /* handle the A_*LINE attributes */
188 static void _highlight(SDL_Rect
*src
, SDL_Rect
*dest
, chtype ch
)
190 short col
= SP
->line_color
;
195 if (ch
& A_UNDERLINE
)
198 SDL_SetPalette(pdc_font
, SDL_LOGPAL
,
199 pdc_color
+ col
, pdc_flastc
, 1);
201 src
->x
= '_' % 32 * pdc_fwidth
;
202 src
->y
= '_' / 32 * pdc_fheight
;
205 SDL_SetColorKey(pdc_font
, SDL_SRCCOLORKEY
, 0);
207 SDL_BlitSurface(pdc_font
, src
, pdc_screen
, dest
);
210 SDL_SetColorKey(pdc_font
, 0, 0);
213 SDL_SetPalette(pdc_font
, SDL_LOGPAL
,
214 pdc_color
+ foregr
, pdc_flastc
, 1);
217 if (ch
& (A_LEFTLINE
|A_RIGHTLINE
))
225 SDL_FillRect(pdc_screen
, dest
, pdc_mapped
[col
]);
227 if (ch
& A_RIGHTLINE
)
229 dest
->x
+= pdc_fwidth
- 1;
230 SDL_FillRect(pdc_screen
, dest
, pdc_mapped
[col
]);
231 dest
->x
-= pdc_fwidth
- 1;
234 dest
->w
= pdc_fwidth
;
238 /* update the given physical line to look like the corresponding line in
241 void PDC_transform_line(int lineno
, int x
, int len
, const chtype
*srcp
)
243 SDL_Rect src
, dest
, lastrect
;
246 PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno
));
248 if (rectcount
== MAXRECT
)
254 dest
.y
= pdc_fheight
* lineno
+ pdc_yoffset
;
255 dest
.x
= pdc_fwidth
* x
+ pdc_xoffset
;
256 dest
.h
= pdc_fheight
;
257 dest
.w
= pdc_fwidth
* len
;
259 /* if the previous rect was just above this one, with the same width
260 and horizontal position, then merge the new one with it instead
261 of adding a new entry */
264 lastrect
= uprect
[rectcount
- 1];
266 if (rectcount
&& lastrect
.x
== dest
.x
&& lastrect
.w
== dest
.w
)
268 if (lastrect
.y
+ lastrect
.h
== dest
.y
)
269 uprect
[rectcount
- 1].h
= lastrect
.h
+ pdc_fheight
;
271 if (lastrect
.y
!= dest
.y
)
272 uprect
[rectcount
++] = dest
;
275 uprect
[rectcount
++] = dest
;
279 for (j
= 0; j
< len
; j
++)
285 if (ch
& A_ALTCHARSET
&& !(ch
& 0xff80))
286 ch
= (ch
& (A_ATTRIBUTES
^ A_ALTCHARSET
)) | acs_map
[ch
& 0x7f];
289 SDL_LowerBlit(pdc_tileback
, &dest
, pdc_screen
, &dest
);
291 src
.x
= (ch
& 0xff) % 32 * pdc_fwidth
;
292 src
.y
= (ch
& 0xff) / 32 * pdc_fheight
;
294 SDL_LowerBlit(pdc_font
, &src
, pdc_screen
, &dest
);
296 if (ch
& (A_UNDERLINE
|A_LEFTLINE
|A_RIGHTLINE
))
297 _highlight(&src
, &dest
, ch
);
299 dest
.x
+= pdc_fwidth
;