author | unc0rr |
Thu, 30 Apr 2009 20:16:58 +0000 | |
changeset 2019 | b3f1eda8865f |
parent 2017 | 7845c77c8d31 |
child 2022 | 9bbf8af42ace |
permissions | -rw-r--r-- |
4 | 1 |
(* |
1066 | 2 |
* Hedgewars, a free turn based strategy game |
883 | 3 |
* Copyright (c) 2004-2008 Andrey Korotaev <unC0Rr@gmail.com> |
4 | 4 |
* |
183 | 5 |
* This program is free software; you can redistribute it and/or modify |
6 |
* it under the terms of the GNU General Public License as published by |
|
7 |
* the Free Software Foundation; version 2 of the License |
|
4 | 8 |
* |
183 | 9 |
* This program is distributed in the hope that it will be useful, |
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
* GNU General Public License for more details. |
|
4 | 13 |
* |
183 | 14 |
* You should have received a copy of the GNU General Public License |
15 |
* along with this program; if not, write to the Free Software |
|
16 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
4 | 17 |
*) |
18 |
||
19 |
unit uStore; |
|
20 |
interface |
|
2017 | 21 |
uses sysutils, uConsts, uTeams, SDLh, |
1906 | 22 |
{$IFDEF IPHONE} |
23 |
gles11, |
|
24 |
{$ELSE} |
|
25 |
GL, |
|
26 |
{$ENDIF} |
|
27 |
uFloat; |
|
4 | 28 |
{$INCLUDE options.inc} |
29 |
||
30 |
procedure StoreInit; |
|
31 |
procedure StoreLoad; |
|
32 |
procedure StoreRelease; |
|
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
33 |
procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
34 |
procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
35 |
procedure DrawSprite2(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
1939 | 36 |
procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
37 |
procedure DrawSurfSprite(X, Y, Height, Frame: LongInt; Source: PTexture); |
762 | 38 |
procedure DrawTexture(X, Y: LongInt; Texture: PTexture); |
1251 | 39 |
procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, Frames: LongInt); |
822 | 40 |
procedure DrawRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); |
853 | 41 |
procedure DrawRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); |
822 | 42 |
procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
762 | 43 |
procedure DrawCentered(X, Top: LongInt; Source: PTexture); |
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
44 |
procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
1865
ebc6dfca60d4
- nemo's patch: some animations, zero probability for infinite weapons
unc0rr
parents:
1854
diff
changeset
|
45 |
procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
1431 | 46 |
procedure DrawFillRect(r: TSDL_Rect); |
762 | 47 |
function RenderStringTex(s: string; Color: Longword; font: THWFont): PTexture; |
2017 | 48 |
function RenderSpeechBubbleTex(s: string; SpeechType: Longword; font: THWFont): PTexture; |
49 |
procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); |
|
50 |
//procedure rotateSurface(Surface: PSDL_Surface); |
|
51 |
procedure copyRotatedSurface(src, dest: PSDL_Surface); // this is necessary since width/height are read only in SDL |
|
52 |
procedure copyToXY(src, dest: PSDL_Surface; destX, destY: Integer); |
|
4 | 53 |
procedure RenderHealth(var Hedgehog: THedgehog); |
54 |
procedure AddProgress; |
|
510 | 55 |
procedure FinishProgress; |
518 | 56 |
function LoadImage(const filename: string; hasAlpha, critical, setTransparent: boolean): PSDL_Surface; |
753 | 57 |
procedure SetupOpenGL; |
4 | 58 |
|
1525 | 59 |
var PixelFormat: PSDL_PixelFormat = nil; |
60 |
SDLPrimSurface: PSDL_Surface = nil; |
|
1023 | 61 |
PauseTexture, |
62 |
ConfirmTexture: PTexture; |
|
4 | 63 |
|
64 |
implementation |
|
1906 | 65 |
uses uMisc, uConsole, uLand, uLocale; |
4 | 66 |
|
690 | 67 |
var |
761 | 68 |
HHTexture: PTexture; |
4 | 69 |
|
70 |
procedure StoreInit; |
|
71 |
begin |
|
72 |
||
73 |
end; |
|
74 |
||
351 | 75 |
procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); |
47 | 76 |
var r: TSDL_Rect; |
77 |
begin |
|
78 |
r:= rect^; |
|
83 | 79 |
if Clear then SDL_FillRect(Surface, @r, 0); |
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
80 |
|
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
81 |
BorderColor:= SDL_MapRGB(Surface^.format, BorderColor shr 16, BorderColor shr 8, BorderColor and $FF); |
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
82 |
FillColor:= SDL_MapRGB(Surface^.format, FillColor shr 16, FillColor shr 8, FillColor and $FF); |
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
83 |
|
351 | 84 |
r.y:= rect^.y + 1; |
85 |
r.h:= rect^.h - 2; |
|
47 | 86 |
SDL_FillRect(Surface, @r, BorderColor); |
351 | 87 |
r.x:= rect^.x + 1; |
88 |
r.w:= rect^.w - 2; |
|
89 |
r.y:= rect^.y; |
|
90 |
r.h:= rect^.h; |
|
47 | 91 |
SDL_FillRect(Surface, @r, BorderColor); |
351 | 92 |
r.x:= rect^.x + 2; |
93 |
r.y:= rect^.y + 1; |
|
94 |
r.w:= rect^.w - 4; |
|
95 |
r.h:= rect^.h - 2; |
|
47 | 96 |
SDL_FillRect(Surface, @r, FillColor); |
351 | 97 |
r.x:= rect^.x + 1; |
98 |
r.y:= rect^.y + 2; |
|
99 |
r.w:= rect^.w - 2; |
|
100 |
r.h:= rect^.h - 4; |
|
47 | 101 |
SDL_FillRect(Surface, @r, FillColor) |
102 |
end; |
|
103 |
||
371 | 104 |
function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: string): TSDL_Rect; |
351 | 105 |
var w, h: LongInt; |
4 | 106 |
tmpsurf: PSDL_Surface; |
107 |
clr: TSDL_Color; |
|
351 | 108 |
Result: TSDL_Rect; |
4 | 109 |
begin |
355 | 110 |
TTF_SizeUTF8(Fontz[Font].Handle, Str2PChar(s), w, h); |
4 | 111 |
Result.x:= X; |
112 |
Result.y:= Y; |
|
202 | 113 |
Result.w:= w + FontBorder * 2 + 4; |
114 |
Result.h:= h + FontBorder * 2; |
|
351 | 115 |
DrawRoundRect(@Result, cWhiteColor, cColorNearBlack, Surface, true); |
189 | 116 |
clr.r:= Color shr 16; |
117 |
clr.g:= (Color shr 8) and $FF; |
|
118 |
clr.b:= Color and $FF; |
|
355 | 119 |
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(s), clr.value); |
202 | 120 |
Result.x:= X + FontBorder + 2; |
121 |
Result.y:= Y + FontBorder; |
|
199 | 122 |
SDLTry(tmpsurf <> nil, true); |
4 | 123 |
SDL_UpperBlit(tmpsurf, nil, Surface, @Result); |
124 |
SDL_FreeSurface(tmpsurf); |
|
125 |
Result.x:= X; |
|
126 |
Result.y:= Y; |
|
202 | 127 |
Result.w:= w + FontBorder * 2 + 4; |
351 | 128 |
Result.h:= h + FontBorder * 2; |
129 |
WriteInRoundRect:= Result |
|
4 | 130 |
end; |
131 |
||
132 |
procedure StoreLoad; |
|
844 | 133 |
var s: string; |
4 | 134 |
|
1185 | 135 |
procedure WriteNames(Font: THWFont); |
136 |
var t: LongInt; |
|
137 |
i: LongInt; |
|
138 |
r, rr: TSDL_Rect; |
|
139 |
drY: LongInt; |
|
140 |
texsurf: PSDL_Surface; |
|
141 |
begin |
|
142 |
r.x:= 0; |
|
143 |
r.y:= 0; |
|
144 |
drY:= - 4; |
|
145 |
for t:= 0 to Pred(TeamsCount) do |
|
146 |
with TeamsArray[t]^ do |
|
147 |
begin |
|
148 |
NameTagTex:= RenderStringTex(TeamName, Clan^.Color, Font); |
|
690 | 149 |
|
1185 | 150 |
r.w:= cTeamHealthWidth + 5; |
151 |
r.h:= NameTagTex^.h; |
|
690 | 152 |
|
1185 | 153 |
texsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 32, RMask, GMask, BMask, AMask); |
154 |
TryDo(texsurf <> nil, errmsgCreateSurface, true); |
|
155 |
TryDo(SDL_SetColorKey(texsurf, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
|
690 | 156 |
|
1185 | 157 |
DrawRoundRect(@r, cWhiteColor, cColorNearBlack, texsurf, true); |
158 |
rr:= r; |
|
159 |
inc(rr.x, 2); dec(rr.w, 4); inc(rr.y, 2); dec(rr.h, 4); |
|
160 |
DrawRoundRect(@rr, Clan^.Color, Clan^.Color, texsurf, false); |
|
161 |
HealthTex:= Surface2Tex(texsurf); |
|
162 |
SDL_FreeSurface(texsurf); |
|
690 | 163 |
|
1185 | 164 |
dec(drY, r.h + 2); |
165 |
DrawHealthY:= drY; |
|
166 |
for i:= 0 to 7 do |
|
167 |
with Hedgehogs[i] do |
|
168 |
if Gear <> nil then |
|
1242 | 169 |
begin |
1185 | 170 |
NameTagTex:= RenderStringTex(Name, Clan^.Color, fnt16); |
1294
50198e5c7f02
- Hedgehog doesn't take off hat when shooting from shotgun
unc0rr
parents:
1251
diff
changeset
|
171 |
if Hat <> 'NoHat' then |
50198e5c7f02
- Hedgehog doesn't take off hat when shooting from shotgun
unc0rr
parents:
1251
diff
changeset
|
172 |
begin |
1698 | 173 |
texsurf:= LoadImage(Pathz[ptHats] + '/' + Hat, false, false, false); |
174 |
if texsurf <> nil then |
|
175 |
begin |
|
176 |
HatTex:= Surface2Tex(texsurf); |
|
177 |
SDL_FreeSurface(texsurf) |
|
178 |
end |
|
1294
50198e5c7f02
- Hedgehog doesn't take off hat when shooting from shotgun
unc0rr
parents:
1251
diff
changeset
|
179 |
end |
1242 | 180 |
end; |
1185 | 181 |
end; |
182 |
end; |
|
4 | 183 |
|
1185 | 184 |
procedure MakeCrossHairs; |
185 |
var t: LongInt; |
|
186 |
tmpsurf, texsurf: PSDL_Surface; |
|
187 |
Color, i: Longword; |
|
188 |
begin |
|
189 |
s:= Pathz[ptGraphics] + '/' + cCHFileName; |
|
190 |
tmpsurf:= LoadImage(s, true, true, false); |
|
4 | 191 |
|
1185 | 192 |
for t:= 0 to Pred(TeamsCount) do |
193 |
with TeamsArray[t]^ do |
|
194 |
begin |
|
195 |
texsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, tmpsurf^.w, tmpsurf^.h, 32, RMask, GMask, BMask, AMask); |
|
196 |
TryDo(texsurf <> nil, errmsgCreateSurface, true); |
|
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
197 |
|
1185 | 198 |
Color:= Clan^.Color; |
199 |
Color:= SDL_MapRGB(texsurf^.format, Color shr 16, Color shr 8, Color and $FF); |
|
200 |
SDL_FillRect(texsurf, nil, Color); |
|
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
201 |
|
1185 | 202 |
SDL_UpperBlit(tmpsurf, nil, texsurf, nil); |
777 | 203 |
|
1185 | 204 |
TryDo(tmpsurf^.format^.BytesPerPixel = 4, 'Ooops', true); |
777 | 205 |
|
1185 | 206 |
if SDL_MustLock(texsurf) then |
207 |
SDLTry(SDL_LockSurface(texsurf) >= 0, true); |
|
777 | 208 |
|
1185 | 209 |
// make black pixel be alpha-transparent |
210 |
for i:= 0 to texsurf^.w * texsurf^.h - 1 do |
|
211 |
if PLongwordArray(texsurf^.pixels)^[i] = $FF000000 then PLongwordArray(texsurf^.pixels)^[i]:= 0; |
|
777 | 212 |
|
1185 | 213 |
if SDL_MustLock(texsurf) then |
214 |
SDL_UnlockSurface(texsurf); |
|
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
215 |
|
1185 | 216 |
CrosshairTex:= Surface2Tex(texsurf); |
217 |
SDL_FreeSurface(texsurf) |
|
218 |
end; |
|
351 | 219 |
|
1185 | 220 |
SDL_FreeSurface(tmpsurf) |
221 |
end; |
|
4 | 222 |
|
1185 | 223 |
procedure InitHealth; |
224 |
var i, t: LongInt; |
|
225 |
begin |
|
226 |
for t:= 0 to Pred(TeamsCount) do |
|
227 |
if TeamsArray[t] <> nil then |
|
228 |
with TeamsArray[t]^ do |
|
229 |
begin |
|
230 |
for i:= 0 to cMaxHHIndex do |
|
231 |
if Hedgehogs[i].Gear <> nil then |
|
232 |
RenderHealth(Hedgehogs[i]); |
|
233 |
end |
|
234 |
end; |
|
4 | 235 |
|
1185 | 236 |
procedure LoadGraves; |
237 |
var t: LongInt; |
|
238 |
texsurf: PSDL_Surface; |
|
239 |
begin |
|
240 |
for t:= 0 to Pred(TeamsCount) do |
|
241 |
if TeamsArray[t] <> nil then |
|
242 |
with TeamsArray[t]^ do |
|
243 |
begin |
|
244 |
if GraveName = '' then GraveName:= 'Simple'; |
|
245 |
texsurf:= LoadImage(Pathz[ptGraves] + '/' + GraveName, false, true, true); |
|
246 |
GraveTex:= Surface2Tex(texsurf); |
|
247 |
SDL_FreeSurface(texsurf) |
|
248 |
end |
|
249 |
end; |
|
4 | 250 |
|
844 | 251 |
var ii: TSprite; |
252 |
fi: THWFont; |
|
253 |
ai: TAmmoType; |
|
254 |
tmpsurf: PSDL_Surface; |
|
255 |
i: LongInt; |
|
4 | 256 |
begin |
257 |
for fi:= Low(THWFont) to High(THWFont) do |
|
1185 | 258 |
with Fontz[fi] do |
259 |
begin |
|
260 |
s:= Pathz[ptFonts] + '/' + Name; |
|
261 |
WriteToConsole(msgLoading + s + '... '); |
|
262 |
Handle:= TTF_OpenFont(Str2PChar(s), Height); |
|
263 |
SDLTry(Handle <> nil, true); |
|
264 |
TTF_SetFontStyle(Handle, style); |
|
265 |
WriteLnToConsole(msgOK) |
|
266 |
end; |
|
4 | 267 |
AddProgress; |
53 | 268 |
|
4 | 269 |
WriteNames(fnt16); |
70 | 270 |
MakeCrossHairs; |
4 | 271 |
LoadGraves; |
272 |
||
273 |
AddProgress; |
|
274 |
for ii:= Low(TSprite) to High(TSprite) do |
|
1185 | 275 |
with SpritesData[ii] do |
1939 | 276 |
if (not cReducedQuality) or |
277 |
((ii <> sprSky) and (ii <> sprHorizont) and (ii <> sprFlake)) then |
|
1185 | 278 |
begin |
279 |
if AltPath = ptNone then |
|
280 |
tmpsurf:= LoadImage(Pathz[Path] + '/' + FileName, true, true, true) |
|
281 |
else begin |
|
282 |
tmpsurf:= LoadImage(Pathz[Path] + '/' + FileName, true, false, true); |
|
283 |
if tmpsurf = nil then |
|
284 |
tmpsurf:= LoadImage(Pathz[AltPath] + '/' + FileName, true, true, true) |
|
285 |
end; |
|
286 |
if Width = 0 then Width:= tmpsurf^.w; |
|
287 |
if Height = 0 then Height:= tmpsurf^.h; |
|
288 |
Texture:= Surface2Tex(tmpsurf); |
|
289 |
if saveSurf then Surface:= tmpsurf else SDL_FreeSurface(tmpsurf) |
|
290 |
end; |
|
80 | 291 |
|
4 | 292 |
AddProgress; |
567 | 293 |
|
761 | 294 |
tmpsurf:= LoadImage(Pathz[ptGraphics] + '/' + cHHFileName, true, true, true); |
295 |
HHTexture:= Surface2Tex(tmpsurf); |
|
296 |
SDL_FreeSurface(tmpsurf); |
|
4 | 297 |
|
298 |
InitHealth; |
|
299 |
||
762 | 300 |
PauseTexture:= RenderStringTex(trmsg[sidPaused], $FFFF00, fntBig); |
1023 | 301 |
ConfirmTexture:= RenderStringTex(trmsg[sidConfirm], $FFFF00, fntBig); |
281
5b483aa9f2ab
Pause support (mouse cursor is released when the game is paused)
unc0rr
parents:
208
diff
changeset
|
302 |
|
843 | 303 |
for ai:= Low(TAmmoType) to High(TAmmoType) do |
304 |
with Ammoz[ai] do |
|
305 |
begin |
|
306 |
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(trAmmo[NameId]), $FFFFFF); |
|
307 |
NameTex:= Surface2Tex(tmpsurf); |
|
308 |
SDL_FreeSurface(tmpsurf) |
|
309 |
end; |
|
310 |
||
844 | 311 |
for i:= Low(CountTexz) to High(CountTexz) do |
312 |
begin |
|
313 |
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i) + 'x'), $FFFFFF); |
|
314 |
CountTexz[i]:= Surface2Tex(tmpsurf); |
|
315 |
SDL_FreeSurface(tmpsurf) |
|
316 |
end; |
|
317 |
||
4 | 318 |
{$IFDEF DUMP} |
319 |
SDL_SaveBMP_RW(LandSurface, SDL_RWFromFile('LandSurface.bmp', 'wb'), 1); |
|
320 |
SDL_SaveBMP_RW(StoreSurface, SDL_RWFromFile('StoreSurface.bmp', 'wb'), 1); |
|
321 |
{$ENDIF} |
|
322 |
end; |
|
323 |
||
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
324 |
procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
4 | 325 |
var rr: TSDL_Rect; |
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
326 |
_l, _r, _t, _b: real; |
1916 | 327 |
VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
4 | 328 |
begin |
759 | 329 |
if SourceTexture^.h = 0 then exit; |
4 | 330 |
rr.x:= X; |
331 |
rr.y:= Y; |
|
351 | 332 |
rr.w:= r^.w; |
333 |
rr.h:= r^.h; |
|
755 | 334 |
|
1896 | 335 |
_l:= r^.x / SourceTexture^.w * SourceTexture^.rx; |
336 |
_r:= (r^.x + r^.w) / SourceTexture^.w * SourceTexture^.rx; |
|
337 |
_t:= r^.y / SourceTexture^.h * SourceTexture^.ry; |
|
338 |
_b:= (r^.y + r^.h) / SourceTexture^.h * SourceTexture^.ry; |
|
755 | 339 |
|
340 |
glBindTexture(GL_TEXTURE_2D, SourceTexture^.id); |
|
341 |
||
1916 | 342 |
VertexBuffer[0].X:= X; |
343 |
VertexBuffer[0].Y:= Y; |
|
344 |
VertexBuffer[1].X:= rr.w + X; |
|
345 |
VertexBuffer[1].Y:= Y; |
|
346 |
VertexBuffer[2].X:= rr.w + X; |
|
347 |
VertexBuffer[2].Y:= rr.h + Y; |
|
348 |
VertexBuffer[3].X:= X; |
|
349 |
VertexBuffer[3].Y:= rr.h + Y; |
|
755 | 350 |
|
1916 | 351 |
TextureBuffer[0].X:= _l; |
352 |
TextureBuffer[0].Y:= _t; |
|
353 |
TextureBuffer[1].X:= _r; |
|
354 |
TextureBuffer[1].Y:= _t; |
|
355 |
TextureBuffer[2].X:= _r; |
|
356 |
TextureBuffer[2].Y:= _b; |
|
357 |
TextureBuffer[3].X:= _l; |
|
358 |
TextureBuffer[3].Y:= _b; |
|
755 | 359 |
|
1916 | 360 |
glEnableClientState(GL_VERTEX_ARRAY); |
361 |
glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
755 | 362 |
|
1916 | 363 |
glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
364 |
glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
|
365 |
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
366 |
||
367 |
glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
|
368 |
glDisableClientState(GL_VERTEX_ARRAY) |
|
762 | 369 |
end; |
370 |
||
371 |
procedure DrawTexture(X, Y: LongInt; Texture: PTexture); |
|
372 |
begin |
|
1904 | 373 |
glPushMatrix; |
374 |
glTranslatef(X, Y, 0); |
|
375 |
||
762 | 376 |
glBindTexture(GL_TEXTURE_2D, Texture^.id); |
377 |
||
1904 | 378 |
glEnableClientState(GL_VERTEX_ARRAY); |
379 |
glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
762 | 380 |
|
1912
c3d31fb59f0e
Save much CPU time by initializing vertex arrays in texture creation function
unc0rr
parents:
1908
diff
changeset
|
381 |
glVertexPointer(2, GL_FLOAT, 0, @Texture^.vb); |
c3d31fb59f0e
Save much CPU time by initializing vertex arrays in texture creation function
unc0rr
parents:
1908
diff
changeset
|
382 |
glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb); |
c3d31fb59f0e
Save much CPU time by initializing vertex arrays in texture creation function
unc0rr
parents:
1908
diff
changeset
|
383 |
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb)); |
1904 | 384 |
|
385 |
glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
|
386 |
glDisableClientState(GL_VERTEX_ARRAY); |
|
387 |
||
388 |
glPopMatrix |
|
4 | 389 |
end; |
390 |
||
1251 | 391 |
procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, Frames: LongInt); |
1242 | 392 |
var ft, fb: GLfloat; |
393 |
hw: LongInt; |
|
1916 | 394 |
VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
1242 | 395 |
begin |
396 |
glPushMatrix; |
|
397 |
glTranslatef(X, Y, 0); |
|
1251 | 398 |
glScalef(Scale, Scale, 1.0); |
1242 | 399 |
|
400 |
if Dir < 0 then |
|
401 |
hw:= - 16 |
|
402 |
else |
|
403 |
hw:= 16; |
|
404 |
||
1896 | 405 |
ft:= Frame / Frames * Texture^.ry; |
406 |
fb:= (Frame + 1) / Frames * Texture^.ry; |
|
1242 | 407 |
|
408 |
glBindTexture(GL_TEXTURE_2D, Texture^.id); |
|
409 |
||
1916 | 410 |
VertexBuffer[0].X:= -hw; |
411 |
VertexBuffer[0].Y:= -16; |
|
412 |
VertexBuffer[1].X:= hw; |
|
413 |
VertexBuffer[1].Y:= -16; |
|
414 |
VertexBuffer[2].X:= hw; |
|
415 |
VertexBuffer[2].Y:= 16; |
|
416 |
VertexBuffer[3].X:= -hw; |
|
417 |
VertexBuffer[3].Y:= 16; |
|
1242 | 418 |
|
1916 | 419 |
TextureBuffer[0].X:= 0; |
420 |
TextureBuffer[0].Y:= ft; |
|
421 |
TextureBuffer[1].X:= Texture^.rx; |
|
422 |
TextureBuffer[1].Y:= ft; |
|
423 |
TextureBuffer[2].X:= Texture^.rx; |
|
424 |
TextureBuffer[2].Y:= fb; |
|
425 |
TextureBuffer[3].X:= 0; |
|
426 |
TextureBuffer[3].Y:= fb; |
|
1242 | 427 |
|
1916 | 428 |
glEnableClientState(GL_VERTEX_ARRAY); |
429 |
glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
1242 | 430 |
|
1916 | 431 |
glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
432 |
glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
|
433 |
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
434 |
||
435 |
glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
|
436 |
glDisableClientState(GL_VERTEX_ARRAY); |
|
437 |
||
1242 | 438 |
|
439 |
glPopMatrix |
|
440 |
end; |
|
441 |
||
822 | 442 |
procedure DrawRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); |
775 | 443 |
begin |
777 | 444 |
DrawRotatedTex(SpritesData[Sprite].Texture, |
822 | 445 |
SpritesData[Sprite].Width, |
446 |
SpritesData[Sprite].Height, |
|
447 |
X, Y, Dir, Angle) |
|
777 | 448 |
end; |
449 |
||
853 | 450 |
procedure DrawRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); |
806 | 451 |
begin |
452 |
glPushMatrix; |
|
809 | 453 |
glTranslatef(X, Y, 0); |
806 | 454 |
glRotatef(Angle, 0, 0, 1); |
455 |
||
853 | 456 |
if Dir < 0 then glScalef(-1.0, 1.0, 1.0); |
457 |
||
458 |
DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame); |
|
806 | 459 |
|
460 |
glPopMatrix |
|
461 |
end; |
|
462 |
||
822 | 463 |
procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
1916 | 464 |
var VertexBuffer: array [0..3] of TVertex2f; |
777 | 465 |
begin |
775 | 466 |
glPushMatrix; |
467 |
glTranslatef(X, Y, 0); |
|
822 | 468 |
|
469 |
if Dir < 0 then |
|
470 |
begin |
|
471 |
hw:= - hw; |
|
472 |
glRotatef(Angle, 0, 0, -1); |
|
473 |
end else |
|
474 |
glRotatef(Angle, 0, 0, 1); |
|
475 |
||
775 | 476 |
|
777 | 477 |
glBindTexture(GL_TEXTURE_2D, Tex^.id); |
775 | 478 |
|
1916 | 479 |
VertexBuffer[0].X:= -hw; |
480 |
VertexBuffer[0].Y:= -hh; |
|
481 |
VertexBuffer[1].X:= hw; |
|
482 |
VertexBuffer[1].Y:= -hh; |
|
483 |
VertexBuffer[2].X:= hw; |
|
484 |
VertexBuffer[2].Y:= hh; |
|
485 |
VertexBuffer[3].X:= -hw; |
|
486 |
VertexBuffer[3].Y:= hh; |
|
775 | 487 |
|
1916 | 488 |
glEnableClientState(GL_VERTEX_ARRAY); |
489 |
glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
775 | 490 |
|
1916 | 491 |
glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
492 |
glTexCoordPointer(2, GL_FLOAT, 0, @Tex^.tb); |
|
493 |
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
775 | 494 |
|
1916 | 495 |
glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
496 |
glDisableClientState(GL_VERTEX_ARRAY); |
|
775 | 497 |
|
498 |
glPopMatrix |
|
499 |
end; |
|
500 |
||
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
501 |
procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
4 | 502 |
begin |
503 |
r.y:= r.y + Height * Position; |
|
504 |
r.h:= Height; |
|
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
505 |
DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
4 | 506 |
end; |
507 |
||
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
508 |
procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
755 | 509 |
var r: TSDL_Rect; |
4 | 510 |
begin |
755 | 511 |
r.x:= 0; |
512 |
r.w:= SpritesData[Sprite].Width; |
|
513 |
r.y:= Frame * SpritesData[Sprite].Height; |
|
514 |
r.h:= SpritesData[Sprite].Height; |
|
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
515 |
DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
4 | 516 |
end; |
517 |
||
1939 | 518 |
procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
519 |
var r: TSDL_Rect; |
|
520 |
begin |
|
521 |
r.x:= 0; |
|
522 |
r.y:= 0; |
|
523 |
r.w:= SpritesData[Sprite].Width; |
|
524 |
r.h:= SpritesData[Sprite].Height; |
|
525 |
||
526 |
if (X < LeftX) then |
|
527 |
r.x:= LeftX - X; |
|
528 |
if (Y < TopY) then |
|
529 |
r.y:= TopY - Y; |
|
530 |
||
531 |
if (Y + SpritesData[Sprite].Height > BottomY) then |
|
532 |
r.h:= BottomY - Y + 1; |
|
533 |
if (X + SpritesData[Sprite].Width > RightX) then |
|
534 |
r.w:= RightX - X + 1; |
|
535 |
||
536 |
dec(r.h, r.y); |
|
537 |
dec(r.w, r.x); |
|
538 |
||
539 |
DrawFromRect(X + r.x, Y + r.y, @r, SpritesData[Sprite].Texture) |
|
540 |
end; |
|
541 |
||
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
542 |
procedure DrawSprite2(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
43 | 543 |
var r: TSDL_Rect; |
544 |
begin |
|
545 |
r.x:= FrameX * SpritesData[Sprite].Width; |
|
546 |
r.w:= SpritesData[Sprite].Width; |
|
547 |
r.y:= FrameY * SpritesData[Sprite].Height; |
|
548 |
r.h:= SpritesData[Sprite].Height; |
|
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
549 |
DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
43 | 550 |
end; |
551 |
||
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
552 |
procedure DrawSurfSprite(X, Y, Height, Frame: LongInt; Source: PTexture); |
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
553 |
var r: TSDL_Rect; |
198 | 554 |
begin |
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
555 |
r.x:= 0; |
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
556 |
r.w:= Source^.w; |
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
557 |
r.y:= Frame * Height; |
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
558 |
r.h:= Height; |
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
559 |
DrawFromRect(X, Y, @r, Source) |
198 | 560 |
end; |
561 |
||
762 | 562 |
procedure DrawCentered(X, Top: LongInt; Source: PTexture); |
95 | 563 |
begin |
762 | 564 |
DrawTexture(X - Source^.w div 2, Top, Source) |
4 | 565 |
end; |
566 |
||
1865
ebc6dfca60d4
- nemo's patch: some animations, zero probability for infinite weapons
unc0rr
parents:
1854
diff
changeset
|
567 |
procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
1916 | 568 |
const VertexBuffer: array [0..3] of TVertex2f = ( |
569 |
(x: -16; y: -16), |
|
570 |
(x: 16; y: -16), |
|
571 |
(x: 16; y: 16), |
|
572 |
(x: -16; y: 16)); |
|
761 | 573 |
var l, r, t, b: real; |
1916 | 574 |
TextureBuffer: array [0..3] of TVertex2f; |
4 | 575 |
begin |
761 | 576 |
|
577 |
t:= Pos * 32 / HHTexture^.h; |
|
578 |
b:= (Pos + 1) * 32 / HHTexture^.h; |
|
579 |
||
580 |
if Dir = -1 then |
|
581 |
begin |
|
582 |
l:= (Step + 1) * 32 / HHTexture^.w; |
|
583 |
r:= Step * 32 / HHTexture^.w |
|
584 |
end else |
|
585 |
begin |
|
586 |
l:= Step * 32 / HHTexture^.w; |
|
587 |
r:= (Step + 1) * 32 / HHTexture^.w |
|
588 |
end; |
|
589 |
||
821
e6c0408b54ed
Use 'regular standing' and 'rope swing' hedgehog sprites
unc0rr
parents:
809
diff
changeset
|
590 |
|
e6c0408b54ed
Use 'regular standing' and 'rope swing' hedgehog sprites
unc0rr
parents:
809
diff
changeset
|
591 |
glPushMatrix(); |
e6c0408b54ed
Use 'regular standing' and 'rope swing' hedgehog sprites
unc0rr
parents:
809
diff
changeset
|
592 |
glTranslatef(X, Y, 0); |
e6c0408b54ed
Use 'regular standing' and 'rope swing' hedgehog sprites
unc0rr
parents:
809
diff
changeset
|
593 |
glRotatef(Angle, 0, 0, 1); |
e6c0408b54ed
Use 'regular standing' and 'rope swing' hedgehog sprites
unc0rr
parents:
809
diff
changeset
|
594 |
|
761 | 595 |
glBindTexture(GL_TEXTURE_2D, HHTexture^.id); |
596 |
||
1916 | 597 |
TextureBuffer[0].X:= l; |
598 |
TextureBuffer[0].Y:= t; |
|
599 |
TextureBuffer[1].X:= r; |
|
600 |
TextureBuffer[1].Y:= t; |
|
601 |
TextureBuffer[2].X:= r; |
|
602 |
TextureBuffer[2].Y:= b; |
|
603 |
TextureBuffer[3].X:= l; |
|
604 |
TextureBuffer[3].Y:= b; |
|
761 | 605 |
|
1916 | 606 |
glEnableClientState(GL_VERTEX_ARRAY); |
607 |
glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
761 | 608 |
|
1916 | 609 |
glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
610 |
glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
|
611 |
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
761 | 612 |
|
1916 | 613 |
glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
614 |
glDisableClientState(GL_VERTEX_ARRAY); |
|
761 | 615 |
|
1854 | 616 |
|
617 |
glColor4f(1,1,1,1); |
|
821
e6c0408b54ed
Use 'regular standing' and 'rope swing' hedgehog sprites
unc0rr
parents:
809
diff
changeset
|
618 |
|
e6c0408b54ed
Use 'regular standing' and 'rope swing' hedgehog sprites
unc0rr
parents:
809
diff
changeset
|
619 |
glPopMatrix |
4 | 620 |
end; |
621 |
||
1431 | 622 |
procedure DrawFillRect(r: TSDL_Rect); |
1916 | 623 |
var VertexBuffer: array [0..3] of TVertex2f; |
1431 | 624 |
begin |
625 |
glDisable(GL_TEXTURE_2D); |
|
626 |
||
627 |
glColor4ub(0, 0, 0, 127); |
|
628 |
||
1916 | 629 |
VertexBuffer[0].X:= r.x; |
630 |
VertexBuffer[0].Y:= r.y; |
|
631 |
VertexBuffer[1].X:= r.x + r.w; |
|
632 |
VertexBuffer[1].Y:= r.y; |
|
633 |
VertexBuffer[2].X:= r.x + r.w; |
|
634 |
VertexBuffer[2].Y:= r.y + r.h; |
|
635 |
VertexBuffer[3].X:= r.x; |
|
636 |
VertexBuffer[3].Y:= r.y + r.h; |
|
1431 | 637 |
|
1916 | 638 |
glEnableClientState(GL_VERTEX_ARRAY); |
639 |
glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
|
640 |
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
641 |
glDisableClientState(GL_VERTEX_ARRAY); |
|
1431 | 642 |
|
643 |
glColor4f(1, 1, 1, 1); |
|
644 |
glEnable(GL_TEXTURE_2D) |
|
645 |
end; |
|
646 |
||
4 | 647 |
procedure StoreRelease; |
648 |
var ii: TSprite; |
|
649 |
begin |
|
650 |
for ii:= Low(TSprite) to High(TSprite) do |
|
769
788efc1d649f
- Save 8 MB of memory by freeing LandSurface and not using it anymore after game initialization
unc0rr
parents:
768
diff
changeset
|
651 |
begin |
759 | 652 |
FreeTexture(SpritesData[ii].Texture); |
769
788efc1d649f
- Save 8 MB of memory by freeing LandSurface and not using it anymore after game initialization
unc0rr
parents:
768
diff
changeset
|
653 |
if SpritesData[ii].Surface <> nil then SDL_FreeSurface(SpritesData[ii].Surface) |
788efc1d649f
- Save 8 MB of memory by freeing LandSurface and not using it anymore after game initialization
unc0rr
parents:
768
diff
changeset
|
654 |
end; |
761 | 655 |
|
1806 | 656 |
FreeTexture(HHTexture) |
4 | 657 |
end; |
658 |
||
762 | 659 |
function RenderStringTex(s: string; Color: Longword; font: THWFont): PTexture; |
432 | 660 |
var w, h: LongInt; |
351 | 661 |
Result: PSDL_Surface; |
95 | 662 |
begin |
1989 | 663 |
if length(s) = 0 then s:= ' '; |
355 | 664 |
TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(s), w, h); |
785 | 665 |
|
762 | 666 |
Result:= SDL_CreateRGBSurface(SDL_SWSURFACE, w + FontBorder * 2 + 4, h + FontBorder * 2, |
667 |
32, RMask, GMask, BMask, AMask); |
|
785 | 668 |
|
107 | 669 |
TryDo(Result <> nil, 'RenderString: fail to create surface', true); |
785 | 670 |
|
95 | 671 |
WriteInRoundRect(Result, 0, 0, Color, font, s); |
785 | 672 |
|
762 | 673 |
TryDo(SDL_SetColorKey(Result, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
785 | 674 |
|
762 | 675 |
RenderStringTex:= Surface2Tex(Result); |
785 | 676 |
|
762 | 677 |
SDL_FreeSurface(Result) |
95 | 678 |
end; |
679 |
||
2017 | 680 |
function RenderSpeechBubbleTex(s: string; SpeechType: Longword; font: THWFont): PTexture; |
681 |
var textWidth, textHeight, x, y, w, h, i, pos, prevpos, line, numLines, edgeWidth, edgeHeight, cornerWidth, cornerHeight: LongInt; |
|
682 |
Result, tmpsurf, rotatedEdge: PSDL_Surface; |
|
683 |
rect: TSDL_Rect; |
|
684 |
chars: TSysCharSet = [#9,' ','.',';',':','?','!',',']; |
|
685 |
substr: shortstring; |
|
686 |
edge, corner, tail: TSPrite; |
|
687 |
begin |
|
688 |
||
689 |
case SpeechType of |
|
690 |
1: begin; |
|
691 |
edge:= sprSpeechEdge; |
|
692 |
corner:= sprSpeechCorner; |
|
693 |
tail:= sprSpeechTail; |
|
694 |
end; |
|
695 |
2: begin; |
|
696 |
edge:= sprThoughtEdge; |
|
697 |
corner:= sprThoughtCorner; |
|
698 |
tail:= sprThoughtTail; |
|
699 |
end; |
|
700 |
3: begin; |
|
701 |
edge:= sprShoutEdge; |
|
702 |
corner:= sprShoutCorner; |
|
703 |
tail:= sprShoutTail; |
|
704 |
end; |
|
705 |
end; |
|
706 |
edgeHeight:= SpritesData[edge].Height; |
|
707 |
edgeWidth:= SpritesData[edge].Width; |
|
708 |
cornerWidth:= SpritesData[corner].Width; |
|
709 |
cornerHeight:= SpritesData[corner].Height; |
|
710 |
// This one screws it up |
|
711 |
s:= 'This is the song that never ends. ''cause it goes on and on my friends. Some people, started singing it not knowing what it was. And they''ll just go on singing it forever just because... This is the song that never ends...'; |
|
712 |
// This one doesn't |
|
713 |
//s:= 'This is the song that never ends. cause it goes on and on my friends. Some people, started singing it not knowing what it was. And theyll just go on singing it forever just because... This is the song that never ends... '; |
|
714 |
// Also screws up, but only action |
|
715 |
//s:= 'This is the song that never ends. cause it goes on and on .'; |
|
716 |
// ok in all |
|
717 |
// s:= 'This is the song that never ends. cause it goes on .'; |
|
718 |
numLines:= 1; |
|
719 |
||
720 |
if length(s) = 0 then s:= '...'; |
|
721 |
||
722 |
TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(s), w, h); |
|
723 |
textWidth:= w; |
|
724 |
textHeight:= h; |
|
725 |
if (length(s) > 20) then |
|
726 |
begin |
|
727 |
i:= round(Sqrt(length(s)) * 2); |
|
728 |
s:= WrapText(s, #1, chars, i); |
|
729 |
for pos:= 1 to length(s) do |
|
730 |
if (s[pos] = #1) or (pos = length(s)) then |
|
731 |
inc(numLines); |
|
732 |
||
733 |
// TODO - find out why this calc doesn't do what I expect |
|
734 |
if numLines = 2 then textWidth:= w div 2 |
|
735 |
else if numlines > 2 then textWidth:= w div (numLines-1); |
|
736 |
end; |
|
737 |
||
738 |
textWidth:=((textWidth-(cornerWidth-edgeWidth)*2) div edgeWidth)*edgeWidth+edgeWidth; |
|
739 |
textHeight:=(((numlines * h)-((cornerHeight-edgeWidth)*2)) div edgeWidth)*edgeWidth+edgeWidth; |
|
2019 | 740 |
|
2017 | 741 |
//textWidth:=max(textWidth,SpritesData[tail].Width); |
742 |
rect.x:= 0; |
|
743 |
rect.y:= 0; |
|
744 |
rect.w:= textWidth + cornerWidth * 2; |
|
745 |
rect.h:= textHeight + cornerHeight * 2 - edgeHeight + SpritesData[tail].Height; |
|
746 |
//s:= inttostr(h) + ' ' + inttostr(numlines) + ' ' + inttostr(rect.x) + ' '+inttostr(rect.y) + ' ' + inttostr(rect.w) + ' ' + inttostr(rect.h) + ' ' + s; |
|
747 |
||
748 |
Result:= SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, 32, RMask, GMask, BMask, AMask); |
|
749 |
||
750 |
TryDo(Result <> nil, 'RenderString: fail to create surface', true); |
|
751 |
||
752 |
//////////////////////////////// CORNERS /////////////////////////////// |
|
753 |
copyToXY(SpritesData[corner].Surface, Result, 0, 0); /////////////////// NW |
|
754 |
||
755 |
flipSurface(SpritesData[corner].Surface, true); // store all 4 versions in memory to avoid repeated flips? |
|
756 |
x:= 0; |
|
757 |
y:= textHeight + cornerHeight -1; |
|
758 |
copyToXY(SpritesData[corner].Surface, Result, x, y); /////////////////// SW |
|
759 |
||
760 |
flipSurface(SpritesData[corner].Surface, false); |
|
761 |
x:= rect.w-cornerWidth-1; |
|
762 |
y:= textHeight + cornerHeight -1; |
|
763 |
copyToXY(SpritesData[corner].Surface, Result, x, y); /////////////////// SE |
|
764 |
||
765 |
flipSurface(SpritesData[corner].Surface, true); |
|
766 |
x:= rect.w-cornerWidth-1; |
|
767 |
y:= 0; |
|
768 |
copyToXY(SpritesData[corner].Surface, Result, x, y); /////////////////// NE |
|
769 |
flipSurface(SpritesData[corner].Surface, false); // restore original position |
|
770 |
//////////////////////////////// END CORNERS /////////////////////////////// |
|
771 |
||
772 |
//////////////////////////////// EDGES ////////////////////////////////////// |
|
773 |
x:= cornerWidth; |
|
774 |
y:= 0; |
|
775 |
while x < rect.w-cornerWidth-1 do |
|
776 |
begin |
|
777 |
copyToXY(SpritesData[edge].Surface, Result, x, y); ///////////////// top edge |
|
778 |
inc(x,edgeWidth); |
|
779 |
end; |
|
780 |
flipSurface(SpritesData[edge].Surface, true); |
|
781 |
x:= cornerWidth; |
|
782 |
y:= textHeight + cornerHeight*2 - edgeHeight-1; |
|
783 |
while x < rect.w-cornerWidth-1 do |
|
784 |
begin |
|
785 |
copyToXY(SpritesData[edge].Surface, Result, x, y); ///////////////// bottom edge |
|
786 |
inc(x,edgeWidth); |
|
787 |
end; |
|
788 |
flipSurface(SpritesData[edge].Surface, true); // restore original position |
|
789 |
||
790 |
rotatedEdge:= SDL_CreateRGBSurface(SDL_SWSURFACE, edgeHeight, edgeWidth, 32, RMask, GMask, BMask, AMask); |
|
791 |
x:= rect.w - edgeHeight - 1; |
|
792 |
y:= cornerHeight; |
|
793 |
//// initially was going to rotate in place, but the SDL spec claims width/height are read only |
|
794 |
copyRotatedSurface(SpritesData[edge].Surface,rotatedEdge); |
|
795 |
while y < textHeight + cornerHeight do |
|
796 |
begin |
|
797 |
copyToXY(rotatedEdge, Result, x, y); |
|
798 |
inc(y,edgeWidth); |
|
799 |
end; |
|
800 |
flipSurface(rotatedEdge, false); // restore original position |
|
801 |
x:= 0; |
|
802 |
y:= cornerHeight; |
|
803 |
while y < textHeight + cornerHeight do |
|
804 |
begin |
|
805 |
copyToXY(rotatedEdge, Result, x, y); |
|
806 |
inc(y,edgeWidth); |
|
807 |
end; |
|
808 |
//////////////////////////////// END EDGES ////////////////////////////////////// |
|
809 |
||
810 |
x:= cornerWidth; |
|
811 |
y:= textHeight + cornerHeight * 2 - edgeHeight - 1; |
|
812 |
copyToXY(SpritesData[tail].Surface, Result, x, y); |
|
813 |
||
814 |
rect.x:= edgeHeight; |
|
815 |
rect.y:= edgeHeight; |
|
816 |
rect.w:= rect.w - edgeHeight * 2; |
|
817 |
rect.h:= textHeight + cornerHeight * 2 - edgeHeight * 2; |
|
818 |
SDL_FillRect(Result, @rect, cWhiteColor); |
|
819 |
||
820 |
pos:= 1; prevpos:= 0; line:= 0; |
|
821 |
while pos <= length(s) do |
|
822 |
begin |
|
823 |
if (s[pos] = #1) or (pos = length(s)) then |
|
824 |
begin |
|
825 |
if s[pos] <> #1 then inc(pos); |
|
826 |
while s[prevpos+1] = ' 'do inc(prevpos); |
|
827 |
substr:= copy(s, prevpos+1, pos-prevpos-1); |
|
828 |
if Length(substr) <> 0 then |
|
829 |
begin |
|
830 |
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(substr), cColorNearBlack); |
|
831 |
rect.x:= edgeHeight; |
|
832 |
rect.y:= edgeHeight + line * h; |
|
833 |
SDLTry(tmpsurf <> nil, true); |
|
834 |
SDL_UpperBlit(tmpsurf, nil, Result, @rect); |
|
835 |
SDL_FreeSurface(tmpsurf); |
|
836 |
inc(line); |
|
837 |
prevpos:= pos; |
|
838 |
end; |
|
839 |
end; |
|
840 |
inc(pos); |
|
841 |
end; |
|
842 |
||
843 |
//TryDo(SDL_SetColorKey(Result, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
|
844 |
RenderSpeechBubbleTex:= Surface2Tex(Result); |
|
845 |
||
846 |
SDL_FreeSurface(rotatedEdge); |
|
847 |
SDL_FreeSurface(Result) |
|
848 |
end; |
|
849 |
||
4 | 850 |
procedure RenderHealth(var Hedgehog: THedgehog); |
95 | 851 |
var s: shortstring; |
4 | 852 |
begin |
351 | 853 |
str(Hedgehog.Gear^.Health, s); |
762 | 854 |
if Hedgehog.HealthTagTex <> nil then FreeTexture(Hedgehog.HealthTagTex); |
855 |
Hedgehog.HealthTagTex:= RenderStringTex(s, Hedgehog.Team^.Clan^.Color, fnt16) |
|
4 | 856 |
end; |
857 |
||
518 | 858 |
function LoadImage(const filename: string; hasAlpha: boolean; critical, setTransparent: boolean): PSDL_Surface; |
30 | 859 |
var tmpsurf: PSDL_Surface; |
753 | 860 |
//Result: PSDL_Surface; |
355 | 861 |
s: shortstring; |
4 | 862 |
begin |
863 |
WriteToConsole(msgLoading + filename + '... '); |
|
355 | 864 |
s:= filename + '.' + cBitsStr + '.png'; |
865 |
tmpsurf:= IMG_Load(Str2PChar(s)); |
|
351 | 866 |
|
74 | 867 |
if tmpsurf = nil then |
351 | 868 |
begin |
355 | 869 |
s:= filename + '.png'; |
870 |
tmpsurf:= IMG_Load(Str2PChar(s)); |
|
351 | 871 |
end; |
80 | 872 |
|
873 |
if tmpsurf = nil then |
|
874 |
if critical then OutError(msgFailed, true) |
|
875 |
else begin |
|
876 |
WriteLnToConsole(msgFailed); |
|
351 | 877 |
exit(nil) |
80 | 878 |
end; |
351 | 879 |
|
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset
|
880 |
if setTransparent then TryDo(SDL_SetColorKey(tmpsurf, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
753 | 881 |
//if hasAlpha then Result:= SDL_DisplayFormatAlpha(tmpsurf) |
882 |
// else Result:= SDL_DisplayFormat(tmpsurf); |
|
620 | 883 |
{$IFDEF DEBUGFILE}WriteLnToConsole('(' + inttostr(tmpsurf^.w) + ',' + inttostr(tmpsurf^.h) + ') ');{$ENDIF} |
351 | 884 |
WriteLnToConsole(msgOK); |
753 | 885 |
LoadImage:= tmpsurf//Result |
886 |
end; |
|
887 |
||
888 |
procedure SetupOpenGL; |
|
889 |
begin |
|
756 | 890 |
glLoadIdentity; |
753 | 891 |
glViewport(0, 0, cScreenWidth, cScreenHeight); |
754 | 892 |
glScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0); |
893 |
glTranslatef(-cScreenWidth / 2, -cScreenHeight / 2, 0); |
|
756 | 894 |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
753 | 895 |
glMatrixMode(GL_MODELVIEW) |
4 | 896 |
end; |
897 |
||
510 | 898 |
//////////////////////////////////////////////////////////////////////////////// |
766 | 899 |
var ProgrTex: PTexture = nil; |
534 | 900 |
Step: integer = 0; |
510 | 901 |
|
902 |
procedure AddProgress; |
|
903 |
var r: TSDL_Rect; |
|
766 | 904 |
texsurf: PSDL_Surface; |
510 | 905 |
begin |
906 |
if Step = 0 then |
|
907 |
begin |
|
908 |
WriteToConsole(msgLoading + 'progress sprite: '); |
|
766 | 909 |
texsurf:= LoadImage(Pathz[ptGraphics] + '/Progress', false, true, true); |
910 |
ProgrTex:= Surface2Tex(texsurf); |
|
911 |
SDL_FreeSurface(texsurf) |
|
510 | 912 |
end; |
1045 | 913 |
|
766 | 914 |
glClear(GL_COLOR_BUFFER_BIT); |
775 | 915 |
glEnable(GL_TEXTURE_2D); |
510 | 916 |
r.x:= 0; |
766 | 917 |
r.w:= ProgrTex^.w; |
918 |
r.h:= ProgrTex^.w; |
|
919 |
r.y:= (Step mod (ProgrTex^.h div ProgrTex^.w)) * ProgrTex^.w; |
|
920 |
DrawFromRect((cScreenWidth - ProgrTex^.w) div 2, |
|
841
0700e3d3474d
Get rid if deprecated Surface parameter of Draw* calls
unc0rr
parents:
840
diff
changeset
|
921 |
(cScreenHeight - ProgrTex^.w) div 2, @r, ProgrTex); |
775 | 922 |
glDisable(GL_TEXTURE_2D); |
766 | 923 |
SDL_GL_SwapBuffers(); |
510 | 924 |
inc(Step); |
925 |
end; |
|
926 |
||
927 |
procedure FinishProgress; |
|
928 |
begin |
|
929 |
WriteLnToConsole('Freeing progress surface... '); |
|
766 | 930 |
FreeTexture(ProgrTex) |
510 | 931 |
end; |
932 |
||
2017 | 933 |
procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); |
934 |
var y, x, i, j: LongInt; |
|
935 |
tmpPixel: Longword; |
|
936 |
pixels: PLongWordArray; |
|
937 |
begin |
|
938 |
TryDo(Surface^.format^.BytesPerPixel = 4, 'flipSurface failed, expecting 32 bit surface', true); |
|
939 |
pixels:= Surface^.pixels; |
|
940 |
if Vertical then |
|
941 |
for y := 0 to (Surface^.h div 2) - 1 do |
|
942 |
for x := 0 to Surface^.w - 1 do |
|
943 |
begin |
|
944 |
i:= y * Surface^.w + x; |
|
945 |
j:= (Surface^.h - y - 1) * Surface^.w + x; |
|
946 |
tmpPixel:= pixels^[i]; |
|
947 |
pixels^[i]:= pixels^[j]; |
|
948 |
pixels^[j]:= tmpPixel; |
|
949 |
end |
|
950 |
else |
|
951 |
for x := 0 to (Surface^.w div 2) - 1 do |
|
952 |
for y := 0 to Surface^.h -1 do |
|
953 |
begin |
|
954 |
i:= y*Surface^.w + x; |
|
955 |
j:= y*Surface^.w + (Surface^.w - x - 1); |
|
956 |
tmpPixel:= pixels^[i]; |
|
957 |
pixels^[i]:= pixels^[j]; |
|
958 |
pixels^[j]:= tmpPixel; |
|
959 |
end; |
|
960 |
end; |
|
961 |
||
962 |
procedure copyToXY(src, dest: PSDL_Surface; destX, destY: Integer); |
|
963 |
var srcX, srcY, i, j, maxDest: LongInt; |
|
964 |
srcPixels, destPixels: PLongWordArray; |
|
965 |
begin |
|
966 |
maxDest:= (dest^.pitch div 4) * dest^.h; |
|
967 |
srcPixels:= src^.pixels; |
|
968 |
destPixels:= dest^.pixels; |
|
969 |
||
970 |
for srcX:= 0 to src^.w - 1 do |
|
971 |
for srcY:= 0 to src^.h - 1 do |
|
972 |
begin |
|
973 |
i:= (destY + srcY) * (dest^.pitch div 4) + destX + srcX; |
|
974 |
j:= srcY * (src^.pitch div 4) + srcX; |
|
975 |
// basic skip of transparent pixels - cleverness would be to do true alpha |
|
976 |
if (i < maxDest) and ($FF000000 and srcPixels^[j] <> 0) then destPixels^[i]:= srcPixels^[j]; |
|
977 |
end; |
|
978 |
end; |
|
979 |
||
980 |
procedure copyRotatedSurface(src, dest: PSDL_Surface); // this is necessary since width/height are read only in SDL, apparently |
|
981 |
var y, x, i, j: LongInt; |
|
982 |
srcPixels, destPixels: PLongWordArray; |
|
983 |
begin |
|
984 |
TryDo(src^.format^.BytesPerPixel = 4, 'rotateSurface failed, expecting 32 bit surface', true); |
|
985 |
TryDo(dest^.format^.BytesPerPixel = 4, 'rotateSurface failed, expecting 32 bit surface', true); |
|
986 |
||
987 |
srcPixels:= src^.pixels; |
|
988 |
destPixels:= dest^.pixels; |
|
989 |
||
990 |
j:= 0; |
|
991 |
for x := 0 to src^.w - 1 do |
|
992 |
for y := 0 to src^.h - 1 do |
|
993 |
begin |
|
994 |
i:= (src^.h - 1 - y) * (src^.pitch div 4) + x; |
|
995 |
destPixels^[j]:= srcPixels^[i]; |
|
996 |
inc(j) |
|
997 |
end; |
|
998 |
end; |
|
999 |
||
4 | 1000 |
end. |