--- a/hedgewars/uStore.pas Thu Aug 26 23:59:18 2010 +0200
+++ b/hedgewars/uStore.pas Wed Oct 27 14:02:20 2010 +0200
@@ -20,7 +20,7 @@
unit uStore;
interface
-uses sysutils, uConsts, uTeams, SDLh, GLunit;
+uses sysutils, uConsts, uTeams, SDLh, GLunit, uWorld;
var PixelFormat: PSDL_PixelFormat;
@@ -62,6 +62,7 @@
procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real);
procedure DrawFillRect(r: TSDL_Rect);
+procedure DrawCircle(X, Y, Radius: LongInt; Width: Single; r, g, b, a: Byte);
procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean);
function CheckCJKFont(s: ansistring; font: THWFont): THWFont;
function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture;
@@ -84,7 +85,7 @@
procedure Tint(c: Longword); inline;
implementation
-uses uMisc, uConsole, uLocale;
+uses uMisc, uConsole, uLocale, uMobile;
type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple);
@@ -237,13 +238,13 @@
r.h:= 19;
DrawRoundRect(@r, cWhiteColor, cNearBlackColor, texsurf, true);
-
+
// overwrite flag for cpu teams and keep players from using it
if (Hedgehogs[0].Gear <> nil) and (Hedgehogs[0].BotLevel > 0) then
Flag:= 'cpu'
else if Flag = 'cpu' then
Flag:= 'hedgewars';
-
+
flagsurf:= LoadImage(Pathz[ptFlags] + '/' + Flag, ifNone);
if flagsurf = nil then
flagsurf:= LoadImage(Pathz[ptFlags] + '/hedgewars', ifNone);
@@ -251,7 +252,7 @@
copyToXY(flagsurf, texsurf, 2, 2);
SDL_FreeSurface(flagsurf);
flagsurf:= nil;
-
+
// restore black border pixels inside the flag
PLongwordArray(texsurf^.pixels)^[32 * 2 + 2]:= cNearBlackColor;
PLongwordArray(texsurf^.pixels)^[32 * 2 + 23]:= cNearBlackColor;
@@ -261,6 +262,8 @@
FlagTex:= Surface2Tex(texsurf, false);
SDL_FreeSurface(texsurf);
+ AIKillsTex := RenderStringTex(inttostr(stats.AIKills), Clan^.Color, fnt16);
+
dec(drY, r.h + 2);
DrawHealthY:= drY;
for i:= 0 to 7 do
@@ -274,27 +277,27 @@
texsurf:= LoadImage(Pathz[ptHats] + '/Reserved/' + Copy(Hat,9,Length(s)-8), ifNone)
else
texsurf:= LoadImage(Pathz[ptHats] + '/' + Hat, ifNone);
- if texsurf <> nil then
+ if texsurf <> nil then
begin
- HatTex:= Surface2Tex(texsurf, true);
- SDL_FreeSurface(texsurf)
+ HatTex:= Surface2Tex(texsurf, true);
+ SDL_FreeSurface(texsurf)
end;
- texsurf:= nil;
+ texsurf:= nil;
end
end;
end;
MissionIcons:= LoadImage(Pathz[ptGraphics] + '/missions', ifCritical);
iconsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, 28, 28, 32, RMask, GMask, BMask, AMask);
- if iconsurf <> nil then
+ if iconsurf <> nil then
begin
- r.x:= 0;
- r.y:= 0;
- r.w:= 28;
- r.h:= 28;
- DrawRoundRect(@r, cWhiteColor, cNearBlackColor, iconsurf, true);
- ropeIconTex:= Surface2Tex(iconsurf, false);
- SDL_FreeSurface(iconsurf);
- iconsurf:= nil;
+ r.x:= 0;
+ r.y:= 0;
+ r.w:= 28;
+ r.h:= 28;
+ DrawRoundRect(@r, cWhiteColor, cNearBlackColor, iconsurf, true);
+ ropeIconTex:= Surface2Tex(iconsurf, false);
+ SDL_FreeSurface(iconsurf);
+ iconsurf:= nil;
end;
end;
@@ -325,7 +328,7 @@
// make black pixel be alpha-transparent
for i:= 0 to texsurf^.w * texsurf^.h - 1 do
- if PLongwordArray(texsurf^.pixels)^[i] = AMask then PLongwordArray(texsurf^.pixels)^[i]:= 0;
+ if PLongwordArray(texsurf^.pixels)^[i] = AMask then PLongwordArray(texsurf^.pixels)^[i]:= (RMask or GMask or BMask) and Color;
if SDL_MustLock(texsurf) then
SDL_UnlockSurface(texsurf);
@@ -358,8 +361,9 @@
if TeamsArray[t] <> nil then
with TeamsArray[t]^ do
begin
- if GraveName = '' then GraveName:= 'Simple';
- texsurf:= LoadImage(Pathz[ptGraves] + '/' + GraveName, ifCritical or ifTransparent);
+ if GraveName = '' then GraveName:= 'Statue';
+ texsurf:= LoadImage(Pathz[ptGraves] + '/' + GraveName, ifTransparent);
+ if texsurf = nil then texsurf:= LoadImage(Pathz[ptGraves] + '/Statue', ifCritical or ifTransparent);
GraveTex:= Surface2Tex(texsurf, false);
SDL_FreeSurface(texsurf)
end
@@ -407,30 +411,29 @@
if tmpsurf <> nil then
begin
if getImageDimensions then
- begin
+ begin
imageWidth:= tmpsurf^.w;
imageHeight:= tmpsurf^.h
- end;
+ end;
if getDimensions then
- begin
+ begin
Width:= tmpsurf^.w;
Height:= tmpsurf^.h
- end;
+ end;
if (ii in [sprSky, sprSkyL, sprSkyR, sprHorizont, sprHorizontL, sprHorizontR]) then
- begin
+ begin
Texture:= Surface2Tex(tmpsurf, true);
Texture^.Scale:= 2
- end
+ end
else
- begin
+ begin
Texture:= Surface2Tex(tmpsurf, false);
if (ii = sprWater) and ((cReducedQuality and (rq2DWater or rqClampLess)) = 0) then // HACK: We should include some sprite attribute to define the texture wrap directions
- begin
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- end;
end;
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, priority);
- if saveSurf then Surface:= tmpsurf else SDL_FreeSurface(tmpsurf)
+ if saveSurf then
+ Surface:= tmpsurf else SDL_FreeSurface(tmpsurf)
end
else
Surface:= nil
@@ -444,6 +447,7 @@
InitHealth;
+// TODO: are those textures ever freed?
PauseTexture:= RenderStringTex(trmsg[sidPaused], cYellowColor, fntBig);
ConfirmTexture:= RenderStringTex(trmsg[sidConfirm], cYellowColor, fntBig);
SyncTexture:= RenderStringTex(trmsg[sidSync], cYellowColor, fntBig);
@@ -453,29 +457,24 @@
// name of weapons in ammo menu
for ai:= Low(TAmmoType) to High(TAmmoType) do
with Ammoz[ai] do
- begin
+ begin
TryDo(trAmmo[NameId] <> '','No default text/translation found for ammo type #' + intToStr(ord(ai)) + '!',true);
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(trAmmo[NameId],fnt16)].Handle, Str2PChar(trAmmo[NameId]), cWhiteColorChannels);
TryDo(tmpsurf <> nil,'Name-texture creation for ammo type #' + intToStr(ord(ai)) + ' failed!',true);
tmpsurf:= doSurfaceConversion(tmpsurf);
NameTex:= Surface2Tex(tmpsurf, false);
SDL_FreeSurface(tmpsurf)
- end;
+ end;
// number of weapons in ammo menu
for i:= Low(CountTexz) to High(CountTexz) do
- begin
+begin
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i) + 'x'), cWhiteColorChannels);
tmpsurf:= doSurfaceConversion(tmpsurf);
CountTexz[i]:= Surface2Tex(tmpsurf, false);
SDL_FreeSurface(tmpsurf)
- end;
+end;
-{$IFDEF DUMP}
-//not working anymore, where are LandSurface and StoreSurface defined?
-//SDL_SaveBMP_RW(LandSurface, SDL_RWFromFile('LandSurface.bmp', 'wb'), 1);
-//SDL_SaveBMP_RW(StoreSurface, SDL_RWFromFile('StoreSurface.bmp', 'wb'), 1);
-{$ENDIF}
AddProgress;
{$IFDEF SDL_IMAGE_NEWER}
@@ -494,6 +493,13 @@
VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
begin
if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then exit;
+
+// don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
+if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then
+ exit;
+if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then
+ exit;
+
rr.x:= X;
rr.y:= Y;
rr.w:= W;
@@ -532,6 +538,7 @@
procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
begin
+
glPushMatrix;
glTranslatef(X, Y, 0);
glScalef(Scale, Scale, 1);
@@ -555,6 +562,12 @@
hw, nx, ny: LongInt;
VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
begin
+// don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
+if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then
+ exit;
+if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then
+ exit;
+
glPushMatrix;
glTranslatef(X, Y, 0);
@@ -636,6 +649,12 @@
procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
var VertexBuffer: array [0..3] of TVertex2f;
begin
+// don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
+if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then
+ exit;
+if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then
+ exit;
+
glPushMatrix;
glTranslatef(X, Y, 0);
@@ -716,8 +735,13 @@
end;
procedure DrawCentered(X, Top: LongInt; Source: PTexture);
+var scale: GLfloat;
begin
-DrawTexture(X - Source^.w shr 1, Top, Source)
+ if (Source^.w + 20) > cScreenWidth then
+ scale:= cScreenWidth / (Source^.w + 20)
+ else
+ scale:= 1.0;
+ DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale)
end;
procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real);
@@ -729,6 +753,11 @@
var l, r, t, b: real;
TextureBuffer: array [0..3] of TVertex2f;
begin
+// don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
+if (abs(X) > 32) and ((abs(X) - 16) * cScaleFactor > cScreenWidth) then
+ exit;
+if (abs(Y) > 32) and ((abs(Y - 0.5 * cScreenHeight) - 16) * cScaleFactor > cScreenHeight) then
+ exit;
t:= Pos * 32 / HHTexture^.h;
b:= (Pos + 1) * 32 / HHTexture^.h;
@@ -769,6 +798,12 @@
procedure DrawFillRect(r: TSDL_Rect);
var VertexBuffer: array [0..3] of TVertex2f;
begin
+// don't draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
+if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then
+ exit;
+if (abs(r.y) > r.h) and ((abs(r.y + r.h / 2 - (0.5 * cScreenHeight)) - r.h / 2) * cScaleFactor > cScreenHeight) then
+ exit;
+
glDisable(GL_TEXTURE_2D);
Tint($00, $00, $00, $80);
@@ -789,6 +824,29 @@
glEnable(GL_TEXTURE_2D)
end;
+procedure DrawCircle(X, Y, Radius: LongInt; Width: Single; r, g, b, a: Byte);
+var
+ i: LongInt;
+ CircleVertex: array [0..359] of TVertex2f;
+begin
+ for i := 0 to 359 do begin
+ CircleVertex[i].X := X + Radius*cos(i*pi/180);
+ CircleVertex[i].Y := Y + Radius*sin(i*pi/180);
+ end;
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_LINE_SMOOTH);
+ glPushMatrix;
+ glTranslatef(WorldDx, WorldDy, 0);
+ glLineWidth(Width);
+ Tint(r, g, b, a);
+ glVertexPointer(2, GL_FLOAT, 0, @CircleVertex[0]);
+ glDrawArrays(GL_LINE_LOOP, 0, 360);
+ Tint($FF, $FF, $FF, $FF);
+ glPopMatrix;
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_LINE_SMOOTH);
+end;
+
procedure StoreRelease;
var ii: TSprite;
begin
@@ -820,7 +878,12 @@
u: WideChar;
tmpstr: array[0..256] of WideChar;
begin
-if (font >= CJKfnt16) or (length(s) = 0) then exit(font);
+
+{$IFNDEF IPHONEOS}
+// remove chinese fonts for now
+if (font >= CJKfnt16) or (length(s) = 0) then
+{$ENDIF}
+ exit(font);
l:= Utf8ToUnicode(@tmpstr, Str2PChar(s), length(s))-1;
i:= 0;
@@ -1064,20 +1127,7 @@
var tmpsurf: PSDL_Surface;
s: shortstring;
begin
- WriteToConsole(msgLoading + filename + '.png (flags: ' + inttostr(imageFlags)+') ');
-{$IFDEF DEBUGFILE}
- WriteToConsole('[flag translation:');
- if imageFlags = ifNone then
- WriteToConsole(' None')
- else
- begin
- if (imageFlags and ifAlpha) <> 0 then WriteToConsole(' Alpha');
- if (imageFlags and ifCritical) <> 0 then WriteToConsole(' Critical');
- if (imageFlags and ifTransparent) <> 0 then WriteToConsole(' Transparent');
- if (imageFlags and ifIgnoreCaps) <> 0 then WriteToConsole(' IgnoreCaps');
- end;
- WriteToConsole('] ');
-{$ENDIF}
+ WriteToConsole(msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + ']');
s:= filename + '.png';
tmpsurf:= IMG_Load(Str2PChar(s));
@@ -1093,7 +1143,7 @@
SDL_FreeSurface(tmpsurf);
OutError(msgFailedSize, (imageFlags and ifCritical) <> 0);
// dummy surface to replace non-critical textures that failed to load due to their size
- exit(SDL_CreateRGBSurface(SDL_SWSURFACE, 32, 32, 32, RMask, GMask, BMask, AMask));
+ exit(SDL_CreateRGBSurface(SDL_SWSURFACE, 2, 2, 32, RMask, GMask, BMask, AMask));
end;
tmpsurf:= doSurfaceConversion(tmpsurf);
@@ -1109,6 +1159,7 @@
function glLoadExtension(extension : shortstring) : boolean;
begin
{$IFDEF IPHONEOS}
+ extension:= extension; // avoid hint
glLoadExtension:= false;
{$IFDEF DEBUGFILE}
AddFileLog('OpenGL - "' + extension + '" skipped')
@@ -1125,23 +1176,20 @@
end;
procedure SetupOpenGL;
+{$IFNDEF IPHONEOS}
var vendor: shortstring;
{$IFDEF DARWIN}
one: LongInt;
{$ENDIF}
+{$ENDIF}
begin
- // initialized here because when initModule is called cScreenWidth/Height are not yet set
- if (uStore.wScreen = 0) and (uStore.hScreen = 0) then
- begin
- uStore.wScreen:= cScreenWidth;
- uStore.hScreen:= cScreenHeight;
- end;
{$IFDEF IPHONEOS}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); // no double buffering
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1);
{$ELSE}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ vendor:= LowerCase(shortstring(pchar(glGetString(GL_VENDOR))));
{$IFNDEF SDL13}
// this attribute is default in 1.3 and must be enabled in MacOSX
if (cReducedQuality and rqDesyncVBlank) <> 0 then
@@ -1165,10 +1213,9 @@
glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize);
- vendor:= LowerCase(shortstring(pchar(glGetString(GL_VENDOR))));
{$IFDEF DEBUGFILE}
AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER))));
- AddFileLog(' |----- Vendor: ' + vendor);
+ AddFileLog(' |----- Vendor: ' + shortstring(pchar(glGetString(GL_VENDOR))));
AddFileLog(' |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION))));
AddFileLog(' \----- GL_MAX_TEXTURE_SIZE: ' + inttostr(MaxTextureSize));
{$ENDIF}
@@ -1239,11 +1286,10 @@
{$ENDIF}
// set view port to whole window
-{$IFDEF IPHONEOS}
- glViewport(0, 0, cScreenHeight, cScreenWidth);
-{$ELSE}
- glViewport(0, 0, cScreenWidth, cScreenHeight);
-{$ENDIF}
+ if (rotationQt = 0) or (rotationQt = 180) then
+ glViewport(0, 0, cScreenWidth, cScreenHeight)
+ else
+ glViewport(0, 0, cScreenHeight, cScreenWidth);
glMatrixMode(GL_MODELVIEW);
// prepare default translation/scaling
@@ -1261,8 +1307,8 @@
glDisable(GL_DITHER);
// enable common states by default as they save a lot
glEnable(GL_TEXTURE_2D);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
end;
procedure SetScale(f: GLfloat);
@@ -1277,7 +1323,7 @@
glPushMatrix; // save default scaling
glLoadIdentity;
glRotatef(rotationQt, 0, 0, 1);
- glScalef(f / wScreen, -f / hScreen, 1.0);
+ glScalef(f / cScreenWidth, -f / cScreenHeight, 1.0);
glTranslatef(0, -cScreenHeight / 2, 0);
end;
@@ -1295,13 +1341,12 @@
texsurf:= LoadImage(Pathz[ptGraphics] + '/Progress', ifCritical or ifTransparent);
ProgrTex:= Surface2Tex(texsurf, false);
-
+
squaresize:= texsurf^.w shr 1;
numsquares:= texsurf^.h div squaresize;
SDL_FreeSurface(texsurf);
-{$IFDEF IPHONEOS}
- startSpinning();
-{$ENDIF}
+
+ perfExt_AddProgress();
end;
TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true);
@@ -1309,12 +1354,12 @@
glClear(GL_COLOR_BUFFER_BIT);
if Step < numsquares then r.x:= 0
else r.x:= squaresize;
-
+
r.y:= (Step mod numsquares) * squaresize;
r.w:= squaresize;
r.h:= squaresize;
-
- DrawFromRect( -squaresize div 2, (hScreen - squaresize) shr 1, @r, ProgrTex);
+
+ DrawFromRect( -squaresize div 2, (cScreenHeight - squaresize) shr 1, @r, ProgrTex);
SDL_GL_SwapBuffers();
{$IFDEF SDL13}
@@ -1328,9 +1373,7 @@
begin
WriteLnToConsole('Freeing progress surface... ');
FreeTexture(ProgrTex);
-{$IFDEF IPHONEOS}
- stopSpinning();
-{$ENDIF}
+ perfExt_FinishProgress();
end;
procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean);
@@ -1468,7 +1511,7 @@
if w < (i + wa) then w:= i + wa;
inc(h, j + ha);
end;
-
+
// add borders space
inc(w, wa);
inc(h, ha + 8);
@@ -1498,7 +1541,7 @@
if tmpline <> '' then
begin
r:= WriteInRect(tmpsurf, FontBorder + 2, r.y + r.h, $ff707070, font, tmpline);
-
+
// render highlighted caption (if there's a ':')
tmpline2:= '';
SplitByChar(tmpline, tmpline2, ':');
@@ -1516,7 +1559,7 @@
r.h:= 32;
SDL_FillRect(tmpsurf, @r, $ffffffff);
SDL_UpperBlit(iconsurf, iconrect, tmpsurf, @r);
-
+
RenderHelpWindow:= Surface2Tex(tmpsurf, true);
SDL_FreeSurface(tmpsurf)
end;
@@ -1539,8 +1582,8 @@
// image region
i:= LongInt(atype) - 1;
-r.x:= (i shr 5) * 32;
-r.y:= (i mod 32) * 32;
+r.x:= (i shr 4) * 32;
+r.y:= (i mod 16) * 32;
r.w:= 32;
r.h:= 32;
@@ -1558,7 +1601,7 @@
extra:= trmsg[sidNoEndTurn];
extracolor:= LongInt($ff70c770);
end
-else
+else
begin
extra:= '';
extracolor:= 0;
@@ -1588,16 +1631,12 @@
begin
PixelFormat:= nil;
SDLPrimSurface:= nil;
-{$IFDEF IPHONEOS}
- rotationQt:= -90;
-{$ELSE}
+
+{$IFNDEF IPHONEOS}
rotationQt:= 0;
cGPUVendor:= gvUnknown;
{$ENDIF}
- // really initalized in storeLoad
- uStore.wScreen:= 0;
- uStore.hScreen:= 0;
-
+
cScaleFactor:= 2.0;
SupportNPOTT:= false;
Step:= 0;