1 /*
2 	This file is part of Warzone 2100.
3 	Copyright (C) 1999-2004  Eidos Interactive
4 	Copyright (C) 2005-2020  Warzone 2100 Project
5 
6 	Warzone 2100 is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 2 of the License, or
9 	(at your option) any later version.
10 
11 	Warzone 2100 is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with Warzone 2100; if not, write to the Free Software
18 	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 /*
21  * Image.c
22  *
23  * Image definitions and related functions.
24  *
25  */
26 
27 #include "lib/framework/frame.h"
28 #include "lib/framework/frameresource.h"
29 #include "lib/ivis_opengl/bitimage.h"
30 #include "lib/ivis_opengl/piepalette.h"
31 #include "lib/ivis_opengl/piestate.h"
32 
33 #include "intimage.h"
34 
35 #define INCEND	(0)
36 
37 enum
38 {
39 	FR_SOLID,	//< Bitmap drawn solid.
40 	FR_KEYED,	//< Bitmap drawn with colour 0 transparent.
41 };
42 
43 enum FRAMERECTTYPE
44 {
45 	FR_IGNORE,	//< Fill rect is ignored.
46 	FR_FRAME,	//< Fill rect drawn relative to frame.
47 	FR_LEFT,	//< Fill rect drawn relative to left of frame.
48 	FR_RIGHT,	//< Fill rect drawn relative to right of frame.
49 	FR_TOP,		//< Fill rect drawn relative to top of frame.
50 	FR_BOTTOM,	//< Fill rect drawn relative to bottom of frame.
51 };
52 
53 struct FRAMERECT
54 {
55 	FRAMERECTTYPE Type;		//< One of the FR_... values.
56 	int TLXOffset, TLYOffset;	//< Offsets for the rect fill.
57 	int BRXOffset, BRYOffset;
58 	int ColourIndex;		//< Hackish index into the WZCOLOR palette
59 };
60 
61 // Frame definition structure.
62 struct IMAGEFRAME
63 {
64 	SWORD OffsetX0, OffsetY0;	//< Offset top left of frame.
65 	SWORD OffsetX1, OffsetY1;	//< Offset bottom right of frame.
66 	SWORD TopLeft;			//< Image indecies for the corners ( -1 = don't draw).
67 	SWORD TopRight;
68 	SWORD BottomLeft;
69 	SWORD BottomRight;
70 	SWORD TopEdge, TopType;		//< Image indecies for the edges ( -1 = don't draw). Type ie FR_SOLID or FR_KEYED.
71 	SWORD RightEdge, RightType;
72 	SWORD BottomEdge, BottomType;
73 	SWORD LeftEdge, LeftType;
74 	FRAMERECT FRect[5];		//< Fill rectangles.
75 };
76 
77 IMAGEFILE *IntImages;	// All the 2d graphics for the user interface.
78 
79 /** Form frame definition for normal frames. */
80 IMAGEFRAME FrameNormal =
81 {
82 	0, 0, 0, 0,
83 	IMAGE_FRAME_C0,
84 	IMAGE_FRAME_C1,
85 	IMAGE_FRAME_C3,
86 	IMAGE_FRAME_C2,
87 	IMAGE_FRAME_HT, FR_SOLID,
88 	IMAGE_FRAME_VR, FR_SOLID,
89 	IMAGE_FRAME_HB, FR_SOLID,
90 	IMAGE_FRAME_VL, FR_SOLID,
91 	{	{FR_FRAME, 0, 1, 0, -1, 33},
92 		{FR_IGNORE, 0, 0, 0, 0 , 0},
93 		{FR_IGNORE, 0, 0, 0, 0 , 0},
94 		{FR_IGNORE, 0, 0, 0, 0 , 0},
95 		{FR_IGNORE, 0, 0, 0, 0 , 0}
96 	},
97 };
98 
99 /** Form frame definition for radar frames. */
100 IMAGEFRAME FrameRadar =
101 {
102 	0, 0, 0, 0,
103 	IMAGE_FRAME_C0,
104 	IMAGE_FRAME_C1,
105 	IMAGE_FRAME_C3,
106 	IMAGE_FRAME_C2,
107 	IMAGE_FRAME_HT, FR_SOLID,
108 	IMAGE_FRAME_VR, FR_SOLID,
109 	IMAGE_FRAME_HB, FR_SOLID,
110 	IMAGE_FRAME_VL, FR_SOLID,
111 	{	{FR_IGNORE, 0, 0, 0, 0 , 0},
112 		{FR_IGNORE, 0, 0, 0, 0 , 0},
113 		{FR_IGNORE, 0, 0, 0, 0 , 0},
114 		{FR_IGNORE, 0, 0, 0, 0 , 0},
115 		{FR_IGNORE, 0, 0, 0, 0 , 0}
116 	},
117 };
118 
119 // Read bitmaps used by the interface.
120 //
imageInitBitmaps()121 bool imageInitBitmaps()
122 {
123 	IntImages = (IMAGEFILE *)resGetData("IMG", "intfac.img");
124 
125 	return true;
126 }
127 
128 // Render a window frame.
129 //
RenderWindowFrame(FRAMETYPE frame,UDWORD x,UDWORD y,UDWORD Width,UDWORD Height,const glm::mat4 & modelViewProjectionMatrix)130 void RenderWindowFrame(FRAMETYPE frame, UDWORD x, UDWORD y, UDWORD Width, UDWORD Height, const glm::mat4 &modelViewProjectionMatrix)
131 {
132 	SWORD WTopRight = 0;
133 	SWORD WTopLeft = 0;
134 	SWORD WBottomRight = 0;
135 	SWORD WBottomLeft = 0;
136 	SWORD HTopRight = 0;
137 	SWORD HTopLeft = 0;
138 	SWORD HBottomRight = 0;
139 	SWORD HBottomLeft = 0;
140 	UWORD RectI;
141 	const FRAMERECT *Rect;
142 	const IMAGEFRAME *Frame = (frame == FRAME_NORMAL) ? &FrameNormal : &FrameRadar;
143 
144 	x += Frame->OffsetX0;
145 	y += Frame->OffsetY0;
146 	Width -= Frame->OffsetX1 + Frame->OffsetX0;
147 	Height -= Frame->OffsetY1 + Frame->OffsetY0;
148 
149 	for (RectI = 0; RectI < 5; RectI++)
150 	{
151 		Rect = &Frame->FRect[RectI];
152 
153 		switch (Rect->Type)
154 		{
155 		case FR_FRAME:
156 			iV_TransBoxFill(x + Rect->TLXOffset, y + Rect->TLYOffset,
157 			                x + Width - INCEND + Rect->BRXOffset, y + Height - INCEND + Rect->BRYOffset);
158 			break;
159 		case FR_LEFT:
160 			iV_TransBoxFill(x + Rect->TLXOffset, y + Rect->TLYOffset,
161 			                x + Rect->BRXOffset, y + Height - INCEND + Rect->BRYOffset);
162 			break;
163 		case FR_RIGHT:
164 			iV_TransBoxFill(x + Width - INCEND + Rect->TLXOffset, y + Rect->TLYOffset,
165 			                x + Width - INCEND + Rect->BRXOffset, y + Height - INCEND + Rect->BRYOffset);
166 			break;
167 		case FR_TOP:
168 			iV_TransBoxFill(x + Rect->TLXOffset, y + Rect->TLYOffset,
169 			                x + Width - INCEND + Rect->BRXOffset, y + Rect->BRYOffset);
170 			break;
171 		case FR_BOTTOM:
172 			iV_TransBoxFill(x + Rect->TLXOffset, y + Height - INCEND + Rect->TLYOffset,
173 			                x + Width - INCEND + Rect->BRXOffset, y + Height - INCEND + Rect->BRYOffset);
174 			break;
175 		case FR_IGNORE:
176 			break; // ignored
177 		}
178 	}
179 
180 	BatchedImageDrawRequests imageDrawBatch(true); // defer drawing
181 
182 	if (Frame->TopLeft >= 0)
183 	{
184 		WTopLeft = (SWORD)iV_GetImageWidth(IntImages, Frame->TopLeft);
185 		HTopLeft = (SWORD)iV_GetImageHeight(IntImages, Frame->TopLeft);
186 		iV_DrawImage(IntImages, Frame->TopLeft, x, y, modelViewProjectionMatrix, &imageDrawBatch);
187 	}
188 
189 	if (Frame->TopRight >= 0)
190 	{
191 		WTopRight = (SWORD)iV_GetImageWidth(IntImages, Frame->TopRight);
192 		HTopRight = (SWORD)iV_GetImageHeight(IntImages, Frame->TopRight);
193 		iV_DrawImage(IntImages, Frame->TopRight, x + Width - WTopRight, y, modelViewProjectionMatrix, &imageDrawBatch);
194 	}
195 
196 	if (Frame->BottomRight >= 0)
197 	{
198 		WBottomRight = (SWORD)iV_GetImageWidth(IntImages, Frame->BottomRight);
199 		HBottomRight = (SWORD)iV_GetImageHeight(IntImages, Frame->BottomRight);
200 		iV_DrawImage(IntImages, Frame->BottomRight, x + Width - WBottomRight, y + Height - HBottomRight, modelViewProjectionMatrix, &imageDrawBatch);
201 	}
202 
203 	if (Frame->BottomLeft >= 0)
204 	{
205 		WBottomLeft = (SWORD)iV_GetImageWidth(IntImages, Frame->BottomLeft);
206 		HBottomLeft = (SWORD)iV_GetImageHeight(IntImages, Frame->BottomLeft);
207 		iV_DrawImage(IntImages, Frame->BottomLeft, x, y + Height - HBottomLeft, modelViewProjectionMatrix, &imageDrawBatch);
208 	}
209 
210 	if (Frame->TopEdge >= 0)
211 	{
212 		iV_DrawImageRepeatX(IntImages, Frame->TopEdge, x + iV_GetImageWidth(IntImages, Frame->TopLeft), y,
213 		                    Width - WTopLeft - WTopRight, modelViewProjectionMatrix, false, &imageDrawBatch);
214 	}
215 
216 	if (Frame->BottomEdge >= 0)
217 	{
218 		iV_DrawImageRepeatX(IntImages, Frame->BottomEdge, x + WBottomLeft, y + Height - iV_GetImageHeight(IntImages, Frame->BottomEdge),
219 		                    Width - WBottomLeft - WBottomRight, modelViewProjectionMatrix, false, &imageDrawBatch);
220 	}
221 
222 	if (Frame->LeftEdge >= 0)
223 	{
224 		iV_DrawImageRepeatY(IntImages, Frame->LeftEdge, x, y + HTopLeft, Height - HTopLeft - HBottomLeft, modelViewProjectionMatrix, &imageDrawBatch);
225 	}
226 
227 	if (Frame->RightEdge >= 0)
228 	{
229 		iV_DrawImageRepeatY(IntImages, Frame->RightEdge, x + Width - iV_GetImageWidth(IntImages, Frame->RightEdge), y + HTopRight,
230 		                    Height - HTopRight - HBottomRight, modelViewProjectionMatrix, &imageDrawBatch);
231 	}
232 
233 	imageDrawBatch.draw(true);
234 }
235 
initialize()236 void IntListTabWidget::initialize()
237 {
238 	ListTabWidget::initialize();
239 	tabWidget()->setHeight(15);
240 	tabWidget()->addStyle(TabSelectionStyle(Image(IntImages, IMAGE_TAB1),    Image(IntImages, IMAGE_TAB1DOWN),    Image(IntImages, IMAGE_TABHILIGHT),    Image(), Image(), Image(), Image(), Image(), Image(), 2));
241 	tabWidget()->addStyle(TabSelectionStyle(Image(IntImages, IMAGE_TAB1_SM), Image(IntImages, IMAGE_TAB1DOWN_SM), Image(IntImages, IMAGE_TABHILIGHT_SM), Image(), Image(), Image(), Image(), Image(), Image(), 2));
242 	tabWidget()->addStyle(TabSelectionStyle(Image(IntImages, IMAGE_TAB1_SM), Image(IntImages, IMAGE_TAB1DOWN_SM), Image(IntImages, IMAGE_TABHILIGHT_SM), Image(IntImages, IMAGE_LFTTAB), Image(IntImages, IMAGE_LFTTABD), Image(IntImages, IMAGE_LFTTABD), Image(IntImages, IMAGE_RGTTAB), Image(IntImages, IMAGE_RGTTABD), Image(IntImages, IMAGE_RGTTABD), 2));
243 }
244