18 |
18 |
19 {$INCLUDE "options.inc"} |
19 {$INCLUDE "options.inc"} |
20 |
20 |
21 unit uStore; |
21 unit uStore; |
22 interface |
22 interface |
23 uses sysutils, uConsts, uTeams, SDLh, GLunit, uWorld; |
23 uses sysutils, uConsts, SDLh, GLunit, uTypes; |
24 |
|
25 |
|
26 var PixelFormat: PSDL_PixelFormat; |
|
27 SDLPrimSurface: PSDL_Surface; |
|
28 PauseTexture, |
|
29 SyncTexture, |
|
30 ConfirmTexture: PTexture; |
|
31 cScaleFactor: GLfloat; |
|
32 SupportNPOTT: Boolean; |
|
33 Step: LongInt; |
|
34 squaresize : LongInt; |
|
35 numsquares : LongInt; |
|
36 ProgrTex: PTexture; |
|
37 MissionIcons: PSDL_Surface; |
|
38 ropeIconTex: PTexture; |
|
39 rotationQt: GLfloat; |
|
40 wScreen: LongInt; |
|
41 hScreen: LongInt; |
|
42 framel, framer, depthl, depthr: GLuint; |
|
43 texl, texr: GLuint; |
|
44 |
24 |
45 procedure initModule; |
25 procedure initModule; |
46 procedure freeModule; |
26 procedure freeModule; |
47 |
27 |
48 procedure StoreLoad; |
28 procedure StoreLoad; |
49 procedure StoreRelease; |
29 procedure StoreRelease; |
50 procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
|
51 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
|
52 procedure DrawSprite2(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
|
53 procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
|
54 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat = 1.0); |
|
55 procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt); |
|
56 procedure DrawRotatedTextureF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
|
57 procedure DrawRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); |
|
58 procedure DrawRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); |
|
59 procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
|
60 procedure DrawCentered(X, Top: LongInt; Source: 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); |
|
63 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
|
64 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
|
65 procedure DrawFillRect(r: TSDL_Rect); |
|
66 procedure DrawCircle(X, Y, Radius: LongInt; Width: Single; r, g, b, a: Byte); |
|
67 procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); |
|
68 function CheckCJKFont(s: ansistring; font: THWFont): THWFont; |
|
69 function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture; |
|
70 function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture; |
|
71 procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); |
|
72 //procedure rotateSurface(Surface: PSDL_Surface); |
|
73 procedure copyRotatedSurface(src, dest: PSDL_Surface); // this is necessary since width/height are read only in SDL |
|
74 procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); |
|
75 procedure RenderHealth(var Hedgehog: THedgehog); |
30 procedure RenderHealth(var Hedgehog: THedgehog); |
76 procedure AddProgress; |
31 procedure AddProgress; |
77 procedure FinishProgress; |
32 procedure FinishProgress; |
78 function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface; |
33 function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface; |
79 procedure SetupOpenGL; |
34 procedure SetupOpenGL; |
80 procedure SetScale(f: GLfloat); |
35 procedure SetScale(f: GLfloat); |
81 function RenderHelpWindow(caption, subcaption, description, extra: ansistring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture; |
36 function RenderHelpWindow(caption, subcaption, description, extra: ansistring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture; |
82 procedure RenderWeaponTooltip(atype: TAmmoType); |
37 procedure RenderWeaponTooltip(atype: TAmmoType); |
83 procedure ShowWeaponTooltip(x, y: LongInt); |
38 procedure ShowWeaponTooltip(x, y: LongInt); |
84 procedure FreeWeaponTooltip; |
39 procedure FreeWeaponTooltip; |
85 procedure Tint(r, g, b, a: Byte); inline; |
|
86 procedure Tint(c: Longword); inline; |
|
87 |
40 |
88 implementation |
41 implementation |
89 uses uMisc, uConsole, uLocale, uMobile; |
42 uses uMisc, uConsole, uMobile, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands, uDebug; |
90 |
43 |
91 type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple); |
44 type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple); |
92 |
45 |
93 var HHTexture: PTexture; |
46 var MaxTextureSize: LongInt; |
94 MaxTextureSize: LongInt; |
|
95 cGPUVendor: TGPUVendor; |
47 cGPUVendor: TGPUVendor; |
96 lastTint: Longword; |
|
97 |
|
98 procedure Tint(r, g, b, a: Byte); inline; |
|
99 var nc: Longword; |
|
100 begin |
|
101 nc:= (a shl 24) or (b shl 16) or (g shl 8) or r; |
|
102 if nc = lastTint then |
|
103 exit; |
|
104 glColor4ub(r, g, b, a); |
|
105 lastTint:= nc; |
|
106 end; |
|
107 |
|
108 procedure Tint(c: Longword); inline; |
|
109 begin |
|
110 Tint(((c shr 16) and $FF), ((c shr 8) and $FF), (c and $FF), $FF); |
|
111 end; |
|
112 |
|
113 procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); |
|
114 var r: TSDL_Rect; |
|
115 begin |
|
116 r:= rect^; |
|
117 if Clear then SDL_FillRect(Surface, @r, 0); |
|
118 |
|
119 BorderColor:= SDL_MapRGB(Surface^.format, BorderColor shr 16, BorderColor shr 8, BorderColor and $FF); |
|
120 FillColor:= SDL_MapRGB(Surface^.format, FillColor shr 16, FillColor shr 8, FillColor and $FF); |
|
121 |
|
122 r.y:= rect^.y + 1; |
|
123 r.h:= rect^.h - 2; |
|
124 SDL_FillRect(Surface, @r, BorderColor); |
|
125 r.x:= rect^.x + 1; |
|
126 r.w:= rect^.w - 2; |
|
127 r.y:= rect^.y; |
|
128 r.h:= rect^.h; |
|
129 SDL_FillRect(Surface, @r, BorderColor); |
|
130 r.x:= rect^.x + 2; |
|
131 r.y:= rect^.y + 1; |
|
132 r.w:= rect^.w - 4; |
|
133 r.h:= rect^.h - 2; |
|
134 SDL_FillRect(Surface, @r, FillColor); |
|
135 r.x:= rect^.x + 1; |
|
136 r.y:= rect^.y + 2; |
|
137 r.w:= rect^.w - 2; |
|
138 r.h:= rect^.h - 4; |
|
139 SDL_FillRect(Surface, @r, FillColor) |
|
140 end; |
|
141 |
|
142 function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect; |
|
143 var w, h: LongInt; |
|
144 tmpsurf: PSDL_Surface; |
|
145 clr: TSDL_Color; |
|
146 finalRect: TSDL_Rect; |
|
147 begin |
|
148 w:= 0; h:= 0; // avoid compiler hints |
|
149 TTF_SizeUTF8(Fontz[Font].Handle, Str2PChar(s), w, h); |
|
150 finalRect.x:= X; |
|
151 finalRect.y:= Y; |
|
152 finalRect.w:= w + FontBorder * 2 + 4; |
|
153 finalRect.h:= h + FontBorder * 2; |
|
154 DrawRoundRect(@finalRect, cWhiteColor, endian(cNearBlackColorChannels.value), Surface, true); |
|
155 clr.r:= (Color shr 16) and $FF; |
|
156 clr.g:= (Color shr 8) and $FF; |
|
157 clr.b:= Color and $FF; |
|
158 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(s), clr); |
|
159 finalRect.x:= X + FontBorder + 2; |
|
160 finalRect.y:= Y + FontBorder; |
|
161 SDLTry(tmpsurf <> nil, true); |
|
162 SDL_UpperBlit(tmpsurf, nil, Surface, @finalRect); |
|
163 SDL_FreeSurface(tmpsurf); |
|
164 finalRect.x:= X; |
|
165 finalRect.y:= Y; |
|
166 finalRect.w:= w + FontBorder * 2 + 4; |
|
167 finalRect.h:= h + FontBorder * 2; |
|
168 WriteInRoundRect:= finalRect; |
|
169 end; |
|
170 |
48 |
171 function WriteInRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect; |
49 function WriteInRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect; |
172 var w, h: LongInt; |
50 var w, h: LongInt; |
173 tmpsurf: PSDL_Surface; |
51 tmpsurf: PSDL_Surface; |
174 clr: TSDL_Color; |
52 clr: TSDL_Color; |
481 {$IFDEF SDL_IMAGE_NEWER} |
362 {$IFDEF SDL_IMAGE_NEWER} |
482 IMG_Quit(); |
363 IMG_Quit(); |
483 {$ENDIF} |
364 {$ENDIF} |
484 end; |
365 end; |
485 |
366 |
486 procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
|
487 begin |
|
488 DrawFromRect(X, Y, r^.w, r^.h, r, SourceTexture) |
|
489 end; |
|
490 |
|
491 procedure DrawFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
|
492 var rr: TSDL_Rect; |
|
493 _l, _r, _t, _b: real; |
|
494 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
|
495 begin |
|
496 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then exit; |
|
497 |
|
498 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
499 if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then |
|
500 exit; |
|
501 if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then |
|
502 exit; |
|
503 |
|
504 rr.x:= X; |
|
505 rr.y:= Y; |
|
506 rr.w:= W; |
|
507 rr.h:= H; |
|
508 |
|
509 _l:= r^.x / SourceTexture^.w * SourceTexture^.rx; |
|
510 _r:= (r^.x + r^.w) / SourceTexture^.w * SourceTexture^.rx; |
|
511 _t:= r^.y / SourceTexture^.h * SourceTexture^.ry; |
|
512 _b:= (r^.y + r^.h) / SourceTexture^.h * SourceTexture^.ry; |
|
513 |
|
514 glBindTexture(GL_TEXTURE_2D, SourceTexture^.id); |
|
515 |
|
516 VertexBuffer[0].X:= X; |
|
517 VertexBuffer[0].Y:= Y; |
|
518 VertexBuffer[1].X:= rr.w + X; |
|
519 VertexBuffer[1].Y:= Y; |
|
520 VertexBuffer[2].X:= rr.w + X; |
|
521 VertexBuffer[2].Y:= rr.h + Y; |
|
522 VertexBuffer[3].X:= X; |
|
523 VertexBuffer[3].Y:= rr.h + Y; |
|
524 |
|
525 TextureBuffer[0].X:= _l; |
|
526 TextureBuffer[0].Y:= _t; |
|
527 TextureBuffer[1].X:= _r; |
|
528 TextureBuffer[1].Y:= _t; |
|
529 TextureBuffer[2].X:= _r; |
|
530 TextureBuffer[2].Y:= _b; |
|
531 TextureBuffer[3].X:= _l; |
|
532 TextureBuffer[3].Y:= _b; |
|
533 |
|
534 |
|
535 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
|
536 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
|
537 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
538 end; |
|
539 |
|
540 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat); |
|
541 begin |
|
542 |
|
543 glPushMatrix; |
|
544 glTranslatef(X, Y, 0); |
|
545 glScalef(Scale, Scale, 1); |
|
546 |
|
547 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
|
548 |
|
549 glVertexPointer(2, GL_FLOAT, 0, @Texture^.vb); |
|
550 glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb); |
|
551 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb)); |
|
552 |
|
553 glPopMatrix |
|
554 end; |
|
555 |
|
556 procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt); |
|
557 begin |
|
558 DrawRotatedTextureF(Texture, Scale, 0, 0, X, Y, Frame, Dir, w, h, 0) |
|
559 end; |
|
560 |
|
561 procedure DrawRotatedTextureF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
|
562 var ft, fb, fl, fr: GLfloat; |
|
563 hw, nx, ny: LongInt; |
|
564 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
|
565 begin |
|
566 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
567 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then |
|
568 exit; |
|
569 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then |
|
570 exit; |
|
571 |
|
572 glPushMatrix; |
|
573 glTranslatef(X, Y, 0); |
|
574 |
|
575 if Dir < 0 then |
|
576 glRotatef(Angle, 0, 0, -1) |
|
577 else |
|
578 glRotatef(Angle, 0, 0, 1); |
|
579 |
|
580 glTranslatef(Dir*OffsetX, OffsetY, 0); |
|
581 glScalef(Scale, Scale, 1); |
|
582 |
|
583 // Any reason for this call? And why only in t direction, not s? |
|
584 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
|
585 |
|
586 if Dir < 0 then |
|
587 hw:= w div -2 |
|
588 else |
|
589 hw:= w div 2; |
|
590 |
|
591 nx:= round(Texture^.w / w); // number of horizontal frames |
|
592 ny:= round(Texture^.h / h); // number of vertical frames |
|
593 |
|
594 ft:= (Frame mod ny) * Texture^.ry / ny; |
|
595 fb:= ((Frame mod ny) + 1) * Texture^.ry / ny; |
|
596 fl:= (Frame div ny) * Texture^.rx / nx; |
|
597 fr:= ((Frame div ny) + 1) * Texture^.rx / nx; |
|
598 |
|
599 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
|
600 |
|
601 VertexBuffer[0].X:= -hw; |
|
602 VertexBuffer[0].Y:= w / -2; |
|
603 VertexBuffer[1].X:= hw; |
|
604 VertexBuffer[1].Y:= w / -2; |
|
605 VertexBuffer[2].X:= hw; |
|
606 VertexBuffer[2].Y:= w / 2; |
|
607 VertexBuffer[3].X:= -hw; |
|
608 VertexBuffer[3].Y:= w / 2; |
|
609 |
|
610 TextureBuffer[0].X:= fl; |
|
611 TextureBuffer[0].Y:= ft; |
|
612 TextureBuffer[1].X:= fr; |
|
613 TextureBuffer[1].Y:= ft; |
|
614 TextureBuffer[2].X:= fr; |
|
615 TextureBuffer[2].Y:= fb; |
|
616 TextureBuffer[3].X:= fl; |
|
617 TextureBuffer[3].Y:= fb; |
|
618 |
|
619 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
|
620 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
|
621 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
622 |
|
623 glPopMatrix |
|
624 end; |
|
625 |
|
626 procedure DrawRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); |
|
627 begin |
|
628 DrawRotatedTex(SpritesData[Sprite].Texture, |
|
629 SpritesData[Sprite].Width, |
|
630 SpritesData[Sprite].Height, |
|
631 X, Y, Dir, Angle) |
|
632 end; |
|
633 |
|
634 procedure DrawRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); |
|
635 begin |
|
636 glPushMatrix; |
|
637 glTranslatef(X, Y, 0); |
|
638 |
|
639 if Dir < 0 then |
|
640 glRotatef(Angle, 0, 0, -1) |
|
641 else |
|
642 glRotatef(Angle, 0, 0, 1); |
|
643 if Dir < 0 then glScalef(-1.0, 1.0, 1.0); |
|
644 |
|
645 DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame); |
|
646 |
|
647 glPopMatrix |
|
648 end; |
|
649 |
|
650 procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
|
651 var VertexBuffer: array [0..3] of TVertex2f; |
|
652 begin |
|
653 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
654 if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then |
|
655 exit; |
|
656 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then |
|
657 exit; |
|
658 |
|
659 glPushMatrix; |
|
660 glTranslatef(X, Y, 0); |
|
661 |
|
662 if Dir < 0 then |
|
663 begin |
|
664 hw:= - hw; |
|
665 glRotatef(Angle, 0, 0, -1); |
|
666 end else |
|
667 glRotatef(Angle, 0, 0, 1); |
|
668 |
|
669 |
|
670 glBindTexture(GL_TEXTURE_2D, Tex^.id); |
|
671 |
|
672 VertexBuffer[0].X:= -hw; |
|
673 VertexBuffer[0].Y:= -hh; |
|
674 VertexBuffer[1].X:= hw; |
|
675 VertexBuffer[1].Y:= -hh; |
|
676 VertexBuffer[2].X:= hw; |
|
677 VertexBuffer[2].Y:= hh; |
|
678 VertexBuffer[3].X:= -hw; |
|
679 VertexBuffer[3].Y:= hh; |
|
680 |
|
681 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
|
682 glTexCoordPointer(2, GL_FLOAT, 0, @Tex^.tb); |
|
683 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
684 |
|
685 glPopMatrix |
|
686 end; |
|
687 |
|
688 procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
|
689 begin |
|
690 r.y:= r.y + Height * Position; |
|
691 r.h:= Height; |
|
692 DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
|
693 end; |
|
694 |
|
695 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
|
696 var row, col, numFramesFirstCol: LongInt; |
|
697 begin |
|
698 numFramesFirstCol:= SpritesData[Sprite].imageHeight div SpritesData[Sprite].Height; |
|
699 row:= Frame mod numFramesFirstCol; |
|
700 col:= Frame div numFramesFirstCol; |
|
701 DrawSprite2 (Sprite, X, Y, col, row); |
|
702 end; |
|
703 |
|
704 procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
|
705 var r: TSDL_Rect; |
|
706 begin |
|
707 r.x:= 0; |
|
708 r.y:= 0; |
|
709 r.w:= SpritesData[Sprite].Width; |
|
710 r.h:= SpritesData[Sprite].Height; |
|
711 |
|
712 if (X < LeftX) then |
|
713 r.x:= LeftX - X; |
|
714 if (Y < TopY) then |
|
715 r.y:= TopY - Y; |
|
716 |
|
717 if (Y + SpritesData[Sprite].Height > BottomY) then |
|
718 r.h:= BottomY - Y + 1; |
|
719 if (X + SpritesData[Sprite].Width > RightX) then |
|
720 r.w:= RightX - X + 1; |
|
721 |
|
722 dec(r.h, r.y); |
|
723 dec(r.w, r.x); |
|
724 |
|
725 DrawFromRect(X + r.x, Y + r.y, @r, SpritesData[Sprite].Texture) |
|
726 end; |
|
727 |
|
728 procedure DrawSprite2(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
|
729 var r: TSDL_Rect; |
|
730 begin |
|
731 r.x:= FrameX * SpritesData[Sprite].Width; |
|
732 r.w:= SpritesData[Sprite].Width; |
|
733 r.y:= FrameY * SpritesData[Sprite].Height; |
|
734 r.h:= SpritesData[Sprite].Height; |
|
735 DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
|
736 end; |
|
737 |
|
738 procedure DrawCentered(X, Top: LongInt; Source: PTexture); |
|
739 var scale: GLfloat; |
|
740 begin |
|
741 if (Source^.w + 20) > cScreenWidth then |
|
742 scale:= cScreenWidth / (Source^.w + 20) |
|
743 else |
|
744 scale:= 1.0; |
|
745 DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale) |
|
746 end; |
|
747 |
|
748 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
|
749 const VertexBuffer: array [0..3] of TVertex2f = ( |
|
750 (x: -16; y: -16), |
|
751 (x: 16; y: -16), |
|
752 (x: 16; y: 16), |
|
753 (x: -16; y: 16)); |
|
754 var l, r, t, b: real; |
|
755 TextureBuffer: array [0..3] of TVertex2f; |
|
756 begin |
|
757 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
758 if (abs(X) > 32) and ((abs(X) - 16) * cScaleFactor > cScreenWidth) then |
|
759 exit; |
|
760 if (abs(Y) > 32) and ((abs(Y - 0.5 * cScreenHeight) - 16) * cScaleFactor > cScreenHeight) then |
|
761 exit; |
|
762 |
|
763 t:= Pos * 32 / HHTexture^.h; |
|
764 b:= (Pos + 1) * 32 / HHTexture^.h; |
|
765 |
|
766 if Dir = -1 then |
|
767 begin |
|
768 l:= (Step + 1) * 32 / HHTexture^.w; |
|
769 r:= Step * 32 / HHTexture^.w |
|
770 end else |
|
771 begin |
|
772 l:= Step * 32 / HHTexture^.w; |
|
773 r:= (Step + 1) * 32 / HHTexture^.w |
|
774 end; |
|
775 |
|
776 |
|
777 glPushMatrix(); |
|
778 glTranslatef(X, Y, 0); |
|
779 glRotatef(Angle, 0, 0, 1); |
|
780 |
|
781 glBindTexture(GL_TEXTURE_2D, HHTexture^.id); |
|
782 |
|
783 TextureBuffer[0].X:= l; |
|
784 TextureBuffer[0].Y:= t; |
|
785 TextureBuffer[1].X:= r; |
|
786 TextureBuffer[1].Y:= t; |
|
787 TextureBuffer[2].X:= r; |
|
788 TextureBuffer[2].Y:= b; |
|
789 TextureBuffer[3].X:= l; |
|
790 TextureBuffer[3].Y:= b; |
|
791 |
|
792 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
|
793 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
|
794 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
795 |
|
796 glPopMatrix |
|
797 end; |
|
798 |
|
799 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
|
800 var VertexBuffer: array [0..3] of TVertex2f; |
|
801 begin |
|
802 glDisable(GL_TEXTURE_2D); |
|
803 glEnable(GL_LINE_SMOOTH); |
|
804 |
|
805 glPushMatrix; |
|
806 glTranslatef(WorldDx, WorldDy, 0); |
|
807 glLineWidth(Width); |
|
808 |
|
809 Tint(r, g, b, a); |
|
810 VertexBuffer[0].X:= X0; |
|
811 VertexBuffer[0].Y:= Y0; |
|
812 VertexBuffer[1].X:= X1; |
|
813 VertexBuffer[1].Y:= Y1; |
|
814 |
|
815 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
|
816 glDrawArrays(GL_LINES, 0, Length(VertexBuffer)); |
|
817 Tint($FF, $FF, $FF, $FF); |
|
818 |
|
819 glPopMatrix; |
|
820 |
|
821 glEnable(GL_TEXTURE_2D); |
|
822 glDisable(GL_LINE_SMOOTH); |
|
823 end; |
|
824 |
|
825 procedure DrawFillRect(r: TSDL_Rect); |
|
826 var VertexBuffer: array [0..3] of TVertex2f; |
|
827 begin |
|
828 // don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
|
829 if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then |
|
830 exit; |
|
831 if (abs(r.y) > r.h) and ((abs(r.y + r.h / 2 - (0.5 * cScreenHeight)) - r.h / 2) * cScaleFactor > cScreenHeight) then |
|
832 exit; |
|
833 |
|
834 glDisable(GL_TEXTURE_2D); |
|
835 |
|
836 Tint($00, $00, $00, $80); |
|
837 |
|
838 VertexBuffer[0].X:= r.x; |
|
839 VertexBuffer[0].Y:= r.y; |
|
840 VertexBuffer[1].X:= r.x + r.w; |
|
841 VertexBuffer[1].Y:= r.y; |
|
842 VertexBuffer[2].X:= r.x + r.w; |
|
843 VertexBuffer[2].Y:= r.y + r.h; |
|
844 VertexBuffer[3].X:= r.x; |
|
845 VertexBuffer[3].Y:= r.y + r.h; |
|
846 |
|
847 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
|
848 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
|
849 |
|
850 Tint($FF, $FF, $FF, $FF); |
|
851 glEnable(GL_TEXTURE_2D) |
|
852 end; |
|
853 |
|
854 procedure DrawCircle(X, Y, Radius: LongInt; Width: Single; r, g, b, a: Byte); |
|
855 var |
|
856 i: LongInt; |
|
857 CircleVertex: array [0..359] of TVertex2f; |
|
858 begin |
|
859 for i := 0 to 359 do begin |
|
860 CircleVertex[i].X := X + Radius*cos(i*pi/180); |
|
861 CircleVertex[i].Y := Y + Radius*sin(i*pi/180); |
|
862 end; |
|
863 glDisable(GL_TEXTURE_2D); |
|
864 glEnable(GL_LINE_SMOOTH); |
|
865 glPushMatrix; |
|
866 glLineWidth(Width); |
|
867 Tint(r, g, b, a); |
|
868 glVertexPointer(2, GL_FLOAT, 0, @CircleVertex[0]); |
|
869 glDrawArrays(GL_LINE_LOOP, 0, 360); |
|
870 Tint($FF, $FF, $FF, $FF); |
|
871 glPopMatrix; |
|
872 glEnable(GL_TEXTURE_2D); |
|
873 glDisable(GL_LINE_SMOOTH); |
|
874 end; |
|
875 |
|
876 procedure StoreRelease; |
367 procedure StoreRelease; |
877 var ii: TSprite; |
368 var ii: TSprite; |
878 begin |
369 begin |
879 for ii:= Low(TSprite) to High(TSprite) do |
370 for ii:= Low(TSprite) to High(TSprite) do |
880 begin |
371 begin |
899 end |
390 end |
900 {$ENDIF} |
391 {$ENDIF} |
901 end; |
392 end; |
902 |
393 |
903 |
394 |
904 function CheckCJKFont(s: ansistring; font: THWFont): THWFont; |
|
905 var l, i : LongInt; |
|
906 u: WideChar; |
|
907 tmpstr: array[0..256] of WideChar; |
|
908 begin |
|
909 |
|
910 {$IFNDEF IPHONEOS} |
|
911 // remove chinese fonts for now |
|
912 if (font >= CJKfnt16) or (length(s) = 0) then |
|
913 {$ENDIF} |
|
914 exit(font); |
|
915 |
|
916 l:= Utf8ToUnicode(@tmpstr, Str2PChar(s), length(s))-1; |
|
917 i:= 0; |
|
918 while i < l do |
|
919 begin |
|
920 u:= tmpstr[i]; |
|
921 if (#$2E80 <= u) and ( |
|
922 (u <= #$2FDF ) or // CJK Radicals Supplement / Kangxi Radicals |
|
923 ((#$2FF0 <= u) and (u <= #$303F)) or // Ideographic Description Characters / CJK Radicals Supplement |
|
924 ((#$31C0 <= u) and (u <= #$31EF)) or // CJK Strokes |
|
925 ((#$3200 <= u) and (u <= #$4DBF)) or // Enclosed CJK Letters and Months / CJK Compatibility / CJK Unified Ideographs Extension A |
|
926 ((#$4E00 <= u) and (u <= #$9FFF)) or // CJK Unified Ideographs |
|
927 ((#$F900 <= u) and (u <= #$FAFF)) or // CJK Compatibility Ideographs |
|
928 ((#$FE30 <= u) and (u <= #$FE4F))) // CJK Compatibility Forms |
|
929 then exit(THWFont( ord(font) + ((ord(High(THWFont))+1) div 2) )); |
|
930 inc(i) |
|
931 end; |
|
932 exit(font); |
|
933 (* two more to check. pascal WideChar is only 16 bit though |
|
934 ((#$20000 <= u) and (u >= #$2A6DF)) or // CJK Unified Ideographs Extension B |
|
935 ((#$2F800 <= u) and (u >= #$2FA1F))) // CJK Compatibility Ideographs Supplement *) |
|
936 end; |
|
937 |
|
938 function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture; |
|
939 var w, h: LongInt; |
|
940 finalSurface: PSDL_Surface; |
|
941 begin |
|
942 if length(s) = 0 then s:= ' '; |
|
943 font:= CheckCJKFont(s, font); |
|
944 w:= 0; h:= 0; // avoid compiler hints |
|
945 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(s), w, h); |
|
946 |
|
947 finalSurface:= SDL_CreateRGBSurface(SDL_SWSURFACE, w + FontBorder * 2 + 4, h + FontBorder * 2, |
|
948 32, RMask, GMask, BMask, AMask); |
|
949 |
|
950 TryDo(finalSurface <> nil, 'RenderString: fail to create surface', true); |
|
951 |
|
952 WriteInRoundRect(finalSurface, 0, 0, Color, font, s); |
|
953 |
|
954 TryDo(SDL_SetColorKey(finalSurface, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
|
955 |
|
956 RenderStringTex:= Surface2Tex(finalSurface, false); |
|
957 |
|
958 SDL_FreeSurface(finalSurface); |
|
959 end; |
|
960 |
|
961 function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture; |
|
962 var textWidth, textHeight, x, y, w, h, i, j, pos, prevpos, line, numLines, edgeWidth, edgeHeight, cornerWidth, cornerHeight: LongInt; |
|
963 finalSurface, tmpsurf, rotatedEdge: PSDL_Surface; |
|
964 rect: TSDL_Rect; |
|
965 chars: TSysCharSet = [#9,' ','.',';',':','?','!',',']; |
|
966 substr: shortstring; |
|
967 edge, corner, tail: TSPrite; |
|
968 begin |
|
969 |
|
970 case SpeechType of |
|
971 1: begin; |
|
972 edge:= sprSpeechEdge; |
|
973 corner:= sprSpeechCorner; |
|
974 tail:= sprSpeechTail; |
|
975 end; |
|
976 2: begin; |
|
977 edge:= sprThoughtEdge; |
|
978 corner:= sprThoughtCorner; |
|
979 tail:= sprThoughtTail; |
|
980 end; |
|
981 3: begin; |
|
982 edge:= sprShoutEdge; |
|
983 corner:= sprShoutCorner; |
|
984 tail:= sprShoutTail; |
|
985 end; |
|
986 end; |
|
987 edgeHeight:= SpritesData[edge].Height; |
|
988 edgeWidth:= SpritesData[edge].Width; |
|
989 cornerWidth:= SpritesData[corner].Width; |
|
990 cornerHeight:= SpritesData[corner].Height; |
|
991 // This one screws up WrapText |
|
992 //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...'; |
|
993 // This one does not |
|
994 //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 will go on singing it forever just because... This is the song that never ends... '; |
|
995 |
|
996 numLines:= 0; |
|
997 |
|
998 if length(s) = 0 then s:= '...'; |
|
999 font:= CheckCJKFont(s, font); |
|
1000 w:= 0; h:= 0; // avoid compiler hints |
|
1001 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(s), w, h); |
|
1002 if w<8 then w:= 8; |
|
1003 j:= 0; |
|
1004 if (length(s) > 20) then |
|
1005 begin |
|
1006 w:= 0; |
|
1007 i:= round(Sqrt(length(s)) * 2); |
|
1008 s:= WrapText(s, #1, chars, i); |
|
1009 pos:= 1; prevpos:= 0; line:= 0; |
|
1010 // Find the longest line for the purposes of centring the text. Font dependant. |
|
1011 while pos <= length(s) do |
|
1012 begin |
|
1013 if (s[pos] = #1) or (pos = length(s)) then |
|
1014 begin |
|
1015 inc(numlines); |
|
1016 if s[pos] <> #1 then inc(pos); |
|
1017 while s[prevpos+1] = ' ' do inc(prevpos); |
|
1018 substr:= copy(s, prevpos+1, pos-prevpos-1); |
|
1019 i:= 0; j:= 0; |
|
1020 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(substr), i, j); |
|
1021 if i > w then w:= i; |
|
1022 prevpos:= pos; |
|
1023 end; |
|
1024 inc(pos); |
|
1025 end; |
|
1026 end |
|
1027 else numLines := 1; |
|
1028 |
|
1029 textWidth:=((w-(cornerWidth-edgeWidth)*2) div edgeWidth)*edgeWidth+edgeWidth; |
|
1030 textHeight:=(((numlines * h + 2)-((cornerHeight-edgeWidth)*2)) div edgeWidth)*edgeWidth; |
|
1031 |
|
1032 textHeight:=max(textHeight,edgeWidth); |
|
1033 //textWidth:=max(textWidth,SpritesData[tail].Width); |
|
1034 rect.x:= 0; |
|
1035 rect.y:= 0; |
|
1036 rect.w:= textWidth + (cornerWidth * 2); |
|
1037 rect.h:= textHeight + cornerHeight*2 - edgeHeight + SpritesData[tail].Height; |
|
1038 //s:= inttostr(w) + ' ' + inttostr(numlines) + ' ' + inttostr(rect.x) + ' '+inttostr(rect.y) + ' ' + inttostr(rect.w) + ' ' + inttostr(rect.h); |
|
1039 |
|
1040 finalSurface:= SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, 32, RMask, GMask, BMask, AMask); |
|
1041 |
|
1042 TryDo(finalSurface <> nil, 'RenderString: fail to create surface', true); |
|
1043 |
|
1044 //////////////////////////////// CORNERS /////////////////////////////// |
|
1045 copyToXY(SpritesData[corner].Surface, finalSurface, 0, 0); /////////////////// NW |
|
1046 |
|
1047 flipSurface(SpritesData[corner].Surface, true); // store all 4 versions in memory to avoid repeated flips? |
|
1048 x:= 0; |
|
1049 y:= textHeight + cornerHeight -1; |
|
1050 copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// SW |
|
1051 |
|
1052 flipSurface(SpritesData[corner].Surface, false); |
|
1053 x:= rect.w-cornerWidth-1; |
|
1054 y:= textHeight + cornerHeight -1; |
|
1055 copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// SE |
|
1056 |
|
1057 flipSurface(SpritesData[corner].Surface, true); |
|
1058 x:= rect.w-cornerWidth-1; |
|
1059 y:= 0; |
|
1060 copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// NE |
|
1061 flipSurface(SpritesData[corner].Surface, false); // restore original position |
|
1062 //////////////////////////////// END CORNERS /////////////////////////////// |
|
1063 |
|
1064 //////////////////////////////// EDGES ////////////////////////////////////// |
|
1065 x:= cornerWidth; |
|
1066 y:= 0; |
|
1067 while x < rect.w-cornerWidth-1 do |
|
1068 begin |
|
1069 copyToXY(SpritesData[edge].Surface, finalSurface, x, y); ///////////////// top edge |
|
1070 inc(x,edgeWidth); |
|
1071 end; |
|
1072 flipSurface(SpritesData[edge].Surface, true); |
|
1073 x:= cornerWidth; |
|
1074 y:= textHeight + cornerHeight*2 - edgeHeight-1; |
|
1075 while x < rect.w-cornerWidth-1 do |
|
1076 begin |
|
1077 copyToXY(SpritesData[edge].Surface, finalSurface, x, y); ///////////////// bottom edge |
|
1078 inc(x,edgeWidth); |
|
1079 end; |
|
1080 flipSurface(SpritesData[edge].Surface, true); // restore original position |
|
1081 |
|
1082 rotatedEdge:= SDL_CreateRGBSurface(SDL_SWSURFACE, edgeHeight, edgeWidth, 32, RMask, GMask, BMask, AMask); |
|
1083 x:= rect.w - edgeHeight - 1; |
|
1084 y:= cornerHeight; |
|
1085 //// initially was going to rotate in place, but the SDL spec claims width/height are read only |
|
1086 copyRotatedSurface(SpritesData[edge].Surface,rotatedEdge); |
|
1087 while y < textHeight + cornerHeight do |
|
1088 begin |
|
1089 copyToXY(rotatedEdge, finalSurface, x, y); |
|
1090 inc(y,edgeWidth); |
|
1091 end; |
|
1092 flipSurface(rotatedEdge, false); // restore original position |
|
1093 x:= 0; |
|
1094 y:= cornerHeight; |
|
1095 while y < textHeight + cornerHeight do |
|
1096 begin |
|
1097 copyToXY(rotatedEdge, finalSurface, x, y); |
|
1098 inc(y,edgeWidth); |
|
1099 end; |
|
1100 //////////////////////////////// END EDGES ////////////////////////////////////// |
|
1101 |
|
1102 x:= cornerWidth; |
|
1103 y:= textHeight + cornerHeight * 2 - edgeHeight - 1; |
|
1104 copyToXY(SpritesData[tail].Surface, finalSurface, x, y); |
|
1105 |
|
1106 rect.x:= edgeHeight; |
|
1107 rect.y:= edgeHeight; |
|
1108 rect.w:= rect.w - edgeHeight * 2; |
|
1109 rect.h:= textHeight + cornerHeight * 2 - edgeHeight * 2; |
|
1110 i:= rect.w; |
|
1111 j:= rect.h; |
|
1112 SDL_FillRect(finalSurface, @rect, cWhiteColor); |
|
1113 |
|
1114 pos:= 1; prevpos:= 0; line:= 0; |
|
1115 while pos <= length(s) do |
|
1116 begin |
|
1117 if (s[pos] = #1) or (pos = length(s)) then |
|
1118 begin |
|
1119 if s[pos] <> #1 then inc(pos); |
|
1120 while s[prevpos+1] = ' 'do inc(prevpos); |
|
1121 substr:= copy(s, prevpos+1, pos-prevpos-1); |
|
1122 if Length(substr) <> 0 then |
|
1123 begin |
|
1124 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(substr), cNearBlackColorChannels); |
|
1125 rect.x:= edgeHeight + 1 + ((i - w) div 2); |
|
1126 // trying to more evenly position the text, vertically |
|
1127 rect.y:= edgeHeight + ((j-(numLines*h)) div 2) + line * h; |
|
1128 SDLTry(tmpsurf <> nil, true); |
|
1129 SDL_UpperBlit(tmpsurf, nil, finalSurface, @rect); |
|
1130 SDL_FreeSurface(tmpsurf); |
|
1131 inc(line); |
|
1132 prevpos:= pos; |
|
1133 end; |
|
1134 end; |
|
1135 inc(pos); |
|
1136 end; |
|
1137 |
|
1138 //TryDo(SDL_SetColorKey(finalSurface, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
|
1139 RenderSpeechBubbleTex:= Surface2Tex(finalSurface, true); |
|
1140 |
|
1141 SDL_FreeSurface(rotatedEdge); |
|
1142 SDL_FreeSurface(finalSurface); |
|
1143 end; |
|
1144 |
|
1145 procedure RenderHealth(var Hedgehog: THedgehog); |
395 procedure RenderHealth(var Hedgehog: THedgehog); |
1146 var s: shortstring; |
396 var s: shortstring; |
1147 begin |
397 begin |
1148 str(Hedgehog.Gear^.Health, s); |
398 str(Hedgehog.Gear^.Health, s); |
1149 if Hedgehog.HealthTagTex <> nil then |
399 if Hedgehog.HealthTagTex <> nil then |
1406 WriteLnToConsole('Freeing progress surface... '); |
656 WriteLnToConsole('Freeing progress surface... '); |
1407 FreeTexture(ProgrTex); |
657 FreeTexture(ProgrTex); |
1408 perfExt_FinishProgress(); |
658 perfExt_FinishProgress(); |
1409 end; |
659 end; |
1410 |
660 |
1411 procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); |
|
1412 var y, x, i, j: LongInt; |
|
1413 tmpPixel: Longword; |
|
1414 pixels: PLongWordArray; |
|
1415 begin |
|
1416 TryDo(Surface^.format^.BytesPerPixel = 4, 'flipSurface failed, expecting 32 bit surface', true); |
|
1417 pixels:= Surface^.pixels; |
|
1418 if Vertical then |
|
1419 for y := 0 to (Surface^.h div 2) - 1 do |
|
1420 for x := 0 to Surface^.w - 1 do |
|
1421 begin |
|
1422 i:= y * Surface^.w + x; |
|
1423 j:= (Surface^.h - y - 1) * Surface^.w + x; |
|
1424 tmpPixel:= pixels^[i]; |
|
1425 pixels^[i]:= pixels^[j]; |
|
1426 pixels^[j]:= tmpPixel; |
|
1427 end |
|
1428 else |
|
1429 for x := 0 to (Surface^.w div 2) - 1 do |
|
1430 for y := 0 to Surface^.h -1 do |
|
1431 begin |
|
1432 i:= y*Surface^.w + x; |
|
1433 j:= y*Surface^.w + (Surface^.w - x - 1); |
|
1434 tmpPixel:= pixels^[i]; |
|
1435 pixels^[i]:= pixels^[j]; |
|
1436 pixels^[j]:= tmpPixel; |
|
1437 end; |
|
1438 end; |
|
1439 |
|
1440 procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); |
|
1441 var srcX, srcY, i, j, maxDest: LongInt; |
|
1442 srcPixels, destPixels: PLongWordArray; |
|
1443 r0, g0, b0, a0, r1, g1, b1, a1: Byte; |
|
1444 begin |
|
1445 maxDest:= (dest^.pitch div 4) * dest^.h; |
|
1446 srcPixels:= src^.pixels; |
|
1447 destPixels:= dest^.pixels; |
|
1448 |
|
1449 for srcX:= 0 to src^.w - 1 do |
|
1450 for srcY:= 0 to src^.h - 1 do |
|
1451 begin |
|
1452 i:= (destY + srcY) * (dest^.pitch div 4) + destX + srcX; |
|
1453 j:= srcY * (src^.pitch div 4) + srcX; |
|
1454 if (i < maxDest) and (srcPixels^[j] and AMask <> 0) then |
|
1455 begin |
|
1456 SDL_GetRGBA(destPixels^[i], dest^.format, @r0, @g0, @b0, @a0); |
|
1457 SDL_GetRGBA(srcPixels^[j], src^.format, @r1, @g1, @b1, @a1); |
|
1458 r0:= (r0 * (255 - LongInt(a1)) + r1 * LongInt(a1)) div 255; |
|
1459 g0:= (g0 * (255 - LongInt(a1)) + g1 * LongInt(a1)) div 255; |
|
1460 b0:= (b0 * (255 - LongInt(a1)) + b1 * LongInt(a1)) div 255; |
|
1461 a0:= (a0 * (255 - LongInt(a1)) + a1 * LongInt(a1)) div 255; |
|
1462 destPixels^[i]:= SDL_MapRGBA(dest^.format, r0, g0, b0, a0); |
|
1463 end; |
|
1464 end; |
|
1465 end; |
|
1466 |
|
1467 procedure copyRotatedSurface(src, dest: PSDL_Surface); // this is necessary since width/height are read only in SDL, apparently |
|
1468 var y, x, i, j: LongInt; |
|
1469 srcPixels, destPixels: PLongWordArray; |
|
1470 begin |
|
1471 TryDo(src^.format^.BytesPerPixel = 4, 'rotateSurface failed, expecting 32 bit surface', true); |
|
1472 TryDo(dest^.format^.BytesPerPixel = 4, 'rotateSurface failed, expecting 32 bit surface', true); |
|
1473 |
|
1474 srcPixels:= src^.pixels; |
|
1475 destPixels:= dest^.pixels; |
|
1476 |
|
1477 j:= 0; |
|
1478 for x := 0 to src^.w - 1 do |
|
1479 for y := 0 to src^.h - 1 do |
|
1480 begin |
|
1481 i:= (src^.h - 1 - y) * (src^.pitch div 4) + x; |
|
1482 destPixels^[j]:= srcPixels^[i]; |
|
1483 inc(j) |
|
1484 end; |
|
1485 end; |
|
1486 |
|
1487 function RenderHelpWindow(caption, subcaption, description, extra: ansistring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture; |
661 function RenderHelpWindow(caption, subcaption, description, extra: ansistring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture; |
1488 var tmpsurf: PSDL_SURFACE; |
662 var tmpsurf: PSDL_SURFACE; |
1489 w, h, i, j: LongInt; |
663 w, h, i, j: LongInt; |
1490 font: THWFont; |
664 font: THWFont; |
1491 r, r2: TSDL_Rect; |
665 r, r2: TSDL_Rect; |