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