1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef KYRA_SCREEN_EOB_H
24 #define KYRA_SCREEN_EOB_H
25 
26 #ifdef ENABLE_EOB
27 
28 #include "kyra/graphics/screen.h"
29 
30 namespace Kyra {
31 
32 class EoBCoreEngine;
33 class SegaRenderer;
34 class SegaAnimator;
35 class Screen_EoB : public Screen {
36 friend class SegaRenderer;
37 public:
38 	// The purpose of this enum is to keep better track of which page is used
39 	// when and for which purpose. We use the pages for more backup operations
40 	// than the original and also have to deal with the different ports which
41 	// all do their own things. This is supposed to help avoid using pages that
42 	// are already in use for something else. It also allows for quick fixes
43 	// if necessary.
44 	enum {
45 		kSegaInitShapesPage		=	7,
46 		kSegaRenderPage			=	8,
47 		kDefeatMsgBackupPage	=	10,
48 		kCheckPwBackupPage		=	10,
49 		kSpellbookBackupPage	=	10,
50 		kEoB2ScriptHelperPage	=	12,
51 		kCampMenuBackupPage		=	12
52 	};
53 
54 public:
55 	Screen_EoB(EoBCoreEngine *vm, OSystem *system);
56 	~Screen_EoB() override;
57 
58 	bool init() override;
59 
60 	void setClearScreenDim(int dim);
61 	void clearCurDim();
62 	void clearCurDimOvl(int pageNum);
63 
64 	void setMouseCursor(int x, int y, const byte *shape) override;
65 	void setMouseCursor(int x, int y, const byte *shape, const uint8 *ovl);
66 
67 	void loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size);
68 
69 	void printShadedText(const char *string, int x, int y, int col1, int col2, int shadowCol, int pitch = -1);
70 
71 	void loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip = false) override;
72 	void loadEoBBitmap(const char *file, const uint8 *cgaMapping, int tempPage, int destPage, int convertToPage);
73 	void loadShapeSetBitmap(const char *file, int tempPage, int destPage);
74 
75 	void convertPage(int srcPage, int dstPage, const uint8 *cgaMapping);
76 
77 	void setScreenPalette(const Palette &pal) override;
78 	void getRealPalette(int num, uint8 *dst) override;
79 
80 	uint8 *encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool encode8bit = false, const uint8 *cgaMapping = 0);
81 	void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd = -1, int flags = 0, ...) override;
82 	const uint8 *scaleShape(const uint8 *shapeData, int blockDistance);
83 	const uint8 *scaleShapeStep(const uint8 *shp);
84 	const uint8 *generateShapeOverlay(const uint8 *shp, const uint8 *fadingTable);
85 
86 	void setShapeFrame(int x1, int y1, int x2, int y2);
87 	void enableShapeBackgroundFading(bool enable);
88 	void setShapeFadingLevel(int val);
89 
90 	void setGfxParameters(int x, int y, int col);
91 	void drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize);
92 	void drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize);
93 
94 	void fadeTextColor(Palette *pal, int color, int rate);
95 	bool delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate);
96 
setTextColorMap(const uint8 * cmap)97 	void setTextColorMap(const uint8 *cmap) override {}
98 	int getRectSize(int w, int h) override;
99 
100 	void setFadeTable(const uint8 *table);
101 	void createFadeTable(const uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight);
102 	void createFadeTable16bit(const uint16 *palData, uint16 *dst, uint16 rootColor, uint8 weight);
103 
104 	const uint16 *getCGADitheringTable(int index);
105 	const uint8 *getEGADitheringTable();
106 
107 	bool loadFont(FontId fontId, const char *filename) override;
108 
109 	// FM-Towns specific
110 	void decodeSHP(const uint8 *data, int dstPage);
111 	void convertToHiColor(int page);
112 	void shadeRect(int x1, int y1, int x2, int y2, int shadingLevel);
113 
114 	// PC-98 specific
115 	void selectPC98Palette(int palID, Palette &dest, int brightness = 0, bool set = false);
116 	void decodeBIN(const uint8 *src, uint8 *dst, uint16 inSize);
117 	void decodePC98PlanarBitmap(uint8 *srcDstBuffer, uint8 *tmpBuffer, uint16 size = 64000);
118 
119 	struct PalCycleData {
120 		const int8 *data;
121 		uint8 delay;
122 	};
123 
124 	void initPC98PaletteCycle(int palID, PalCycleData *data);
125 	void updatePC98PaletteCycle(int brightness);
126 
127 	PalCycleData *_activePalCycle;
128 	uint8 *_cyclePalette;
129 
130 	// Amiga specific
131 	void loadSpecialAmigaCPS(const char *fileName, int destPage, bool isGraphics);
132 	// This is a simple way of emulating the Amiga copper list palette magic for more than 32 colors.
133 	// I use colors 32 to 63 for these extra colors (which the Amiga copper sends to the color
134 	// registers on the fly at vertical beam position 120).
135 	void setDualPalettes(Palette &top, Palette &bottom);
136 
137 	// SegaCD specific
138 	void sega_initGraphics();
139 	void sega_selectPalette(int srcPalID, int dstPalID, bool set = false);
140 	void sega_loadCustomPaletteData(Common::ReadStream *in);
141 	void sega_updatePaletteFaders(int palID);
142 	void sega_fadePalette(int delay, int16 brEnd, int dstPalID = -1, bool waitForCompletion = true, bool noUpdate = false);
sega_fadeToBlack(int delay)143 	void sega_fadeToBlack(int delay) { sega_fadePalette(delay, -7); }
sega_fadeToWhite(int delay)144 	void sega_fadeToWhite(int delay) { sega_fadePalette(delay, 7); }
sega_fadeToNeutral(int delay)145 	void sega_fadeToNeutral(int delay) { sega_fadePalette(delay, 0); }
146 	void sega_paletteOps(int16 opPal, int16 par1, int16 par2);
147 	void sega_setTextBuffer(uint8 *buffer, uint32 bufferSize);
148 	void sega_clearTextBuffer(uint8 col);
149 	void sega_loadTextBackground(const uint8 *src, uint16 size);
150 	void sega_drawTextBox(int pW, int pH, int x, int y, int w, int h, uint8 color1, uint8 color2);
151 	void sega_loadTextBufferToVRAM(uint16 srcOffset, uint16 addr, int size);
152 	void sega_gfxScale(uint8 *out, uint16 w, uint16 h, uint16 pitch, const uint8 *in, const uint16 *stampMap, const uint16 *traceVectors);
153 	void sega_drawClippedLine(int pW, int pH, int x, int y, int w, int h, uint8 color);
154 	uint8 *sega_convertShape(const uint8 *src, int w, int h, int pal, int hOffs = 0);
155 	void sega_encodeShapesFromSprites(const uint8 **dst, const uint8 *src, int numShapes, int w, int h, int pal, bool removeSprites = true);
156 
sega_getRenderer()157 	SegaRenderer *sega_getRenderer() const { return _segaRenderer; }
sega_getAnimator()158 	SegaAnimator *sega_getAnimator() const { return _segaAnimator; }
159 
160 private:
161 	void updateDirtyRects() override;
162 	void ditherRect(const uint8 *src, uint8 *dst, int dstPitch, int srcW, int srcH, int colorKey = -1);
163 
164 	void drawShapeSetPixel(uint8 *dst, uint8 col);
165 	void scaleShapeProcessLine2Bit(uint8 *&shpDst, const uint8 *&shpSrc, uint32 transOffsetDst, uint32 transOffsetSrc);
166 	void scaleShapeProcessLine4Bit(uint8 *&dst, const uint8 *&src);
167 	bool posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2);
168 
169 	void setPagePixel16bit(int pageNum, int x, int y, uint16 color);
170 
171 	void generateEGADitheringTable(const Palette &pal);
172 	void generateCGADitheringTables(const uint8 *mappingData);
173 
174 	int _dsDiv, _dsRem, _dsScaleTrans;
175 	uint8 *_cgaScaleTable;
176 	int16 _gfxX, _gfxY;
177 	uint16 _gfxCol;
178 	const uint8 *_gfxMaxY;
179 
180 	int16 _dsX1, _dsX2, _dsY1, _dsY2;
181 
182 	bool _dsBackgroundFading;
183 	int16 _dsBackgroundFadingXOffs;
184 	uint8 _shapeOverlay[16];
185 
186 	uint8 *_dsTempPage;
187 	uint8 *_shpBuffer;
188 	uint8 *_convertHiColorBuffer;
189 
190 	uint16 *_cgaDitheringTables[2];
191 	const uint8 *_cgaMappingDefault;
192 
193 	uint8 *_egaDitheringTable;
194 	uint8 *_egaDitheringTempPage;
195 
196 	Common::String _cpsFilePattern;
197 
198 	const uint16 _cursorColorKey16Bit;
199 
200 	static const uint8 _egaMatchTable[];
201 	static const ScreenDim _screenDimTable[];
202 	static const int _screenDimTableCount;
203 
204 	// SegaCD specific
205 	struct PaletteFader {
PaletteFaderPaletteFader206 		PaletteFader() : _brCur(0), _brDest(0), _fadeIncr(0), _fadeDelay(0), _fadeTimer(0), _needRefresh(false) {}
207 		int16 _brCur;
208 		int16 _brDest;
209 		int16 _fadeIncr;
210 		int16 _fadeDelay;
211 		int16 _fadeTimer;
212 		bool _needRefresh;
213 	};
214 
215 	PaletteFader *_palFaders;
216 	bool _specialColorReplace;
217 	SegaRenderer *_segaRenderer;
218 	SegaAnimator *_segaAnimator;
219 	uint16 _segaCurPalette[64];
220 	uint16 *_segaCustomPalettes;
221 	uint8 *_defaultRenderBuffer;
222 	int _defaultRenderBufferSize;
223 };
224 
225 /**
226 * Implementation of the Font interface for old DOS fonts used
227 * in EOB and EOB II.
228 *
229 */
230 class OldDOSFont : public Font {
231 public:
232 	OldDOSFont(Common::RenderMode mode, uint8 shadowColor);
233 	~OldDOSFont() override;
234 
235 	bool load(Common::SeekableReadStream &file) override;
getType()236 	Type getType() const override { return kASCII; }
getHeight()237 	int getHeight() const override { return _height; }
getWidth()238 	int getWidth() const override { return _width; }
239 	int getCharWidth(uint16 c) const override;
240 	void setColorMap(const uint8 *src) override;
set16bitColorMap(const uint16 * src)241 	void set16bitColorMap(const uint16 *src) override { _colorMap16bit = src; }
setStyles(int styles)242 	void setStyles(int styles) override { _style = styles; }
243 	void drawChar(uint16 c, byte *dst, int pitch, int bpp) const override;
244 
245 protected:
246 	void unload();
247 
248 	int _style;
249 	const uint8 *_colorMap8bit;
250 	uint8 *_data;
251 	uint16 *_bitmapOffsets;
252 	int _width, _height;
253 	int _numGlyphs;
254 	uint8 _shadowColor;
255 
256 private:
257 	void drawCharIntern(uint16 c, byte *dst, int pitch, int bpp, int col1, int col2) const;
258 	virtual uint16 convert(uint16 c) const;
259 	Common::RenderMode _renderMode;
260 	const uint16 *_colorMap16bit;
261 
262 	static uint16 *_cgaDitheringTable;
263 	static int _numRef;
264 };
265 
266 /**
267  * Implementation of the Font interface for native AmigaDOS system fonts (normally to be loaded via diskfont.library)
268  */
269 class Resource;
270 class AmigaDOSFont : public Font {
271 public:
272 	AmigaDOSFont(Resource *res, bool needsLocalizedFont = false);
~AmigaDOSFont()273 	~AmigaDOSFont() override { unload(); }
274 
275 	bool load(Common::SeekableReadStream &file) override;
getType()276 	Type getType() const override { return kASCII; }
getHeight()277 	int getHeight() const override { return _height; }
getWidth()278 	int getWidth() const override { return _width; }
279 	int getCharWidth(uint16 c) const override;
setColorMap(const uint8 * src)280 	void setColorMap(const uint8 *src) override { _colorMap = src; }
281 	void drawChar(uint16 c, byte *dst, int pitch, int) const override;
282 
283 	static void errorDialog(int index);
284 
285 private:
286 	void unload();
287 
288 	struct TextFont {
TextFontTextFont289 		TextFont() : data(0), bitmap(0), location(0), spacing(0), kerning(0), height(0), width(0), baseLine(0), firstChar(0), lastChar(0), modulo(0) {}
~TextFontTextFont290 		~TextFont() {
291 			delete[] data;
292 		}
293 
294 		uint16 height;
295 		uint16 width;
296 		uint16 baseLine;
297 		uint8 firstChar;
298 		uint8 lastChar;
299 		uint16 modulo;
300 		const uint8 *data;
301 		const uint8 *bitmap;
302 		const uint16 *location;
303 		const int16 *spacing;
304 		const int16 *kerning;
305 	};
306 
307 	TextFont *loadContentFile(const Common::String fileName);
308 	void selectMode(int mode);
309 
310 	struct FontContent {
FontContentFontContent311 		FontContent() : height(0), style(0), flags(0) {}
~FontContentFontContent312 		~FontContent() {
313 			data.reset();
314 		}
315 
316 		Common::String contentFile;
317 		Common::SharedPtr<TextFont> data;
318 		uint16 height;
319 		uint8 style;
320 		uint8 flags;
321 	};
322 
323 	int _width, _height;
324 	uint8 _first, _last;
325 	FontContent *_content;
326 	uint16 _numElements;
327 	uint16 _selectedElement;
328 
329 	const uint8 *_colorMap;
330 	const uint16 _maxPathLen;
331 	const bool _needsLocalizedFont;
332 
333 	static uint8 _errorDialogDisplayed;
334 
335 	Resource *_res;
336 };
337 
338 /**
339 * SJIS Font variant used in EOB I PC-98. It converts 1-byte characters into 2-byte characters and has a specific shadowing to the left.
340 */
341 class SJISFontEoB1PC98 : public SJISFont {
342 public:
343 	SJISFontEoB1PC98(Common::SharedPtr<Graphics::FontSJIS> &font, /*uint8 shadowColor,*/ const uint16 *convTable1, const uint16 *convTable2);
~SJISFontEoB1PC98()344 	~SJISFontEoB1PC98() override {}
345 	int getCharWidth(uint16 c) const override;
346 	void drawChar(uint16 c, byte *dst, int pitch, int) const override;
347 
348 private:
349 	uint16 convert(uint16 c) const;
350 	const uint16 *_convTable1, *_convTable2;
351 	bool _defaultConv;
352 	/*uint8 _shadowColor;*/
353 };
354 
355 /**
356 * OldDOSFont variant used in EOB I PC-98. It uses the same drawing routine, but has a different loader. It contains
357 * ASCII and Katakana characters and requires several conversion tables to display these. It gets drawn on the SJIS overlay.
358 */
359 class Font12x12PC98 : public OldDOSFont{
360 public:
361 	Font12x12PC98(uint8 shadowColor, const uint16 *convTable1, const uint16 *convTable2, const uint8 *lookupTable);
362 	~Font12x12PC98() override;
usesOverlay()363 	bool usesOverlay() const override { return true; }
getType()364 	Type getType() const override { return kSJIS; }
getHeight()365 	int getHeight() const override { return _height >> 1; }
getWidth()366 	int getWidth() const override { return _width >> 1; }
getCharWidth(uint16 c)367 	int getCharWidth(uint16 c) const override { return _width >> 1; };
368 	bool load(Common::SeekableReadStream &file) override;
369 
370 private:
371 	uint16 convert(uint16 c) const override;
372 	const uint16 *_convTable1, *_convTable2;
373 	uint16 *_bmpOffs;
374 };
375 
376 /**
377 * SJIS Font variant used in the intro and outro of EOB II FM-Towns. It appears twice as large, since it is not rendered on the hires overlay pages.
378 */
379 class SJISFontLarge : public SJISFont {
380 public:
381 	SJISFontLarge(Common::SharedPtr<Graphics::FontSJIS> &font);
~SJISFontLarge()382 	~SJISFontLarge() override {}
383 
384 	int getHeight() const override;
385 	int getWidth() const override;
386 	int getCharWidth(uint16 c) const override;
387 
usesOverlay()388 	bool usesOverlay() const override { return false; }
389 	void drawChar(uint16 c, byte *dst, int pitch, int) const override;
390 };
391 
392 /**
393 * 12 x 12 SJIS font for EOB II FM-Towns. The data for this font comes from a file, not from the font rom.
394 */
395 class SJISFont12x12 : public Font {
396 public:
397 	SJISFont12x12(const uint16 *searchTable);
~SJISFont12x12()398 	~SJISFont12x12() override { unload(); }
399 
400 	bool load(Common::SeekableReadStream &file) override;
getType()401 	Type getType() const override { return kSJIS; }
usesOverlay()402 	bool usesOverlay() const override { return true; }
getHeight()403 	int getHeight() const override { return _height; }
getWidth()404 	int getWidth() const override { return _width; }
getCharWidth(uint16 c)405 	int getCharWidth(uint16 c) const override { return _width; }
setColorMap(const uint8 * src)406 	void setColorMap(const uint8 *src) override { _colorMap = src; }
407 	void drawChar(uint16 c, byte *dst, int pitch, int) const override;
408 
409 private:
410 	void unload();
411 
412 	uint8 *_data;
413 	Common::HashMap<uint16, uint8> _searchTable;
414 
415 	const uint8 *_colorMap;
416 	const int _height, _width;
417 };
418 
419 class SegaCDFont : public Font {
420 public:
421 	SegaCDFont(Common::Language lang, const uint16 *convTable1, const uint16 *convTable2, const uint8 *widthTable1, const uint8 *widthTable2, const uint8 *widthTable3);
422 	~SegaCDFont() override;
423 
424 	bool load(Common::SeekableReadStream &file) override;
getType()425 	Type getType() const override { return _forceOneByte ? kASCII : kSJIS; }
getHeight()426 	int getHeight() const override { return _height; }
getWidth()427 	int getWidth() const override { return _width; }
428 	int getCharWidth(uint16 c) const override;
429 	int getCharHeight(uint16 c) const override;
430 	void setStyles(int styles) override;
setColorMap(const uint8 * src)431 	void setColorMap(const uint8 *src) override { _colorMap = src; }
drawChar(uint16 c,byte * dst,int pitch,int bpp)432 	void drawChar(uint16 c, byte *dst, int pitch, int bpp) const override { drawChar(c, dst, pitch, 0, 0); }
433 	void drawChar(uint16 c, byte *dst, int pitch, int xOffs, int yOffs) const override;
434 
435 private:
436 	const uint8 *getGlyphData(uint16 c, uint8 &charWidth, uint8 &charHeight, uint8 &pitch) const;
437 
438 	const uint8 *_data;
439 	const uint8 *_buffer;
440 	bool _forceTwoByte;
441 	bool _forceOneByte;
442 	Common::Language _lang;
443 	uint8 _style;
444 
445 	const uint8 *_colorMap;
446 	const int _height, _width;
447 	const uint16 *_convTable1, *_convTable2;
448 	const uint8 *_widthTable1, *_widthTable2, *_widthTable3;
449 };
450 
451 } // End of namespace Kyra
452 
453 #endif // ENABLE_EOB
454 
455 #endif
456