rnd-20020914-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_start;
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_type == FC_SPECIAL2)
129     font_start = (font_size == FS_BIG ? 0 : FONT1_YSIZE) * FONT_LINES_PER_FONT;
130   else
131     font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
132                                font_size == FS_MEDIUM ? FONT6_YSIZE :
133                                FONT2_YSIZE) *
134                   FONT_LINES_PER_FONT);
135
136   if (font_type == FC_SPECIAL3)
137     font_start -= FONT2_YSIZE * FONT_LINES_PER_FONT;
138
139   while (*text)
140   {
141     char c = *text++;
142
143     if (c == '~' && font_size == FS_SMALL)
144     {
145       print_inverse = TRUE;
146       continue;
147     }
148
149     if (c >= 'a' && c <= 'z')
150       c = 'A' + (c - 'a');
151     else if (c == 'ä' || c == 'Ä')
152       c = 91;
153     else if (c == 'ö' || c == 'Ö')
154       c = 92;
155     else if (c == 'ü' || c == 'Ü')
156       c = 93;
157     else if (c == '[' || c == ']')      /* map to normal braces */
158       c = (c == '[' ? '(' : ')');
159     else if (c == '\\')                 /* bad luck ... */
160       c = '/';
161
162     if ((c >= 32 && c <= 95) || c == '°' || c == '´')
163     {
164       int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
165       int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
166       int dest_x = x, dest_y = y;
167
168       if (c == '°' || c == '´')         /* map '°' and 'TM' signs */
169       {
170         src_x = FONT_CHARS_PER_LINE * font_width;
171         src_y = (c == '°' ? 1 : 2) * font_height + font_start;
172       }
173
174       if (print_inverse)
175       {
176         BlitBitmap(font_bitmap, bitmap,
177                    FONT_CHARS_PER_LINE * font_width,
178                    3 * font_height + font_start,
179                    font_width, font_height, x, y);
180
181         SetClipOrigin(font_bitmap, font_bitmap->stored_clip_gc,
182                       dest_x - src_x, dest_y - src_y);
183         BlitBitmapMasked(font_bitmap, bitmap,
184                          0, 0, font_width, font_height, dest_x, dest_y);
185       }
186       else
187         BlitBitmap(font_bitmap, bitmap,
188                    src_x, src_y, font_width, font_height, dest_x, dest_y);
189     }
190
191     x += font_width;
192   }
193 }