1 /* ResidualVM - A 3D game interpreter
2  *
3  * ResidualVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the AUTHORS
5  * file distributed with this source distribution.
6  *
7  * Additional copyright for this file:
8  * Copyright (C) 1999-2000 Revolution Software Ltd.
9  * This code is based on source code created by Revolution Software,
10  * used with permission.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25  *
26  */
27 
28 #ifndef ICB_INCLUDED_TEXT_SPRITES_H
29 #define ICB_INCLUDED_TEXT_SPRITES_H
30 
31 #include "engines/icb/p4_generic.h"
32 #include "engines/icb/common/px_bitmap.h"
33 #include "engines/icb/common/px_game_object.h"
34 #include "engines/icb/debug.h"
35 
36 namespace ICB {
37 
38 // PC limit
39 #define TEXT_SPRITE_SIZE (300 * 150 * 4)
40 
41 #define TS_NON_SPOKEN_LINE '&'
42 #define TS_SPOKEN_LINE '*'
43 #define TS_LINENO_OPEN '{'
44 #define TS_LINENO_CLOSE '}'
45 
46 // This pointer can be set to force a different RGB to be used for speech text.  Remora uses
47 // this to do text colouring.
48 extern _rgb *psTempSpeechColour;
49 
50 // return codes for text sprite functions
51 enum _TSrtn {
52 	TS_OK,              // it worked
53 	TS_ILLEGAL_SPACING, // line contains leading/trailing spaces or extra spaces between words
54 	TS_TOO_MANY_LINES,  // exceeded lineInfo array while analysing sentence
55 	TS_INVALID_FONT,    // the resource id passed is not a valid font resource
56 	TS_OUT_OF_MEM,      // couldn't allocate memory for text sprite
57 	TS_ILLEGAL_PIN,     // unrecognised value of '_pin_position'
58 	TS_ILLEGAL_MARGIN   // sprite cannot fit within given screen margin
59 };
60 
61 // "Pin position" is the point on the sprite that we want to fix to the screen coordinates.
62 // eg. Speech text traditionally uses "PIN_AT_CENTRE_OF_BASE". That is, for calculating the
63 // required render coordinates, we will specify the coordinates of a point just above the
64 // talker's head, and then whatever the width and height of the text sprite, the render
65 // coordinates will be calculated such that the centre of the text sprite's base will be
66 // exactly at the specified coordinates - ie. text is centred just above the talkers head.
67 // The other pin positions may be used for pointer text, data readouts on PPC, or alternate
68 // positions for speech text, etc.
69 enum _pin_position {
70 	PIN_AT_CENTRE,
71 	PIN_AT_CENTRE_OF_TOP,
72 	PIN_AT_CENTRE_OF_BASE,
73 	PIN_AT_CENTRE_OF_LEFT,
74 	PIN_AT_CENTRE_OF_RIGHT,
75 	PIN_AT_TOP_LEFT,
76 	PIN_AT_TOP_RIGHT,
77 	PIN_AT_BOTTOM_LEFT,
78 	PIN_AT_BOTTOM_RIGHT
79 };
80 
81 // This must now be a multiple of 4!
82 #define MAX_LINES 48 // max character lines in output sprite
83 
84 typedef struct {       // info for each line of words in the output text sprite
85 	uint16 width;  // width of line in pixels
86 	uint16 length; // length of line in characters
87 } _textLine;
88 
89 typedef struct { // info describing whole set of lines used in the sprite
90 	_textLine line[MAX_LINES];
91 	uint8 noOfLines;
92 	uint8 m_stopAtLine;
93 	uint8 m_bLeftFormatted;
94 	uint8 padding;
95 } _lineInfo;
96 
97 // This is the structure that must be filled in before calling MakeTextSprite()
98 // which takes a reference to a structure of this type as it's only parameter
99 typedef struct {                  // info for each line of words in the output text sprite
100 	uint8 *textLine;          // null-terminated text sprite (must not contain any leading/tailing/extra spaces
101 	const char *fontResource; // name of the font
102 	uint32 fontResource_hash; // hash of the font file
103 	uint32 maxWidth;          // maximum allowed pixel width of text sprite
104 	uint32 bitDepth;          // 16,24 or 32 bits per pixel (2,3 or 4 bytes)
105 	int32 lineSpacing;        // no. of pixels to separate lines of characters in the output sprite   - negative for overlap
106 	int32 charSpacing;        // no. of pixels to separate characters along each line                                 - negative for overlap
107 	_rgb bodyColour;          // colour required for character bodies
108 	_rgb borderColour;        // colour required for character borders
109 	int32 errorChecking;      // perform error checking during analysesetence on/off
110 } _TSparams;
111 
112 class text_sprite {
113 	// created by routines:
114 	uint8 sprite[TEXT_SPRITE_SIZE];
115 	uint32 spriteWidth;  // width of text sprite
116 	uint32 spriteHeight; // height of text sprite
117 	uint32 size;         // in bytes (= width * height * bit_depth)      NOT SURE WE NEED THIS FOR ANYTHING
118 	uint32 surfaceId; // The surface we want to eventually draw this sprite on
119 	_lineInfo lineInfo; // infomation about the lines in the text_block
120 	_TSparams params;
121 
122 	// private functions:
123 	_TSrtn BuildTextSprite(int32 stopAtLine = -1, bool8 bRemoraLeftFormatting = FALSE8); // construct the sprite
124 	uint32 CharWidth(const uint8 ch, const char *fontRes, uint32 fontRes_hash);          // get width of a character
125 	void CopyChar(_pxSprite *charPtr, uint8 *spritePtr, uint8 *pal);    // copy character into sprite, based on params
126 	_TSrtn CheckFontResource(const char *fontRes, uint32 fontRes_hash); // check that it's a valid font resource
127 	_pxBitmap *LoadFont(const char *fontRes, uint32 fontRes_hash);
128 
129 public:
130 	int32 renderX; // render coordinate
131 	int32 renderY;
132 
133 	// the usual:
134 	text_sprite();  // constructor -- default constructor
135 	~text_sprite(); // destructor
136 
137 	// Made this public, so Remora can work out how its formatting will be done.
138 	_TSrtn AnalyseSentence(void); // fill in the lineInfo structure
139 
140 	// the main routine to create the sprite (added flag to stop AnalyseSentence() getting called if you need to)
141 	// Also, you can now tell it to stop short of displaying every line in the text.
142 	_TSrtn MakeTextSprite(bool8 analysisAlreadyDone = FALSE8, int32 stopAtLine = -1, bool8 bRemoraLeftFormatting = FALSE8);
143 
144 	// the support routine to calculate suitable render coordinates
145 	_TSrtn GetRenderCoords(const int32 pinX,           // screen x-coord where we want to position the pin
146 	                       const int32 pinY,           // y-coord -"-
147 	                       const _pin_position pinPos, // position of pin on text sprite
148 	                       const int32 margin);        // margin to keep sprite within edge of screen, or -1 if allowed anywhere
149 
150 	uint32 CharHeight(const char *fontRes, uint32 fontRes_hash); // get character height (all the same)
151 	_pxSprite *FindChar(uint8 ch, _pxBitmap *charSet);           // get pointer to header of required character data in font
152 
153 	// the usual set of routines to return required values
GetSprite(void)154 	uint8 *GetSprite(void) {
155 		return sprite; // get pointer to text sprite in memory
156 	}
GetWidth(void)157 	uint32 GetWidth(void) {
158 		return spriteWidth; // get dimensions of text sprite
159 	}
GetHeight(void)160 	uint32 GetHeight(void) {
161 		return spriteHeight; // -"-
162 	}
GetSize(void)163 	uint32 GetSize(void) {
164 		return size; // get byte-length of text sprite data
165 	}
GetLineInfo(void)166 	_lineInfo *GetLineInfo(void) {
167 		return &lineInfo; // infomation about the lines in the text_block
168 	}
GetParams(void)169 	_TSparams *GetParams(void) {
170 		return &params; // infomation about the lines in the text_block
171 	}
SetSurface(uint32 sid)172 	void SetSurface(uint32 sid) { surfaceId = sid; }
GetSurface()173 	uint32 GetSurface() const { return surfaceId; }
174 
175 	// This a variable stuck way down here on it's little lonesome ?
176 	bool8 please_render; // draw yes/no
177 };
178 
179 } // End of namespace ICB
180 
181 #endif // INCLUDED_TEXT_SPRITES_H
182