60 procedure DrawCentered(X, Top: LongInt; Source: PTexture); |
60 procedure DrawCentered(X, Top: LongInt; Source: PTexture); |
61 procedure DrawFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
61 procedure DrawFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
62 procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
62 procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
63 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
63 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
64 procedure DrawFillRect(r: TSDL_Rect); |
64 procedure DrawFillRect(r: TSDL_Rect); |
|
65 procedure DrawCircle(X, Y, Radius: LongInt; Width: Single; r, g, b, a: Byte); |
65 procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); |
66 procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); |
66 function CheckCJKFont(s: ansistring; font: THWFont): THWFont; |
67 function CheckCJKFont(s: ansistring; font: THWFont): THWFont; |
67 function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture; |
68 function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture; |
68 function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture; |
69 function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture; |
69 procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); |
70 procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); |
82 procedure FreeWeaponTooltip; |
83 procedure FreeWeaponTooltip; |
83 procedure Tint(r, g, b, a: Byte); inline; |
84 procedure Tint(r, g, b, a: Byte); inline; |
84 procedure Tint(c: Longword); inline; |
85 procedure Tint(c: Longword); inline; |
85 |
86 |
86 implementation |
87 implementation |
87 uses uMisc, uConsole, uLocale; |
88 uses uMisc, uConsole, uLocale, uMobile; |
88 |
89 |
89 type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple); |
90 type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple); |
90 |
91 |
91 var HHTexture: PTexture; |
92 var HHTexture: PTexture; |
92 MaxTextureSize: LongInt; |
93 MaxTextureSize: LongInt; |
235 |
236 |
236 r.w:= 26; |
237 r.w:= 26; |
237 r.h:= 19; |
238 r.h:= 19; |
238 |
239 |
239 DrawRoundRect(@r, cWhiteColor, cNearBlackColor, texsurf, true); |
240 DrawRoundRect(@r, cWhiteColor, cNearBlackColor, texsurf, true); |
240 |
241 |
241 // overwrite flag for cpu teams and keep players from using it |
242 // overwrite flag for cpu teams and keep players from using it |
242 if (Hedgehogs[0].Gear <> nil) and (Hedgehogs[0].BotLevel > 0) then |
243 if (Hedgehogs[0].Gear <> nil) and (Hedgehogs[0].BotLevel > 0) then |
243 Flag:= 'cpu' |
244 Flag:= 'cpu' |
244 else if Flag = 'cpu' then |
245 else if Flag = 'cpu' then |
245 Flag:= 'hedgewars'; |
246 Flag:= 'hedgewars'; |
246 |
247 |
247 flagsurf:= LoadImage(Pathz[ptFlags] + '/' + Flag, ifNone); |
248 flagsurf:= LoadImage(Pathz[ptFlags] + '/' + Flag, ifNone); |
248 if flagsurf = nil then |
249 if flagsurf = nil then |
249 flagsurf:= LoadImage(Pathz[ptFlags] + '/hedgewars', ifNone); |
250 flagsurf:= LoadImage(Pathz[ptFlags] + '/hedgewars', ifNone); |
250 TryDo(flagsurf <> nil, 'Failed to load flag "' + Flag + '" as well as the default flag', true); |
251 TryDo(flagsurf <> nil, 'Failed to load flag "' + Flag + '" as well as the default flag', true); |
251 copyToXY(flagsurf, texsurf, 2, 2); |
252 copyToXY(flagsurf, texsurf, 2, 2); |
252 SDL_FreeSurface(flagsurf); |
253 SDL_FreeSurface(flagsurf); |
253 flagsurf:= nil; |
254 flagsurf:= nil; |
254 |
255 |
255 // restore black border pixels inside the flag |
256 // restore black border pixels inside the flag |
256 PLongwordArray(texsurf^.pixels)^[32 * 2 + 2]:= cNearBlackColor; |
257 PLongwordArray(texsurf^.pixels)^[32 * 2 + 2]:= cNearBlackColor; |
257 PLongwordArray(texsurf^.pixels)^[32 * 2 + 23]:= cNearBlackColor; |
258 PLongwordArray(texsurf^.pixels)^[32 * 2 + 23]:= cNearBlackColor; |
258 PLongwordArray(texsurf^.pixels)^[32 * 16 + 2]:= cNearBlackColor; |
259 PLongwordArray(texsurf^.pixels)^[32 * 16 + 2]:= cNearBlackColor; |
259 PLongwordArray(texsurf^.pixels)^[32 * 16 + 23]:= cNearBlackColor; |
260 PLongwordArray(texsurf^.pixels)^[32 * 16 + 23]:= cNearBlackColor; |
260 |
261 |
261 FlagTex:= Surface2Tex(texsurf, false); |
262 FlagTex:= Surface2Tex(texsurf, false); |
262 SDL_FreeSurface(texsurf); |
263 SDL_FreeSurface(texsurf); |
|
264 |
|
265 AIKillsTex := RenderStringTex(inttostr(stats.AIKills), Clan^.Color, fnt16); |
263 |
266 |
264 dec(drY, r.h + 2); |
267 dec(drY, r.h + 2); |
265 DrawHealthY:= drY; |
268 DrawHealthY:= drY; |
266 for i:= 0 to 7 do |
269 for i:= 0 to 7 do |
267 with Hedgehogs[i] do |
270 with Hedgehogs[i] do |
272 begin |
275 begin |
273 if (Length(Hat) > 39) and (Copy(Hat,1,8) = 'Reserved') and (Copy(Hat,9,32) = PlayerHash) then |
276 if (Length(Hat) > 39) and (Copy(Hat,1,8) = 'Reserved') and (Copy(Hat,9,32) = PlayerHash) then |
274 texsurf:= LoadImage(Pathz[ptHats] + '/Reserved/' + Copy(Hat,9,Length(s)-8), ifNone) |
277 texsurf:= LoadImage(Pathz[ptHats] + '/Reserved/' + Copy(Hat,9,Length(s)-8), ifNone) |
275 else |
278 else |
276 texsurf:= LoadImage(Pathz[ptHats] + '/' + Hat, ifNone); |
279 texsurf:= LoadImage(Pathz[ptHats] + '/' + Hat, ifNone); |
277 if texsurf <> nil then |
280 if texsurf <> nil then |
278 begin |
281 begin |
279 HatTex:= Surface2Tex(texsurf, true); |
282 HatTex:= Surface2Tex(texsurf, true); |
280 SDL_FreeSurface(texsurf) |
283 SDL_FreeSurface(texsurf) |
281 end; |
284 end; |
282 texsurf:= nil; |
285 texsurf:= nil; |
283 end |
286 end |
284 end; |
287 end; |
285 end; |
288 end; |
286 MissionIcons:= LoadImage(Pathz[ptGraphics] + '/missions', ifCritical); |
289 MissionIcons:= LoadImage(Pathz[ptGraphics] + '/missions', ifCritical); |
287 iconsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, 28, 28, 32, RMask, GMask, BMask, AMask); |
290 iconsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, 28, 28, 32, RMask, GMask, BMask, AMask); |
288 if iconsurf <> nil then |
291 if iconsurf <> nil then |
289 begin |
292 begin |
290 r.x:= 0; |
293 r.x:= 0; |
291 r.y:= 0; |
294 r.y:= 0; |
292 r.w:= 28; |
295 r.w:= 28; |
293 r.h:= 28; |
296 r.h:= 28; |
294 DrawRoundRect(@r, cWhiteColor, cNearBlackColor, iconsurf, true); |
297 DrawRoundRect(@r, cWhiteColor, cNearBlackColor, iconsurf, true); |
295 ropeIconTex:= Surface2Tex(iconsurf, false); |
298 ropeIconTex:= Surface2Tex(iconsurf, false); |
296 SDL_FreeSurface(iconsurf); |
299 SDL_FreeSurface(iconsurf); |
297 iconsurf:= nil; |
300 iconsurf:= nil; |
298 end; |
301 end; |
299 end; |
302 end; |
300 |
303 |
301 procedure MakeCrossHairs; |
304 procedure MakeCrossHairs; |
302 var t: LongInt; |
305 var t: LongInt; |
323 if SDL_MustLock(texsurf) then |
326 if SDL_MustLock(texsurf) then |
324 SDLTry(SDL_LockSurface(texsurf) >= 0, true); |
327 SDLTry(SDL_LockSurface(texsurf) >= 0, true); |
325 |
328 |
326 // make black pixel be alpha-transparent |
329 // make black pixel be alpha-transparent |
327 for i:= 0 to texsurf^.w * texsurf^.h - 1 do |
330 for i:= 0 to texsurf^.w * texsurf^.h - 1 do |
328 if PLongwordArray(texsurf^.pixels)^[i] = AMask then PLongwordArray(texsurf^.pixels)^[i]:= 0; |
331 if PLongwordArray(texsurf^.pixels)^[i] = AMask then PLongwordArray(texsurf^.pixels)^[i]:= (RMask or GMask or BMask) and Color; |
329 |
332 |
330 if SDL_MustLock(texsurf) then |
333 if SDL_MustLock(texsurf) then |
331 SDL_UnlockSurface(texsurf); |
334 SDL_UnlockSurface(texsurf); |
332 |
335 |
333 CrosshairTex:= Surface2Tex(texsurf, false); |
336 CrosshairTex:= Surface2Tex(texsurf, false); |
356 begin |
359 begin |
357 for t:= 0 to Pred(TeamsCount) do |
360 for t:= 0 to Pred(TeamsCount) do |
358 if TeamsArray[t] <> nil then |
361 if TeamsArray[t] <> nil then |
359 with TeamsArray[t]^ do |
362 with TeamsArray[t]^ do |
360 begin |
363 begin |
361 if GraveName = '' then GraveName:= 'Simple'; |
364 if GraveName = '' then GraveName:= 'Statue'; |
362 texsurf:= LoadImage(Pathz[ptGraves] + '/' + GraveName, ifCritical or ifTransparent); |
365 texsurf:= LoadImage(Pathz[ptGraves] + '/' + GraveName, ifTransparent); |
|
366 if texsurf = nil then texsurf:= LoadImage(Pathz[ptGraves] + '/Statue', ifCritical or ifTransparent); |
363 GraveTex:= Surface2Tex(texsurf, false); |
367 GraveTex:= Surface2Tex(texsurf, false); |
364 SDL_FreeSurface(texsurf) |
368 SDL_FreeSurface(texsurf) |
365 end |
369 end |
366 end; |
370 end; |
367 |
371 |
405 end; |
409 end; |
406 |
410 |
407 if tmpsurf <> nil then |
411 if tmpsurf <> nil then |
408 begin |
412 begin |
409 if getImageDimensions then |
413 if getImageDimensions then |
410 begin |
414 begin |
411 imageWidth:= tmpsurf^.w; |
415 imageWidth:= tmpsurf^.w; |
412 imageHeight:= tmpsurf^.h |
416 imageHeight:= tmpsurf^.h |
413 end; |
417 end; |
414 if getDimensions then |
418 if getDimensions then |
415 begin |
419 begin |
416 Width:= tmpsurf^.w; |
420 Width:= tmpsurf^.w; |
417 Height:= tmpsurf^.h |
421 Height:= tmpsurf^.h |
418 end; |
422 end; |
419 if (ii in [sprSky, sprSkyL, sprSkyR, sprHorizont, sprHorizontL, sprHorizontR]) then |
423 if (ii in [sprSky, sprSkyL, sprSkyR, sprHorizont, sprHorizontL, sprHorizontR]) then |
420 begin |
424 begin |
421 Texture:= Surface2Tex(tmpsurf, true); |
425 Texture:= Surface2Tex(tmpsurf, true); |
422 Texture^.Scale:= 2 |
426 Texture^.Scale:= 2 |
423 end |
427 end |
424 else |
428 else |
425 begin |
429 begin |
426 Texture:= Surface2Tex(tmpsurf, false); |
430 Texture:= Surface2Tex(tmpsurf, false); |
427 if (ii = sprWater) and ((cReducedQuality and (rq2DWater or rqClampLess)) = 0) then // HACK: We should include some sprite attribute to define the texture wrap directions |
431 if (ii = sprWater) and ((cReducedQuality and (rq2DWater or rqClampLess)) = 0) then // HACK: We should include some sprite attribute to define the texture wrap directions |
428 begin |
|
429 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
432 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
430 end; |
|
431 end; |
433 end; |
432 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, priority); |
434 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, priority); |
433 if saveSurf then Surface:= tmpsurf else SDL_FreeSurface(tmpsurf) |
435 if saveSurf then |
|
436 Surface:= tmpsurf else SDL_FreeSurface(tmpsurf) |
434 end |
437 end |
435 else |
438 else |
436 Surface:= nil |
439 Surface:= nil |
437 end; |
440 end; |
438 |
441 |
442 HHTexture:= Surface2Tex(tmpsurf, false); |
445 HHTexture:= Surface2Tex(tmpsurf, false); |
443 SDL_FreeSurface(tmpsurf); |
446 SDL_FreeSurface(tmpsurf); |
444 |
447 |
445 InitHealth; |
448 InitHealth; |
446 |
449 |
|
450 // TODO: are those textures ever freed? |
447 PauseTexture:= RenderStringTex(trmsg[sidPaused], cYellowColor, fntBig); |
451 PauseTexture:= RenderStringTex(trmsg[sidPaused], cYellowColor, fntBig); |
448 ConfirmTexture:= RenderStringTex(trmsg[sidConfirm], cYellowColor, fntBig); |
452 ConfirmTexture:= RenderStringTex(trmsg[sidConfirm], cYellowColor, fntBig); |
449 SyncTexture:= RenderStringTex(trmsg[sidSync], cYellowColor, fntBig); |
453 SyncTexture:= RenderStringTex(trmsg[sidSync], cYellowColor, fntBig); |
450 |
454 |
451 AddProgress; |
455 AddProgress; |
452 |
456 |
453 // name of weapons in ammo menu |
457 // name of weapons in ammo menu |
454 for ai:= Low(TAmmoType) to High(TAmmoType) do |
458 for ai:= Low(TAmmoType) to High(TAmmoType) do |
455 with Ammoz[ai] do |
459 with Ammoz[ai] do |
456 begin |
460 begin |
457 TryDo(trAmmo[NameId] <> '','No default text/translation found for ammo type #' + intToStr(ord(ai)) + '!',true); |
461 TryDo(trAmmo[NameId] <> '','No default text/translation found for ammo type #' + intToStr(ord(ai)) + '!',true); |
458 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(trAmmo[NameId],fnt16)].Handle, Str2PChar(trAmmo[NameId]), cWhiteColorChannels); |
462 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(trAmmo[NameId],fnt16)].Handle, Str2PChar(trAmmo[NameId]), cWhiteColorChannels); |
459 TryDo(tmpsurf <> nil,'Name-texture creation for ammo type #' + intToStr(ord(ai)) + ' failed!',true); |
463 TryDo(tmpsurf <> nil,'Name-texture creation for ammo type #' + intToStr(ord(ai)) + ' failed!',true); |
460 tmpsurf:= doSurfaceConversion(tmpsurf); |
464 tmpsurf:= doSurfaceConversion(tmpsurf); |
461 NameTex:= Surface2Tex(tmpsurf, false); |
465 NameTex:= Surface2Tex(tmpsurf, false); |
462 SDL_FreeSurface(tmpsurf) |
466 SDL_FreeSurface(tmpsurf) |
463 end; |
467 end; |
464 |
468 |
465 // number of weapons in ammo menu |
469 // number of weapons in ammo menu |
466 for i:= Low(CountTexz) to High(CountTexz) do |
470 for i:= Low(CountTexz) to High(CountTexz) do |
467 begin |
471 begin |
468 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i) + 'x'), cWhiteColorChannels); |
472 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i) + 'x'), cWhiteColorChannels); |
469 tmpsurf:= doSurfaceConversion(tmpsurf); |
473 tmpsurf:= doSurfaceConversion(tmpsurf); |
470 CountTexz[i]:= Surface2Tex(tmpsurf, false); |
474 CountTexz[i]:= Surface2Tex(tmpsurf, false); |
471 SDL_FreeSurface(tmpsurf) |
475 SDL_FreeSurface(tmpsurf) |
472 end; |
476 end; |
473 |
477 |
474 {$IFDEF DUMP} |
|
475 //not working anymore, where are LandSurface and StoreSurface defined? |
|
476 //SDL_SaveBMP_RW(LandSurface, SDL_RWFromFile('LandSurface.bmp', 'wb'), 1); |
|
477 //SDL_SaveBMP_RW(StoreSurface, SDL_RWFromFile('StoreSurface.bmp', 'wb'), 1); |
|
478 {$ENDIF} |
|
479 AddProgress; |
478 AddProgress; |
480 |
479 |
481 {$IFDEF SDL_IMAGE_NEWER} |
480 {$IFDEF SDL_IMAGE_NEWER} |
482 IMG_Quit(); |
481 IMG_Quit(); |
483 {$ENDIF} |
482 {$ENDIF} |
492 var rr: TSDL_Rect; |
491 var rr: TSDL_Rect; |
493 _l, _r, _t, _b: real; |
492 _l, _r, _t, _b: real; |
494 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
493 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
495 begin |
494 begin |
496 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then exit; |
495 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then exit; |
|
496 |
|
497 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
498 if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then |
|
499 exit; |
|
500 if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then |
|
501 exit; |
|
502 |
497 rr.x:= X; |
503 rr.x:= X; |
498 rr.y:= Y; |
504 rr.y:= Y; |
499 rr.w:= W; |
505 rr.w:= W; |
500 rr.h:= H; |
506 rr.h:= H; |
501 |
507 |
530 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
536 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
531 end; |
537 end; |
532 |
538 |
533 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat); |
539 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat); |
534 begin |
540 begin |
|
541 |
535 glPushMatrix; |
542 glPushMatrix; |
536 glTranslatef(X, Y, 0); |
543 glTranslatef(X, Y, 0); |
537 glScalef(Scale, Scale, 1); |
544 glScalef(Scale, Scale, 1); |
538 |
545 |
539 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
546 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
553 procedure DrawRotatedTextureF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
560 procedure DrawRotatedTextureF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
554 var ft, fb, fl, fr: GLfloat; |
561 var ft, fb, fl, fr: GLfloat; |
555 hw, nx, ny: LongInt; |
562 hw, nx, ny: LongInt; |
556 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
563 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
557 begin |
564 begin |
|
565 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
566 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then |
|
567 exit; |
|
568 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then |
|
569 exit; |
|
570 |
558 glPushMatrix; |
571 glPushMatrix; |
559 glTranslatef(X, Y, 0); |
572 glTranslatef(X, Y, 0); |
560 |
573 |
561 if Dir < 0 then |
574 if Dir < 0 then |
562 glRotatef(Angle, 0, 0, -1) |
575 glRotatef(Angle, 0, 0, -1) |
634 end; |
647 end; |
635 |
648 |
636 procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
649 procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
637 var VertexBuffer: array [0..3] of TVertex2f; |
650 var VertexBuffer: array [0..3] of TVertex2f; |
638 begin |
651 begin |
|
652 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
653 if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then |
|
654 exit; |
|
655 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then |
|
656 exit; |
|
657 |
639 glPushMatrix; |
658 glPushMatrix; |
640 glTranslatef(X, Y, 0); |
659 glTranslatef(X, Y, 0); |
641 |
660 |
642 if Dir < 0 then |
661 if Dir < 0 then |
643 begin |
662 begin |
714 r.h:= SpritesData[Sprite].Height; |
733 r.h:= SpritesData[Sprite].Height; |
715 DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
734 DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
716 end; |
735 end; |
717 |
736 |
718 procedure DrawCentered(X, Top: LongInt; Source: PTexture); |
737 procedure DrawCentered(X, Top: LongInt; Source: PTexture); |
719 begin |
738 var scale: GLfloat; |
720 DrawTexture(X - Source^.w shr 1, Top, Source) |
739 begin |
|
740 if (Source^.w + 20) > cScreenWidth then |
|
741 scale:= cScreenWidth / (Source^.w + 20) |
|
742 else |
|
743 scale:= 1.0; |
|
744 DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale) |
721 end; |
745 end; |
722 |
746 |
723 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
747 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
724 const VertexBuffer: array [0..3] of TVertex2f = ( |
748 const VertexBuffer: array [0..3] of TVertex2f = ( |
725 (x: -16; y: -16), |
749 (x: -16; y: -16), |
727 (x: 16; y: 16), |
751 (x: 16; y: 16), |
728 (x: -16; y: 16)); |
752 (x: -16; y: 16)); |
729 var l, r, t, b: real; |
753 var l, r, t, b: real; |
730 TextureBuffer: array [0..3] of TVertex2f; |
754 TextureBuffer: array [0..3] of TVertex2f; |
731 begin |
755 begin |
|
756 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
757 if (abs(X) > 32) and ((abs(X) - 16) * cScaleFactor > cScreenWidth) then |
|
758 exit; |
|
759 if (abs(Y) > 32) and ((abs(Y - 0.5 * cScreenHeight) - 16) * cScaleFactor > cScreenHeight) then |
|
760 exit; |
732 |
761 |
733 t:= Pos * 32 / HHTexture^.h; |
762 t:= Pos * 32 / HHTexture^.h; |
734 b:= (Pos + 1) * 32 / HHTexture^.h; |
763 b:= (Pos + 1) * 32 / HHTexture^.h; |
735 |
764 |
736 if Dir = -1 then |
765 if Dir = -1 then |
767 end; |
796 end; |
768 |
797 |
769 procedure DrawFillRect(r: TSDL_Rect); |
798 procedure DrawFillRect(r: TSDL_Rect); |
770 var VertexBuffer: array [0..3] of TVertex2f; |
799 var VertexBuffer: array [0..3] of TVertex2f; |
771 begin |
800 begin |
|
801 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
802 if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then |
|
803 exit; |
|
804 if (abs(r.y) > r.h) and ((abs(r.y + r.h / 2 - (0.5 * cScreenHeight)) - r.h / 2) * cScaleFactor > cScreenHeight) then |
|
805 exit; |
|
806 |
772 glDisable(GL_TEXTURE_2D); |
807 glDisable(GL_TEXTURE_2D); |
773 |
808 |
774 Tint($00, $00, $00, $80); |
809 Tint($00, $00, $00, $80); |
775 |
810 |
776 VertexBuffer[0].X:= r.x; |
811 VertexBuffer[0].X:= r.x; |
787 |
822 |
788 Tint($FF, $FF, $FF, $FF); |
823 Tint($FF, $FF, $FF, $FF); |
789 glEnable(GL_TEXTURE_2D) |
824 glEnable(GL_TEXTURE_2D) |
790 end; |
825 end; |
791 |
826 |
|
827 procedure DrawCircle(X, Y, Radius: LongInt; Width: Single; r, g, b, a: Byte); |
|
828 var |
|
829 i: LongInt; |
|
830 CircleVertex: array [0..359] of TVertex2f; |
|
831 begin |
|
832 for i := 0 to 359 do begin |
|
833 CircleVertex[i].X := X + Radius*cos(i*pi/180); |
|
834 CircleVertex[i].Y := Y + Radius*sin(i*pi/180); |
|
835 end; |
|
836 glDisable(GL_TEXTURE_2D); |
|
837 glEnable(GL_LINE_SMOOTH); |
|
838 glPushMatrix; |
|
839 glTranslatef(WorldDx, WorldDy, 0); |
|
840 glLineWidth(Width); |
|
841 Tint(r, g, b, a); |
|
842 glVertexPointer(2, GL_FLOAT, 0, @CircleVertex[0]); |
|
843 glDrawArrays(GL_LINE_LOOP, 0, 360); |
|
844 Tint($FF, $FF, $FF, $FF); |
|
845 glPopMatrix; |
|
846 glEnable(GL_TEXTURE_2D); |
|
847 glDisable(GL_LINE_SMOOTH); |
|
848 end; |
|
849 |
792 procedure StoreRelease; |
850 procedure StoreRelease; |
793 var ii: TSprite; |
851 var ii: TSprite; |
794 begin |
852 begin |
795 for ii:= Low(TSprite) to High(TSprite) do |
853 for ii:= Low(TSprite) to High(TSprite) do |
796 begin |
854 begin |
1062 |
1125 |
1063 function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface; |
1126 function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface; |
1064 var tmpsurf: PSDL_Surface; |
1127 var tmpsurf: PSDL_Surface; |
1065 s: shortstring; |
1128 s: shortstring; |
1066 begin |
1129 begin |
1067 WriteToConsole(msgLoading + filename + '.png (flags: ' + inttostr(imageFlags)+') '); |
1130 WriteToConsole(msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + ']'); |
1068 {$IFDEF DEBUGFILE} |
|
1069 WriteToConsole('[flag translation:'); |
|
1070 if imageFlags = ifNone then |
|
1071 WriteToConsole(' None') |
|
1072 else |
|
1073 begin |
|
1074 if (imageFlags and ifAlpha) <> 0 then WriteToConsole(' Alpha'); |
|
1075 if (imageFlags and ifCritical) <> 0 then WriteToConsole(' Critical'); |
|
1076 if (imageFlags and ifTransparent) <> 0 then WriteToConsole(' Transparent'); |
|
1077 if (imageFlags and ifIgnoreCaps) <> 0 then WriteToConsole(' IgnoreCaps'); |
|
1078 end; |
|
1079 WriteToConsole('] '); |
|
1080 {$ENDIF} |
|
1081 |
1131 |
1082 s:= filename + '.png'; |
1132 s:= filename + '.png'; |
1083 tmpsurf:= IMG_Load(Str2PChar(s)); |
1133 tmpsurf:= IMG_Load(Str2PChar(s)); |
1084 |
1134 |
1085 if tmpsurf = nil then |
1135 if tmpsurf = nil then |
1091 if ((imageFlags and ifIgnoreCaps) = 0) and ((tmpsurf^.w > MaxTextureSize) or (tmpsurf^.h > MaxTextureSize)) then |
1141 if ((imageFlags and ifIgnoreCaps) = 0) and ((tmpsurf^.w > MaxTextureSize) or (tmpsurf^.h > MaxTextureSize)) then |
1092 begin |
1142 begin |
1093 SDL_FreeSurface(tmpsurf); |
1143 SDL_FreeSurface(tmpsurf); |
1094 OutError(msgFailedSize, (imageFlags and ifCritical) <> 0); |
1144 OutError(msgFailedSize, (imageFlags and ifCritical) <> 0); |
1095 // dummy surface to replace non-critical textures that failed to load due to their size |
1145 // dummy surface to replace non-critical textures that failed to load due to their size |
1096 exit(SDL_CreateRGBSurface(SDL_SWSURFACE, 32, 32, 32, RMask, GMask, BMask, AMask)); |
1146 exit(SDL_CreateRGBSurface(SDL_SWSURFACE, 2, 2, 32, RMask, GMask, BMask, AMask)); |
1097 end; |
1147 end; |
1098 |
1148 |
1099 tmpsurf:= doSurfaceConversion(tmpsurf); |
1149 tmpsurf:= doSurfaceConversion(tmpsurf); |
1100 |
1150 |
1101 if (imageFlags and ifTransparent) <> 0 then |
1151 if (imageFlags and ifTransparent) <> 0 then |
1123 {$ENDIF} |
1174 {$ENDIF} |
1124 {$ENDIF} |
1175 {$ENDIF} |
1125 end; |
1176 end; |
1126 |
1177 |
1127 procedure SetupOpenGL; |
1178 procedure SetupOpenGL; |
|
1179 {$IFNDEF IPHONEOS} |
1128 var vendor: shortstring; |
1180 var vendor: shortstring; |
1129 {$IFDEF DARWIN} |
1181 {$IFDEF DARWIN} |
1130 one: LongInt; |
1182 one: LongInt; |
1131 {$ENDIF} |
1183 {$ENDIF} |
1132 begin |
1184 {$ENDIF} |
1133 // initialized here because when initModule is called cScreenWidth/Height are not yet set |
1185 begin |
1134 if (uStore.wScreen = 0) and (uStore.hScreen = 0) then |
|
1135 begin |
|
1136 uStore.wScreen:= cScreenWidth; |
|
1137 uStore.hScreen:= cScreenHeight; |
|
1138 end; |
|
1139 |
1186 |
1140 {$IFDEF IPHONEOS} |
1187 {$IFDEF IPHONEOS} |
1141 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); // no double buffering |
1188 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); // no double buffering |
1142 SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1); |
1189 SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1); |
1143 {$ELSE} |
1190 {$ELSE} |
1144 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
1191 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
|
1192 vendor:= LowerCase(shortstring(pchar(glGetString(GL_VENDOR)))); |
1145 {$IFNDEF SDL13} |
1193 {$IFNDEF SDL13} |
1146 // this attribute is default in 1.3 and must be enabled in MacOSX |
1194 // this attribute is default in 1.3 and must be enabled in MacOSX |
1147 if (cReducedQuality and rqDesyncVBlank) <> 0 then |
1195 if (cReducedQuality and rqDesyncVBlank) <> 0 then |
1148 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0) |
1196 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0) |
1149 else |
1197 else |
1163 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16); // buffer has to be 16 bit only |
1211 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16); // buffer has to be 16 bit only |
1164 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // try to prefer hardware rendering |
1212 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // try to prefer hardware rendering |
1165 |
1213 |
1166 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); |
1214 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); |
1167 |
1215 |
1168 vendor:= LowerCase(shortstring(pchar(glGetString(GL_VENDOR)))); |
|
1169 {$IFDEF DEBUGFILE} |
1216 {$IFDEF DEBUGFILE} |
1170 AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER)))); |
1217 AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER)))); |
1171 AddFileLog(' |----- Vendor: ' + vendor); |
1218 AddFileLog(' |----- Vendor: ' + shortstring(pchar(glGetString(GL_VENDOR)))); |
1172 AddFileLog(' |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION)))); |
1219 AddFileLog(' |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION)))); |
1173 AddFileLog(' \----- GL_MAX_TEXTURE_SIZE: ' + inttostr(MaxTextureSize)); |
1220 AddFileLog(' \----- GL_MAX_TEXTURE_SIZE: ' + inttostr(MaxTextureSize)); |
1174 {$ENDIF} |
1221 {$ENDIF} |
1175 |
1222 |
1176 if MaxTextureSize <= 0 then |
1223 if MaxTextureSize <= 0 then |
1237 // just avoid 'never used' compiler warning for now |
1284 // just avoid 'never used' compiler warning for now |
1238 if cGPUVendor = gvUnknown then cGPUVendor:= gvUnknown; |
1285 if cGPUVendor = gvUnknown then cGPUVendor:= gvUnknown; |
1239 {$ENDIF} |
1286 {$ENDIF} |
1240 |
1287 |
1241 // set view port to whole window |
1288 // set view port to whole window |
1242 {$IFDEF IPHONEOS} |
1289 if (rotationQt = 0) or (rotationQt = 180) then |
1243 glViewport(0, 0, cScreenHeight, cScreenWidth); |
1290 glViewport(0, 0, cScreenWidth, cScreenHeight) |
1244 {$ELSE} |
1291 else |
1245 glViewport(0, 0, cScreenWidth, cScreenHeight); |
1292 glViewport(0, 0, cScreenHeight, cScreenWidth); |
1246 {$ENDIF} |
|
1247 |
1293 |
1248 glMatrixMode(GL_MODELVIEW); |
1294 glMatrixMode(GL_MODELVIEW); |
1249 // prepare default translation/scaling |
1295 // prepare default translation/scaling |
1250 glLoadIdentity(); |
1296 glLoadIdentity(); |
1251 glRotatef(rotationQt, 0, 0, 1); |
1297 glRotatef(rotationQt, 0, 0, 1); |
1259 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); |
1305 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); |
1260 // disable dithering |
1306 // disable dithering |
1261 glDisable(GL_DITHER); |
1307 glDisable(GL_DITHER); |
1262 // enable common states by default as they save a lot |
1308 // enable common states by default as they save a lot |
1263 glEnable(GL_TEXTURE_2D); |
1309 glEnable(GL_TEXTURE_2D); |
1264 glEnableClientState(GL_VERTEX_ARRAY); |
1310 glEnableClientState(GL_VERTEX_ARRAY); |
1265 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
1311 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
1266 end; |
1312 end; |
1267 |
1313 |
1268 procedure SetScale(f: GLfloat); |
1314 procedure SetScale(f: GLfloat); |
1269 begin |
1315 begin |
1270 // leave immediately if scale factor did not change |
1316 // leave immediately if scale factor did not change |
1275 else // other scaling |
1321 else // other scaling |
1276 begin |
1322 begin |
1277 glPushMatrix; // save default scaling |
1323 glPushMatrix; // save default scaling |
1278 glLoadIdentity; |
1324 glLoadIdentity; |
1279 glRotatef(rotationQt, 0, 0, 1); |
1325 glRotatef(rotationQt, 0, 0, 1); |
1280 glScalef(f / wScreen, -f / hScreen, 1.0); |
1326 glScalef(f / cScreenWidth, -f / cScreenHeight, 1.0); |
1281 glTranslatef(0, -cScreenHeight / 2, 0); |
1327 glTranslatef(0, -cScreenHeight / 2, 0); |
1282 end; |
1328 end; |
1283 |
1329 |
1284 cScaleFactor:= f; |
1330 cScaleFactor:= f; |
1285 end; |
1331 end; |
1293 begin |
1339 begin |
1294 WriteToConsole(msgLoading + 'progress sprite: '); |
1340 WriteToConsole(msgLoading + 'progress sprite: '); |
1295 texsurf:= LoadImage(Pathz[ptGraphics] + '/Progress', ifCritical or ifTransparent); |
1341 texsurf:= LoadImage(Pathz[ptGraphics] + '/Progress', ifCritical or ifTransparent); |
1296 |
1342 |
1297 ProgrTex:= Surface2Tex(texsurf, false); |
1343 ProgrTex:= Surface2Tex(texsurf, false); |
1298 |
1344 |
1299 squaresize:= texsurf^.w shr 1; |
1345 squaresize:= texsurf^.w shr 1; |
1300 numsquares:= texsurf^.h div squaresize; |
1346 numsquares:= texsurf^.h div squaresize; |
1301 SDL_FreeSurface(texsurf); |
1347 SDL_FreeSurface(texsurf); |
1302 {$IFDEF IPHONEOS} |
1348 |
1303 startSpinning(); |
1349 perfExt_AddProgress(); |
1304 {$ENDIF} |
|
1305 end; |
1350 end; |
1306 |
1351 |
1307 TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true); |
1352 TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true); |
1308 |
1353 |
1309 glClear(GL_COLOR_BUFFER_BIT); |
1354 glClear(GL_COLOR_BUFFER_BIT); |
1310 if Step < numsquares then r.x:= 0 |
1355 if Step < numsquares then r.x:= 0 |
1311 else r.x:= squaresize; |
1356 else r.x:= squaresize; |
1312 |
1357 |
1313 r.y:= (Step mod numsquares) * squaresize; |
1358 r.y:= (Step mod numsquares) * squaresize; |
1314 r.w:= squaresize; |
1359 r.w:= squaresize; |
1315 r.h:= squaresize; |
1360 r.h:= squaresize; |
1316 |
1361 |
1317 DrawFromRect( -squaresize div 2, (hScreen - squaresize) shr 1, @r, ProgrTex); |
1362 DrawFromRect( -squaresize div 2, (cScreenHeight - squaresize) shr 1, @r, ProgrTex); |
1318 |
1363 |
1319 SDL_GL_SwapBuffers(); |
1364 SDL_GL_SwapBuffers(); |
1320 {$IFDEF SDL13} |
1365 {$IFDEF SDL13} |
1321 SDL_RenderPresent(); |
1366 SDL_RenderPresent(); |
1322 {$ENDIF} |
1367 {$ENDIF} |
1466 // get extra label's dimensions |
1509 // get extra label's dimensions |
1467 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(extra), i, j); |
1510 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(extra), i, j); |
1468 if w < (i + wa) then w:= i + wa; |
1511 if w < (i + wa) then w:= i + wa; |
1469 inc(h, j + ha); |
1512 inc(h, j + ha); |
1470 end; |
1513 end; |
1471 |
1514 |
1472 // add borders space |
1515 // add borders space |
1473 inc(w, wa); |
1516 inc(w, wa); |
1474 inc(h, ha + 8); |
1517 inc(h, ha + 8); |
1475 |
1518 |
1476 tmpsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask); |
1519 tmpsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask); |
1496 SplitByChar(tmpline, tmpdesc, '|'); |
1539 SplitByChar(tmpline, tmpdesc, '|'); |
1497 r2:= r; |
1540 r2:= r; |
1498 if tmpline <> '' then |
1541 if tmpline <> '' then |
1499 begin |
1542 begin |
1500 r:= WriteInRect(tmpsurf, FontBorder + 2, r.y + r.h, $ff707070, font, tmpline); |
1543 r:= WriteInRect(tmpsurf, FontBorder + 2, r.y + r.h, $ff707070, font, tmpline); |
1501 |
1544 |
1502 // render highlighted caption (if there's a ':') |
1545 // render highlighted caption (if there's a ':') |
1503 tmpline2:= ''; |
1546 tmpline2:= ''; |
1504 SplitByChar(tmpline, tmpline2, ':'); |
1547 SplitByChar(tmpline, tmpline2, ':'); |
1505 if tmpline2 <> '' then |
1548 if tmpline2 <> '' then |
1506 WriteInRect(tmpsurf, FontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, tmpline + ':'); |
1549 WriteInRect(tmpsurf, FontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, tmpline + ':'); |
1514 r.y:= FontBorder + 4; |
1557 r.y:= FontBorder + 4; |
1515 r.w:= 32; |
1558 r.w:= 32; |
1516 r.h:= 32; |
1559 r.h:= 32; |
1517 SDL_FillRect(tmpsurf, @r, $ffffffff); |
1560 SDL_FillRect(tmpsurf, @r, $ffffffff); |
1518 SDL_UpperBlit(iconsurf, iconrect, tmpsurf, @r); |
1561 SDL_UpperBlit(iconsurf, iconrect, tmpsurf, @r); |
1519 |
1562 |
1520 RenderHelpWindow:= Surface2Tex(tmpsurf, true); |
1563 RenderHelpWindow:= Surface2Tex(tmpsurf, true); |
1521 SDL_FreeSurface(tmpsurf) |
1564 SDL_FreeSurface(tmpsurf) |
1522 end; |
1565 end; |
1523 |
1566 |
1524 procedure RenderWeaponTooltip(atype: TAmmoType); |
1567 procedure RenderWeaponTooltip(atype: TAmmoType); |