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