rnd-20020401-2-src
[rocksndiamonds.git] / src / libgame / text.c
1 /***********************************************************
2 * Artsoft Retro-Game Library                               *
3 *----------------------------------------------------------*
4 * (c) 1994-2001 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)
33 {
34   font.bitmap_big = bitmap_big;
35   font.bitmap_medium = bitmap_medium;
36   font.bitmap_small = bitmap_small;
37 }
38
39 int getFontWidth(int font_size, int font_type)
40 {
41   return (font_size == FS_BIG ? FONT1_XSIZE :
42           font_size == FS_MEDIUM ? FONT6_XSIZE :
43           font_type == FC_SPECIAL1 ? FONT3_XSIZE :
44           font_type == FC_SPECIAL2 ? FONT4_XSIZE :
45           font_type == FC_SPECIAL3 ? FONT5_XSIZE :
46           FONT2_XSIZE);
47 }
48
49 int getFontHeight(int font_size, int font_type)
50 {
51   return (font_size == FS_BIG ? FONT1_YSIZE :
52           font_size == FS_MEDIUM ? FONT6_YSIZE :
53           font_type == FC_SPECIAL1 ? FONT3_YSIZE :
54           font_type == FC_SPECIAL2 ? FONT4_YSIZE :
55           font_type == FC_SPECIAL3 ? FONT5_YSIZE :
56           FONT2_YSIZE);
57 }
58
59 void DrawInitText(char *text, int ypos, int color)
60 {
61   if (window && font.bitmap_small)
62   {
63     ClearRectangle(window, 0, ypos, video.width, FONT2_YSIZE);
64     DrawTextExt(window, (video.width - strlen(text) * FONT2_XSIZE)/2,
65                 ypos, text, FS_SMALL, color);
66     FlushDisplay();
67   }
68 }
69
70 void DrawTextFCentered(int y, int font_type, char *format, ...)
71 {
72   char buffer[MAX_OUTPUT_LINESIZE + 1];
73   int font_width = getFontWidth(FS_SMALL, font_type);
74   va_list ap;
75
76   va_start(ap, format);
77   vsprintf(buffer, format, ap);
78   va_end(ap);
79
80   DrawText(gfx.sx + (gfx.sxsize - strlen(buffer) * font_width) / 2,
81            gfx.sy + y, buffer, FS_SMALL, font_type);
82 }
83
84 void DrawTextF(int x, int y, int font_type, char *format, ...)
85 {
86   char buffer[MAX_OUTPUT_LINESIZE + 1];
87   va_list ap;
88
89   va_start(ap, format);
90   vsprintf(buffer, format, ap);
91   va_end(ap);
92
93   DrawText(gfx.sx + x, gfx.sy + y, buffer, FS_SMALL, font_type);
94 }
95
96 void DrawText(int x, int y, char *text, int font_size, int font_type)
97 {
98   DrawTextExt(drawto, x, y, text, font_size, font_type);
99
100   if (x < gfx.dx)
101     redraw_mask |= REDRAW_FIELD;
102   else if (y < gfx.vy || gfx.vy == 0)
103     redraw_mask |= REDRAW_DOOR_1;
104 }
105
106 void DrawTextExt(DrawBuffer *bitmap, int x, int y,
107                  char *text, int font_size, int font_type)
108 {
109   Bitmap *font_bitmap;
110   int font_width, font_height, font_start;
111   boolean print_inverse = FALSE;
112
113   if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
114     font_size = FS_SMALL;
115   if (font_type < FC_RED || font_type > FC_SPECIAL3)
116     font_type = FC_RED;
117
118   font_width = getFontWidth(font_size, font_type);
119   font_height = getFontHeight(font_size, font_type);
120
121   font_bitmap = (font_size == FS_BIG ? font.bitmap_big :
122                  font_size == FS_MEDIUM ? font.bitmap_medium :
123                  font.bitmap_small);
124   font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
125                              font_size == FS_MEDIUM ? FONT6_YSIZE :
126                              FONT2_YSIZE) *
127                 FONT_LINES_PER_FONT);
128
129   if (font_type == FC_SPECIAL3)
130     font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
131
132   while (*text)
133   {
134     char c = *text++;
135
136     if (c == '~' && font_size == FS_SMALL)
137     {
138       print_inverse = TRUE;
139       continue;
140     }
141
142     if (c >= 'a' && c <= 'z')
143       c = 'A' + (c - 'a');
144     else if (c == 'ä' || c == 'Ä')
145       c = 91;
146     else if (c == 'ö' || c == 'Ö')
147       c = 92;
148     else if (c == 'ü' || c == 'Ü')
149       c = 93;
150     else if (c == '[' || c == ']')      /* map to normal braces */
151       c = (c == '[' ? '(' : ')');
152     else if (c == '\\')                 /* bad luck ... */
153       c = '/';
154
155     if ((c >= 32 && c <= 95) || c == '°')
156     {
157       int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
158       int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
159       int dest_x = x, dest_y = y;
160
161       if (c == '°')
162       {
163         src_x = (FONT_CHARS_PER_LINE + 1) * font_width;
164         src_y = 3 * font_height + font_start;
165       }
166
167       if (print_inverse)
168       {
169         BlitBitmap(font_bitmap, bitmap,
170                    FONT_CHARS_PER_LINE * font_width,
171                    3 * font_height + font_start,
172                    font_width, font_height, x, y);
173
174         SetClipOrigin(font_bitmap, font_bitmap->stored_clip_gc,
175                       dest_x - src_x, dest_y - src_y);
176         BlitBitmapMasked(font_bitmap, bitmap,
177                          0, 0, font_width, font_height, dest_x, dest_y);
178       }
179       else
180         BlitBitmap(font_bitmap, bitmap,
181                    src_x, src_y, font_width, font_height, dest_x, dest_y);
182     }
183
184     x += font_width;
185   }
186 }