rnd-20021130-1-src
[rocksndiamonds.git] / src / libgame / text.c
1 /***********************************************************
2 * Artsoft Retro-Game Library                               *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment                      *
5 *               Holger Schemel                             *
6 *               Detmolder Strasse 189                      *
7 *               33604 Bielefeld                            *
8 *               Germany                                    *
9 *               e-mail: info@artsoft.org                   *
10 *----------------------------------------------------------*
11 * text.c                                                   *
12 ***********************************************************/
13
14 #include <stdio.h>
15 #include <stdarg.h>
16
17 #include "text.h"
18
19
20 /* ========================================================================= */
21 /* exported variables                                                        */
22 /* ========================================================================= */
23
24 struct FontInfo         font;
25
26
27 /* ========================================================================= */
28 /* font functions                                                            */
29 /* ========================================================================= */
30
31 void InitFontInfo(Bitmap *bitmap_big, Bitmap *bitmap_medium,
32                   Bitmap *bitmap_small, Bitmap *bitmap_tile)
33 {
34   font.bitmap_big = bitmap_big;
35   font.bitmap_medium = bitmap_medium;
36   font.bitmap_small = bitmap_small;
37   font.bitmap_tile = bitmap_tile;
38 }
39
40 int getFontWidth(int font_size, int font_type)
41 {
42   return (font_size == FS_BIG ? FONT1_XSIZE :
43           font_size == FS_MEDIUM ? FONT6_XSIZE :
44           font_type == FC_SPECIAL1 ? FONT3_XSIZE :
45           font_type == FC_SPECIAL2 ? FONT4_XSIZE :
46           font_type == FC_SPECIAL3 ? FONT5_XSIZE :
47           FONT2_XSIZE);
48 }
49
50 int getFontHeight(int font_size, int font_type)
51 {
52   return (font_size == FS_BIG ? FONT1_YSIZE :
53           font_size == FS_MEDIUM ? FONT6_YSIZE :
54           font_type == FC_SPECIAL1 ? FONT3_YSIZE :
55           font_type == FC_SPECIAL2 ? FONT4_YSIZE :
56           font_type == FC_SPECIAL3 ? FONT5_YSIZE :
57           FONT2_YSIZE);
58 }
59
60 void DrawInitText(char *text, int ypos, int color)
61 {
62   if (window && font.bitmap_small)
63   {
64     ClearRectangle(window, 0, ypos, video.width, FONT2_YSIZE);
65     DrawTextExt(window, (video.width - strlen(text) * FONT2_XSIZE)/2,
66                 ypos, text, FS_SMALL, color);
67     FlushDisplay();
68   }
69 }
70
71 void DrawTextFCentered(int y, int font_type, char *format, ...)
72 {
73   char buffer[MAX_OUTPUT_LINESIZE + 1];
74   int font_width = getFontWidth(FS_SMALL, font_type);
75   va_list ap;
76
77   va_start(ap, format);
78   vsprintf(buffer, format, ap);
79   va_end(ap);
80
81   DrawText(gfx.sx + (gfx.sxsize - strlen(buffer) * font_width) / 2,
82            gfx.sy + y, buffer, FS_SMALL, font_type);
83 }
84
85 void DrawTextF(int x, int y, int font_type, char *format, ...)
86 {
87   char buffer[MAX_OUTPUT_LINESIZE + 1];
88   va_list ap;
89
90   va_start(ap, format);
91   vsprintf(buffer, format, ap);
92   va_end(ap);
93
94   DrawText(gfx.sx + x, gfx.sy + y, buffer, FS_SMALL, font_type);
95 }
96
97 void DrawText(int x, int y, char *text, int font_size, int font_type)
98 {
99   DrawTextExt(drawto, x, y, text, font_size, font_type);
100
101   if (x < gfx.dx)
102     redraw_mask |= REDRAW_FIELD;
103   else if (y < gfx.vy || gfx.vy == 0)
104     redraw_mask |= REDRAW_DOOR_1;
105 }
106
107 void DrawTextExt(DrawBuffer *bitmap, int x, int y,
108                  char *text, int font_size, int font_type)
109 {
110   Bitmap *font_bitmap;
111   int font_width, font_height, font_starty;
112   boolean print_inverse = FALSE;
113
114   if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
115     font_size = FS_SMALL;
116   if (font_type < FC_RED || font_type > FC_SPECIAL3)
117     font_type = FC_RED;
118
119   font_width = getFontWidth(font_size, font_type);
120   font_height = getFontHeight(font_size, font_type);
121
122   font_bitmap = (font_type == FC_SPECIAL2       ? font.bitmap_tile      :
123                  font_size == FS_BIG            ? font.bitmap_big       :
124                  font_size == FS_MEDIUM         ? font.bitmap_medium    :
125                  font_size == FS_SMALL          ? font.bitmap_small     :
126                  font.bitmap_small);
127
128   if (font_bitmap == NULL)
129     return;
130
131   if (font_type == FC_SPECIAL2)
132     font_starty = (font_size == FS_BIG ? 0 : FONT1_YSIZE) * 5;
133   else
134     font_starty = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
135                                 font_size == FS_MEDIUM ? FONT6_YSIZE :
136                                 FONT2_YSIZE) *
137                    FONT_LINES_PER_FONT);
138
139   if (font_type == FC_SPECIAL3)
140     font_starty -= FONT2_YSIZE * FONT_LINES_PER_FONT;
141
142   while (*text)
143   {
144     char c = *text++;
145
146     if (c == '~' && font_size == FS_SMALL)
147     {
148       print_inverse = TRUE;
149       continue;
150     }
151
152     if (c >= 'a' && c <= 'z')
153       c = 'A' + (c - 'a');
154     else if (c == 'ä' || c == 'Ä')
155       c = 91;
156     else if (c == 'ö' || c == 'Ö')
157       c = 92;
158     else if (c == 'ü' || c == 'Ü')
159       c = 93;
160     else if (c == '[' || c == ']')      /* map to normal braces */
161       c = (c == '[' ? '(' : ')');
162     else if (c == '\\')                 /* bad luck ... */
163       c = '/';
164
165     if ((c >= 32 && c <= 95) || c == '°' || c == '´')
166     {
167       int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
168       int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_starty;
169       int dest_x = x, dest_y = y;
170
171       if (c == '°' || c == '´')         /* map '°' and 'TM' signs */
172       {
173         if (font_type == FC_SPECIAL2)
174         {
175           src_x = (c == '°' ? 1 : 2) * font_width;
176           src_y = 4 * font_height;
177         }
178         else
179         {
180           src_x = FONT_CHARS_PER_LINE * font_width;
181           src_y = (c == '°' ? 1 : 2) * font_height + font_starty;
182         }
183       }
184
185       if (print_inverse)
186       {
187         BlitBitmap(font_bitmap, bitmap,
188                    FONT_CHARS_PER_LINE * font_width,
189                    3 * font_height + font_starty,
190                    font_width, font_height, x, y);
191
192         SetClipOrigin(font_bitmap, font_bitmap->stored_clip_gc,
193                       dest_x - src_x, dest_y - src_y);
194         BlitBitmapMasked(font_bitmap, bitmap,
195                          0, 0, font_width, font_height, dest_x, dest_y);
196       }
197       else
198         BlitBitmap(font_bitmap, bitmap,
199                    src_x, src_y, font_width, font_height, dest_x, dest_y);
200     }
201
202     x += font_width;
203   }
204 }