112 |
112 |
113 function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: string): TSDL_Rect; |
113 function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: string): TSDL_Rect; |
114 var w, h: LongInt; |
114 var w, h: LongInt; |
115 tmpsurf: PSDL_Surface; |
115 tmpsurf: PSDL_Surface; |
116 clr: TSDL_Color; |
116 clr: TSDL_Color; |
117 Result: TSDL_Rect; |
117 finalRect: TSDL_Rect; |
118 begin |
118 begin |
119 TTF_SizeUTF8(Fontz[Font].Handle, Str2PChar(s), w, h); |
119 TTF_SizeUTF8(Fontz[Font].Handle, Str2PChar(s), w, h); |
120 Result.x:= X; |
120 finalRect.x:= X; |
121 Result.y:= Y; |
121 finalRect.y:= Y; |
122 Result.w:= w + FontBorder * 2 + 4; |
122 finalRect.w:= w + FontBorder * 2 + 4; |
123 Result.h:= h + FontBorder * 2; |
123 finalRect.h:= h + FontBorder * 2; |
124 DrawRoundRect(@Result, cWhiteColor, endian(cNearBlackColorChannels.value), Surface, true); |
124 DrawRoundRect(@finalRect, cWhiteColor, endian(cNearBlackColorChannels.value), Surface, true); |
125 clr.r:= (Color shr 16) and $FF; |
125 clr.r:= (Color shr 16) and $FF; |
126 clr.g:= (Color shr 8) and $FF; |
126 clr.g:= (Color shr 8) and $FF; |
127 clr.b:= Color and $FF; |
127 clr.b:= Color and $FF; |
128 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(s), clr); |
128 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(s), clr); |
129 Result.x:= X + FontBorder + 2; |
129 finalRect.x:= X + FontBorder + 2; |
130 Result.y:= Y + FontBorder; |
130 finalRect.y:= Y + FontBorder; |
131 SDLTry(tmpsurf <> nil, true); |
131 SDLTry(tmpsurf <> nil, true); |
132 SDL_UpperBlit(tmpsurf, nil, Surface, @Result); |
132 SDL_UpperBlit(tmpsurf, nil, Surface, @finalRect); |
133 SDL_FreeSurface(tmpsurf); |
133 SDL_FreeSurface(tmpsurf); |
134 Result.x:= X; |
134 finalRect.x:= X; |
135 Result.y:= Y; |
135 finalRect.y:= Y; |
136 Result.w:= w + FontBorder * 2 + 4; |
136 finalRect.w:= w + FontBorder * 2 + 4; |
137 Result.h:= h + FontBorder * 2; |
137 finalRect.h:= h + FontBorder * 2; |
138 WriteInRoundRect:= Result |
138 WriteInRoundRect:= finalRect; |
139 end; |
139 end; |
140 |
140 |
141 procedure StoreLoad; |
141 procedure StoreLoad; |
142 var s: string; |
142 var s: string; |
143 |
143 |
788 ((#$2F800 <= u) and (u >= #$2FA1F))) // CJK Compatibility Ideographs Supplement *) |
788 ((#$2F800 <= u) and (u >= #$2FA1F))) // CJK Compatibility Ideographs Supplement *) |
789 end; |
789 end; |
790 |
790 |
791 function RenderStringTex(s: string; Color: Longword; font: THWFont): PTexture; |
791 function RenderStringTex(s: string; Color: Longword; font: THWFont): PTexture; |
792 var w, h : LongInt; |
792 var w, h : LongInt; |
793 Result: PSDL_Surface; |
793 finalSurface: PSDL_Surface; |
794 begin |
794 begin |
795 if length(s) = 0 then s:= ' '; |
795 if length(s) = 0 then s:= ' '; |
796 font:= CheckCJKFont(s, font); |
796 font:= CheckCJKFont(s, font); |
797 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(s), w, h); |
797 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(s), w, h); |
798 |
798 |
799 Result:= SDL_CreateRGBSurface(SDL_SWSURFACE, w + FontBorder * 2 + 4, h + FontBorder * 2, |
799 finalSurface:= SDL_CreateRGBSurface(SDL_SWSURFACE, w + FontBorder * 2 + 4, h + FontBorder * 2, |
800 32, RMask, GMask, BMask, AMask); |
800 32, RMask, GMask, BMask, AMask); |
801 |
801 |
802 TryDo(Result <> nil, 'RenderString: fail to create surface', true); |
802 TryDo(finalSurface <> nil, 'RenderString: fail to create surface', true); |
803 |
803 |
804 WriteInRoundRect(Result, 0, 0, Color, font, s); |
804 WriteInRoundRect(finalSurface, 0, 0, Color, font, s); |
805 |
805 |
806 TryDo(SDL_SetColorKey(Result, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
806 TryDo(SDL_SetColorKey(finalSurface, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
807 |
807 |
808 RenderStringTex:= Surface2Tex(Result, false); |
808 RenderStringTex:= Surface2Tex(finalSurface, false); |
809 |
809 |
810 SDL_FreeSurface(Result) |
810 SDL_FreeSurface(finalSurface); |
811 end; |
811 end; |
812 |
812 |
813 function RenderSpeechBubbleTex(s: string; SpeechType: Longword; font: THWFont): PTexture; |
813 function RenderSpeechBubbleTex(s: string; SpeechType: Longword; font: THWFont): PTexture; |
814 var textWidth, textHeight, x, y, w, h, i, j, pos, prevpos, line, numLines, edgeWidth, edgeHeight, cornerWidth, cornerHeight: LongInt; |
814 var textWidth, textHeight, x, y, w, h, i, j, pos, prevpos, line, numLines, edgeWidth, edgeHeight, cornerWidth, cornerHeight: LongInt; |
815 Result, tmpsurf, rotatedEdge: PSDL_Surface; |
815 finalSurface, tmpsurf, rotatedEdge: PSDL_Surface; |
816 rect: TSDL_Rect; |
816 rect: TSDL_Rect; |
817 chars: TSysCharSet = [#9,' ','.',';',':','?','!',',']; |
817 chars: TSysCharSet = [#9,' ','.',';',':','?','!',',']; |
818 substr: shortstring; |
818 substr: shortstring; |
819 edge, corner, tail: TSPrite; |
819 edge, corner, tail: TSPrite; |
820 begin |
820 begin |
886 rect.y:= 0; |
886 rect.y:= 0; |
887 rect.w:= textWidth + (cornerWidth * 2); |
887 rect.w:= textWidth + (cornerWidth * 2); |
888 rect.h:= textHeight + cornerHeight*2 - edgeHeight + SpritesData[tail].Height; |
888 rect.h:= textHeight + cornerHeight*2 - edgeHeight + SpritesData[tail].Height; |
889 //s:= inttostr(w) + ' ' + inttostr(numlines) + ' ' + inttostr(rect.x) + ' '+inttostr(rect.y) + ' ' + inttostr(rect.w) + ' ' + inttostr(rect.h); |
889 //s:= inttostr(w) + ' ' + inttostr(numlines) + ' ' + inttostr(rect.x) + ' '+inttostr(rect.y) + ' ' + inttostr(rect.w) + ' ' + inttostr(rect.h); |
890 |
890 |
891 Result:= SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, 32, RMask, GMask, BMask, AMask); |
891 finalSurface:= SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, 32, RMask, GMask, BMask, AMask); |
892 |
892 |
893 TryDo(Result <> nil, 'RenderString: fail to create surface', true); |
893 TryDo(finalSurface <> nil, 'RenderString: fail to create surface', true); |
894 |
894 |
895 //////////////////////////////// CORNERS /////////////////////////////// |
895 //////////////////////////////// CORNERS /////////////////////////////// |
896 copyToXY(SpritesData[corner].Surface, Result, 0, 0); /////////////////// NW |
896 copyToXY(SpritesData[corner].Surface, finalSurface, 0, 0); /////////////////// NW |
897 |
897 |
898 flipSurface(SpritesData[corner].Surface, true); // store all 4 versions in memory to avoid repeated flips? |
898 flipSurface(SpritesData[corner].Surface, true); // store all 4 versions in memory to avoid repeated flips? |
899 x:= 0; |
899 x:= 0; |
900 y:= textHeight + cornerHeight -1; |
900 y:= textHeight + cornerHeight -1; |
901 copyToXY(SpritesData[corner].Surface, Result, x, y); /////////////////// SW |
901 copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// SW |
902 |
902 |
903 flipSurface(SpritesData[corner].Surface, false); |
903 flipSurface(SpritesData[corner].Surface, false); |
904 x:= rect.w-cornerWidth-1; |
904 x:= rect.w-cornerWidth-1; |
905 y:= textHeight + cornerHeight -1; |
905 y:= textHeight + cornerHeight -1; |
906 copyToXY(SpritesData[corner].Surface, Result, x, y); /////////////////// SE |
906 copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// SE |
907 |
907 |
908 flipSurface(SpritesData[corner].Surface, true); |
908 flipSurface(SpritesData[corner].Surface, true); |
909 x:= rect.w-cornerWidth-1; |
909 x:= rect.w-cornerWidth-1; |
910 y:= 0; |
910 y:= 0; |
911 copyToXY(SpritesData[corner].Surface, Result, x, y); /////////////////// NE |
911 copyToXY(SpritesData[corner].Surface, finalSurface, x, y); /////////////////// NE |
912 flipSurface(SpritesData[corner].Surface, false); // restore original position |
912 flipSurface(SpritesData[corner].Surface, false); // restore original position |
913 //////////////////////////////// END CORNERS /////////////////////////////// |
913 //////////////////////////////// END CORNERS /////////////////////////////// |
914 |
914 |
915 //////////////////////////////// EDGES ////////////////////////////////////// |
915 //////////////////////////////// EDGES ////////////////////////////////////// |
916 x:= cornerWidth; |
916 x:= cornerWidth; |
917 y:= 0; |
917 y:= 0; |
918 while x < rect.w-cornerWidth-1 do |
918 while x < rect.w-cornerWidth-1 do |
919 begin |
919 begin |
920 copyToXY(SpritesData[edge].Surface, Result, x, y); ///////////////// top edge |
920 copyToXY(SpritesData[edge].Surface, finalSurface, x, y); ///////////////// top edge |
921 inc(x,edgeWidth); |
921 inc(x,edgeWidth); |
922 end; |
922 end; |
923 flipSurface(SpritesData[edge].Surface, true); |
923 flipSurface(SpritesData[edge].Surface, true); |
924 x:= cornerWidth; |
924 x:= cornerWidth; |
925 y:= textHeight + cornerHeight*2 - edgeHeight-1; |
925 y:= textHeight + cornerHeight*2 - edgeHeight-1; |
926 while x < rect.w-cornerWidth-1 do |
926 while x < rect.w-cornerWidth-1 do |
927 begin |
927 begin |
928 copyToXY(SpritesData[edge].Surface, Result, x, y); ///////////////// bottom edge |
928 copyToXY(SpritesData[edge].Surface, finalSurface, x, y); ///////////////// bottom edge |
929 inc(x,edgeWidth); |
929 inc(x,edgeWidth); |
930 end; |
930 end; |
931 flipSurface(SpritesData[edge].Surface, true); // restore original position |
931 flipSurface(SpritesData[edge].Surface, true); // restore original position |
932 |
932 |
933 rotatedEdge:= SDL_CreateRGBSurface(SDL_SWSURFACE, edgeHeight, edgeWidth, 32, RMask, GMask, BMask, AMask); |
933 rotatedEdge:= SDL_CreateRGBSurface(SDL_SWSURFACE, edgeHeight, edgeWidth, 32, RMask, GMask, BMask, AMask); |
935 y:= cornerHeight; |
935 y:= cornerHeight; |
936 //// initially was going to rotate in place, but the SDL spec claims width/height are read only |
936 //// initially was going to rotate in place, but the SDL spec claims width/height are read only |
937 copyRotatedSurface(SpritesData[edge].Surface,rotatedEdge); |
937 copyRotatedSurface(SpritesData[edge].Surface,rotatedEdge); |
938 while y < textHeight + cornerHeight do |
938 while y < textHeight + cornerHeight do |
939 begin |
939 begin |
940 copyToXY(rotatedEdge, Result, x, y); |
940 copyToXY(rotatedEdge, finalSurface, x, y); |
941 inc(y,edgeWidth); |
941 inc(y,edgeWidth); |
942 end; |
942 end; |
943 flipSurface(rotatedEdge, false); // restore original position |
943 flipSurface(rotatedEdge, false); // restore original position |
944 x:= 0; |
944 x:= 0; |
945 y:= cornerHeight; |
945 y:= cornerHeight; |
946 while y < textHeight + cornerHeight do |
946 while y < textHeight + cornerHeight do |
947 begin |
947 begin |
948 copyToXY(rotatedEdge, Result, x, y); |
948 copyToXY(rotatedEdge, finalSurface, x, y); |
949 inc(y,edgeWidth); |
949 inc(y,edgeWidth); |
950 end; |
950 end; |
951 //////////////////////////////// END EDGES ////////////////////////////////////// |
951 //////////////////////////////// END EDGES ////////////////////////////////////// |
952 |
952 |
953 x:= cornerWidth; |
953 x:= cornerWidth; |
954 y:= textHeight + cornerHeight * 2 - edgeHeight - 1; |
954 y:= textHeight + cornerHeight * 2 - edgeHeight - 1; |
955 copyToXY(SpritesData[tail].Surface, Result, x, y); |
955 copyToXY(SpritesData[tail].Surface, finalSurface, x, y); |
956 |
956 |
957 rect.x:= edgeHeight; |
957 rect.x:= edgeHeight; |
958 rect.y:= edgeHeight; |
958 rect.y:= edgeHeight; |
959 rect.w:= rect.w - edgeHeight * 2; |
959 rect.w:= rect.w - edgeHeight * 2; |
960 rect.h:= textHeight + cornerHeight * 2 - edgeHeight * 2; |
960 rect.h:= textHeight + cornerHeight * 2 - edgeHeight * 2; |
961 i:= rect.w; |
961 i:= rect.w; |
962 j:= rect.h; |
962 j:= rect.h; |
963 SDL_FillRect(Result, @rect, cWhiteColor); |
963 SDL_FillRect(finalSurface, @rect, cWhiteColor); |
964 |
964 |
965 pos:= 1; prevpos:= 0; line:= 0; |
965 pos:= 1; prevpos:= 0; line:= 0; |
966 while pos <= length(s) do |
966 while pos <= length(s) do |
967 begin |
967 begin |
968 if (s[pos] = #1) or (pos = length(s)) then |
968 if (s[pos] = #1) or (pos = length(s)) then |
975 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(substr), cNearBlackColorChannels); |
975 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(substr), cNearBlackColorChannels); |
976 rect.x:= edgeHeight + 1 + ((i - w) div 2); |
976 rect.x:= edgeHeight + 1 + ((i - w) div 2); |
977 // trying to more evenly position the text, vertically |
977 // trying to more evenly position the text, vertically |
978 rect.y:= edgeHeight + ((j-(numLines*h)) div 2) + line * h; |
978 rect.y:= edgeHeight + ((j-(numLines*h)) div 2) + line * h; |
979 SDLTry(tmpsurf <> nil, true); |
979 SDLTry(tmpsurf <> nil, true); |
980 SDL_UpperBlit(tmpsurf, nil, Result, @rect); |
980 SDL_UpperBlit(tmpsurf, nil, finalSurface, @rect); |
981 SDL_FreeSurface(tmpsurf); |
981 SDL_FreeSurface(tmpsurf); |
982 inc(line); |
982 inc(line); |
983 prevpos:= pos; |
983 prevpos:= pos; |
984 end; |
984 end; |
985 end; |
985 end; |
986 inc(pos); |
986 inc(pos); |
987 end; |
987 end; |
988 |
988 |
989 //TryDo(SDL_SetColorKey(Result, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
989 //TryDo(SDL_SetColorKey(finalSurface, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); |
990 RenderSpeechBubbleTex:= Surface2Tex(Result, true); |
990 RenderSpeechBubbleTex:= Surface2Tex(finalSurface, true); |
991 |
991 |
992 SDL_FreeSurface(rotatedEdge); |
992 SDL_FreeSurface(rotatedEdge); |
993 SDL_FreeSurface(Result) |
993 SDL_FreeSurface(finalSurface); |
994 end; |
994 end; |
995 |
995 |
996 procedure RenderHealth(var Hedgehog: THedgehog); |
996 procedure RenderHealth(var Hedgehog: THedgehog); |
997 var s: shortstring; |
997 var s: shortstring; |
998 begin |
998 begin |