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 #include "ags/plugins/ags_sprite_font/ags_sprite_font.h"
24 #include "ags/shared/core/platform.h"
25 
26 namespace AGS3 {
27 namespace Plugins {
28 namespace AGSSpriteFont {
29 
30 #pragma region Defines
31 
32 #define MIN_EDITOR_VERSION 1
33 #define MIN_ENGINE_VERSION 3
34 
35 #define DEFAULT_RGB_R_SHIFT_32  16
36 #define DEFAULT_RGB_G_SHIFT_32  8
37 #define DEFAULT_RGB_B_SHIFT_32  0
38 #define DEFAULT_RGB_A_SHIFT_32  24
39 
40 #define abs(a)                       ((a)<0 ? -(a) : (a))
41 #define ChannelBlend_Normal(B,L)     ((uint8)(B))
42 #define ChannelBlend_Lighten(B,L)    ((uint8)((L > B) ? L:B))
43 #define ChannelBlend_Darken(B,L)     ((uint8)((L > B) ? B:L))
44 #define ChannelBlend_Multiply(B,L)   ((uint8)((B * L) / 255))
45 #define ChannelBlend_Average(B,L)    ((uint8)((B + L) / 2))
46 #define ChannelBlend_Add(B,L)        ((uint8)(min(255, (B + L))))
47 #define ChannelBlend_Subtract(B,L)   ((uint8)((B + L < 255) ? 0:(B + L - 255)))
48 #define ChannelBlend_Difference(B,L) ((uint8)(abs(B - L)))
49 #define ChannelBlend_Negation(B,L)   ((uint8)(255 - abs(255 - B - L)))
50 #define ChannelBlend_Screen(B,L)     ((uint8)(255 - (((255 - B) * (255 - L)) >> 8)))
51 #define ChannelBlend_Exclusion(B,L)  ((uint8)(B + L - 2 * B * L / 255))
52 #define ChannelBlend_Overlay(B,L)    ((uint8)((L < 128) ? (2 * B * L / 255):(255 - 2 * (255 - B) * (255 - L) / 255)))
53 #define ChannelBlend_SoftLight(B,L)  ((uint8)((L < 128)?(2*((B>>1)+64))*((float)L/255):(255-(2*(255-((B>>1)+64))*(float)(255-L)/255))))
54 #define ChannelBlend_HardLight(B,L)  (ChannelBlend_Overlay(L,B))
55 #define ChannelBlend_ColorDodge(B,L) ((uint8)((L == 255) ? L:min(255, ((B << 8 ) / (255 - L)))))
56 #define ChannelBlend_ColorBurn(B,L)  ((uint8)((L == 0) ? L:max(0, (255 - ((255 - B) << 8 ) / L))))
57 #define ChannelBlend_LinearDodge(B,L)(ChannelBlend_Add(B,L))
58 #define ChannelBlend_LinearBurn(B,L) (ChannelBlend_Subtract(B,L))
59 #define ChannelBlend_LinearLight(B,L)((uint8)(L < 128)?ChannelBlend_LinearBurn(B,(2 * L)):ChannelBlend_LinearDodge(B,(2 * (L - 128))))
60 #define ChannelBlend_VividLight(B,L) ((uint8)(L < 128)?ChannelBlend_ColorBurn(B,(2 * L)):ChannelBlend_ColorDodge(B,(2 * (L - 128))))
61 #define ChannelBlend_PinLight(B,L)   ((uint8)(L < 128)?ChannelBlend_Darken(B,(2 * L)):ChannelBlend_Lighten(B,(2 * (L - 128))))
62 #define ChannelBlend_HardMix(B,L)    ((uint8)((ChannelBlend_VividLight(B,L) < 128) ? 0:255))
63 #define ChannelBlend_Reflect(B,L)    ((uint8)((L == 255) ? L:min(255, (B * B / (255 - L)))))
64 #define ChannelBlend_Glow(B,L)       (ChannelBlend_Reflect(L,B))
65 #define ChannelBlend_Phoenix(B,L)    ((uint8)(min(B,L) - max(B,L) + 255))
66 #define ChannelBlend_Alpha(B,L,O)    ((uint8)(O * B + (1 - O) * L))
67 #define ChannelBlend_AlphaF(B,L,F,O) (ChannelBlend_Alpha(F(B,L),B,O))
68 
69 
70 #pragma endregion
71 
72 #define STRINGIFY(s) STRINGIFY_X(s)
73 #define STRINGIFY_X(s) #s
74 
AGS_GetPluginName()75 const char *AGSSpriteFont::AGS_GetPluginName() {
76 	return "AGSSpriteFont";
77 }
78 
AGS_EngineStartup(IAGSEngine * engine)79 void AGSSpriteFont::AGS_EngineStartup(IAGSEngine *engine) {
80 	PluginBase::AGS_EngineStartup(engine);
81 
82 	if (_fontRenderer == nullptr) {
83 		_engine->PrintDebugConsole("AGSSpriteFont: Init fixed width renderer");
84 		_fontRenderer = new SpriteFontRenderer(engine);
85 	}
86 	if (_vWidthRenderer == nullptr) {
87 		_engine->PrintDebugConsole("AGSSpriteFont: Init vari width renderer");
88 		_vWidthRenderer = new VariableWidthSpriteFontRenderer(engine);
89 	}
90 	// Make sure it's got the version with the features we need
91 	if (_engine->version < MIN_ENGINE_VERSION)
92 		_engine->AbortGame("Plugin needs engine version " STRINGIFY(MIN_ENGINE_VERSION) " or newer.");
93 
94 	// Register functions
95 	_engine->PrintDebugConsole("AGSSpriteFont: Register functions");
96 	SCRIPT_METHOD(SetSpriteFont, AGSSpriteFont::SetSpriteFont);
97 	SCRIPT_METHOD(SetVariableSpriteFont, AGSSpriteFont::SetVariableSpriteFont);
98 	SCRIPT_METHOD(SetGlyph, AGSSpriteFont::SetGlyph);
99 	SCRIPT_METHOD(SetSpacing, AGSSpriteFont::SetSpacing);
100 	SCRIPT_METHOD(SetLineHeightAdjust, AGSSpriteFont::SetLineHeightAdjust);
101 }
102 
AGS_EngineShutdown()103 void AGSSpriteFont::AGS_EngineShutdown() {
104 	delete _fontRenderer;
105 	delete _vWidthRenderer;
106 }
107 
SetSpriteFont(ScriptMethodParams & params)108 void AGSSpriteFont::SetSpriteFont(ScriptMethodParams &params) {
109 	PARAMS9(int, fontNum, int, sprite, int, rows, int, columns, int, charWidth, int, charHeight, int, charMin, int, charMax, bool, use32bit);
110 	_engine->PrintDebugConsole("AGSSpriteFont: SetSpriteFont");
111 	_fontRenderer->SetSpriteFont(fontNum, sprite, rows, columns, charWidth, charHeight, charMin, charMax, use32bit);
112 	_engine->ReplaceFontRenderer(fontNum, _fontRenderer);
113 }
114 
SetVariableSpriteFont(ScriptMethodParams & params)115 void AGSSpriteFont::SetVariableSpriteFont(ScriptMethodParams &params) {
116 	PARAMS2(int, fontNum, int, sprite);
117 	_engine->PrintDebugConsole("AGSSpriteFont: SetVariableFont");
118 	_vWidthRenderer->SetSprite(fontNum, sprite);
119 	_engine->ReplaceFontRenderer(fontNum, _vWidthRenderer);
120 }
121 
SetGlyph(ScriptMethodParams & params)122 void AGSSpriteFont::SetGlyph(ScriptMethodParams &params) {
123 	PARAMS6(int, fontNum, int, charNum, int, x, int, y, int, width, int, height);
124 	_engine->PrintDebugConsole("AGSSpriteFont: SetGlyph");
125 	_vWidthRenderer->SetGlyph(fontNum, charNum, x, y, width, height);
126 }
127 
SetSpacing(ScriptMethodParams & params)128 void AGSSpriteFont::SetSpacing(ScriptMethodParams &params) {
129 	PARAMS2(int, fontNum, int, spacing);
130 	_engine->PrintDebugConsole("AGSSpriteFont: SetSpacing");
131 	_vWidthRenderer->SetSpacing(fontNum, spacing);
132 }
133 
SetLineHeightAdjust(ScriptMethodParams & params)134 void AGSSpriteFont::SetLineHeightAdjust(ScriptMethodParams &params) {
135 	//PARAMS4(int, v1, int, v2, int, v3, int, v4);
136 	// TODO
137 }
138 
139 
140 } // namespace AGSSpriteFont
141 } // namespace Plugins
142 } // namespace AGS3
143