hedgewars/uMisc.pas
branchsdl2transition
changeset 11362 ed5a6478e710
parent 11360 7a7611adf715
parent 11046 47a8c19ecb60
child 11367 a91c4c4fd85c
equal deleted inserted replaced
11361:31570b766315 11362:ed5a6478e710
     1 (*
     1 (*
     2  * Hedgewars, a free turn based strategy game
     2  * Hedgewars, a free turn based strategy game
     3  * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
     3  * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     8  *
     8  *
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    12  * GNU General Public License for more details.
    13  *
    13  *
    14  * You should have received a copy of the GNU General Public License
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    17  *)
    17  *)
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uMisc;
    21 unit uMisc;
    26 procedure initModule;
    26 procedure initModule;
    27 procedure freeModule;
    27 procedure freeModule;
    28 
    28 
    29 procedure movecursor(dx, dy: LongInt);
    29 procedure movecursor(dx, dy: LongInt);
    30 function  doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface;
    30 function  doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface;
    31 function  MakeScreenshot(filename: shortstring; k: LongInt): boolean;
    31 function MakeScreenshot(filename: shortstring; k: LongInt; dump: LongWord): boolean;
    32 function  GetTeamStatString(p: PTeam): shortstring;
    32 function  GetTeamStatString(p: PTeam): shortstring;
    33 function  SDL_RectMake(x, y, width, height: LongInt): TSDL_Rect; inline;
    33 function  SDL_RectMake(x, y, width, height: LongInt): TSDL_Rect; inline;
    34 
    34 
    35 implementation
    35 implementation
    36 uses SysUtils, uVariables, uUtils
    36 uses SysUtils, uVariables, uUtils
    42          filename: shortstring;
    42          filename: shortstring;
    43          width, height: LongInt;
    43          width, height: LongInt;
    44          size: QWord;
    44          size: QWord;
    45          end;
    45          end;
    46 
    46 
    47 var conversionFormat: PSDL_PixelFormat;
    47 var conversionFormat : PSDL_PixelFormat;
    48 
    48 
    49 procedure movecursor(dx, dy: LongInt);
    49 procedure movecursor(dx, dy: LongInt);
    50 var x, y: LongInt;
    50 var x, y: LongInt;
    51 begin
    51 begin
    52 if (dx = 0) and (dy = 0) then exit;
    52 if (dx = 0) and (dy = 0) then exit;
    61 // this funtion will be executed in separate thread
    61 // this funtion will be executed in separate thread
    62 function SaveScreenshot(screenshot: pointer): LongInt; cdecl; export;
    62 function SaveScreenshot(screenshot: pointer): LongInt; cdecl; export;
    63 var i: LongInt;
    63 var i: LongInt;
    64     png_ptr: ^png_struct;
    64     png_ptr: ^png_struct;
    65     info_ptr: ^png_info;
    65     info_ptr: ^png_info;
    66     f: file;
    66     f: File;
    67     image: PScreenshot;
    67     image: PScreenshot;
    68 begin
    68 begin
    69 image:= PScreenshot(screenshot);
    69 image:= PScreenshot(screenshot);
    70 
    70 
    71 png_ptr := png_create_write_struct(png_get_libpng_ver(nil), nil, nil, nil);
    71 png_ptr := png_create_write_struct(png_get_libpng_ver(nil), nil, nil, nil);
   134     0, 0, 0, 0,     // number of colors (all)
   134     0, 0, 0, 0,     // number of colors (all)
   135     0, 0, 0, 0      // number of important colors
   135     0, 0, 0, 0      // number of important colors
   136     );
   136     );
   137     image: PScreenshot;
   137     image: PScreenshot;
   138     size: QWord;
   138     size: QWord;
       
   139     writeResult:LongInt;
   139 begin
   140 begin
   140 image:= PScreenshot(screenshot);
   141 image:= PScreenshot(screenshot);
   141 
   142 
   142 size:= image^.Width*image^.Height*4;
   143 size:= image^.Width*image^.Height*4;
   143 
   144 
   161 {$IOCHECKS OFF}
   162 {$IOCHECKS OFF}
   162 Assign(f, image^.filename);
   163 Assign(f, image^.filename);
   163 Rewrite(f, 1);
   164 Rewrite(f, 1);
   164 if IOResult = 0 then
   165 if IOResult = 0 then
   165     begin
   166     begin
   166     BlockWrite(f, head, sizeof(head));
   167     BlockWrite(f, head, sizeof(head), writeResult);
   167     BlockWrite(f, image^.buffer^, size);
   168     BlockWrite(f, image^.buffer^, size, writeResult);
   168     Close(f);
   169     Close(f);
   169     end
   170     end
   170 else
   171 else
   171     begin
   172     begin
   172     //AddFileLog('Error: Could not write to ' + filename);
   173     //AddFileLog('Error: Could not write to ' + filename);
   214 end;
   215 end;
   215 {$ENDIF}
   216 {$ENDIF}
   216 
   217 
   217 // captures and saves the screen. returns true on success.
   218 // captures and saves the screen. returns true on success.
   218 // saved image will be k times smaller than original (useful for saving thumbnails).
   219 // saved image will be k times smaller than original (useful for saving thumbnails).
   219 function MakeScreenshot(filename: shortstring; k: LongInt): Boolean;
   220 function MakeScreenshot(filename: shortstring; k: LongInt; dump: LongWord): boolean;
   220 var p: Pointer;
   221 var p: Pointer;
   221     size: QWord;
   222     size: QWord;
   222     image: PScreenshot;
   223     image: PScreenshot;
   223     format: GLenum;
   224     format: GLenum;
   224     ext: string[4];
   225     ext: string[4];
       
   226     x,y: LongWord;
   225 begin
   227 begin
   226 {$IFDEF PNG_SCREENSHOTS}
   228 {$IFDEF PNG_SCREENSHOTS}
   227 format:= GL_RGBA;
   229 format:= GL_RGBA;
   228 ext:= '.png';
   230 ext:= '.png';
   229 {$ELSE}
   231 {$ELSE}
   230 format:= GL_BGRA;
   232 format:= GL_BGRA;
   231 ext:= '.bmp';
   233 ext:= '.bmp';
   232 {$ENDIF}
   234 {$ENDIF}
   233 
   235 
   234 size:= toPowerOf2(cScreenWidth) * toPowerOf2(cScreenHeight) * 4;
   236 if dump > 0 then
       
   237      size:= LAND_WIDTH*LAND_HEIGHT*4
       
   238 else size:= toPowerOf2(cScreenWidth) * toPowerOf2(cScreenHeight) * 4;
   235 p:= GetMem(size); // will be freed in SaveScreenshot()
   239 p:= GetMem(size); // will be freed in SaveScreenshot()
   236 
   240 
   237 // memory could not be allocated
   241 // memory could not be allocated
   238 if p = nil then
   242 if p = nil then
   239 begin
   243 begin
   240     AddFileLog('Error: Could not allocate memory for screenshot.');
   244     AddFileLog('Error: Could not allocate memory for screenshot.');
   241     MakeScreenshot:= false;
   245     MakeScreenshot:= false;
   242     exit;
   246     exit;
   243 end;
   247 end;
   244 
   248 
       
   249 // read pixels from land array
       
   250 if dump > 0 then
       
   251     begin
       
   252     for y:= 0 to LAND_HEIGHT-1 do
       
   253         for x:= 0 to LAND_WIDTH-1 do
       
   254             if dump = 2 then
       
   255                 PLongWordArray(p)^[y*LAND_WIDTH+x]:= LandPixels[LAND_HEIGHT-1-y, x]
       
   256             else
       
   257                 begin
       
   258                 if Land[LAND_HEIGHT-1-y, x] and lfIndestructible = lfIndestructible then
       
   259                     PLongWordArray(p)^[y*LAND_WIDTH+x]:= (AMask or RMask)
       
   260                 else if Land[LAND_HEIGHT-1-y, x] and lfIce = lfIce then
       
   261                     PLongWordArray(p)^[y*LAND_WIDTH+x]:= (AMask or BMask)
       
   262                 else if Land[LAND_HEIGHT-1-y, x] and lfBouncy = lfBouncy then
       
   263                     PLongWordArray(p)^[y*LAND_WIDTH+x]:= (AMask or GMask)
       
   264                 else if Land[LAND_HEIGHT-1-y, x] and lfObject = lfObject then
       
   265                     PLongWordArray(p)^[y*LAND_WIDTH+x]:= $FFFFFFFF
       
   266                 else if Land[LAND_HEIGHT-1-y, x] and lfBasic = lfBasic then
       
   267                     PLongWordArray(p)^[y*LAND_WIDTH+x]:= AMask
       
   268                 else
       
   269                     PLongWordArray(p)^[y*LAND_WIDTH+x]:= 0
       
   270                 end
       
   271     end
       
   272 else
   245 // read pixels from the front buffer
   273 // read pixels from the front buffer
   246 glReadPixels(0, 0, cScreenWidth, cScreenHeight, format, GL_UNSIGNED_BYTE, p);
   274     begin
   247 
   275     glReadPixels(0, 0, cScreenWidth, cScreenHeight, format, GL_UNSIGNED_BYTE, p);
   248 {$IFDEF USE_VIDEO_RECORDING}
   276 {$IFDEF USE_VIDEO_RECORDING}
   249 ReduceImage(p, cScreenWidth, cScreenHeight, k);
   277     ReduceImage(p, cScreenWidth, cScreenHeight, k)
   250 {$ENDIF}
   278 {$ENDIF}
       
   279     end;
   251 
   280 
   252 // allocate and fill structure that will be passed to new thread
   281 // allocate and fill structure that will be passed to new thread
   253 New(image); // will be disposed in SaveScreenshot()
   282 New(image); // will be disposed in SaveScreenshot()
   254 image^.filename:= UserPathPrefix + filename + ext;
   283 if dump = 2 then
   255 image^.width:= cScreenWidth div k;
   284      image^.filename:= shortstring(UserPathPrefix) + filename + '_landpixels' + ext
   256 image^.height:= cScreenHeight div k;
   285 else if dump = 1 then
       
   286      image^.filename:= shortstring(UserPathPrefix) + filename + '_land' + ext
       
   287 else image^.filename:= shortstring(UserPathPrefix) + filename + ext;
       
   288 
       
   289 if dump <> 0 then
       
   290     begin
       
   291     image^.width:= LAND_WIDTH;
       
   292     image^.height:= LAND_HEIGHT
       
   293     end
       
   294 else
       
   295     begin
       
   296     image^.width:= cScreenWidth div k;
       
   297     image^.height:= cScreenHeight div k
       
   298     end;
   257 image^.size:= size;
   299 image^.size:= size;
   258 image^.buffer:= p;
   300 image^.buffer:= p;
   259 
   301 
   260 SDL_CreateThread(@SaveScreenshot, 'snapshot', image);
   302 SDL_CreateThread(@SaveScreenshot, 'snapshot', image);
   261 MakeScreenshot:= true; // possibly it is not true but we will not wait for thread to terminate
   303 MakeScreenshot:= true; // possibly it is not true but we will not wait for thread to terminate
   282     SDL_RectMake.w:= width;
   324     SDL_RectMake.w:= width;
   283     SDL_RectMake.h:= height;
   325     SDL_RectMake.h:= height;
   284 end;
   326 end;
   285 
   327 
   286 function GetTeamStatString(p: PTeam): shortstring;
   328 function GetTeamStatString(p: PTeam): shortstring;
   287 var s: ansistring;
   329 var s: shortstring;
   288 begin
   330 begin
   289     s:= p^.TeamName + ':' + IntToStr(p^.TeamHealth) + ':';
   331     s:= p^.TeamName + ':' + IntToStr(p^.TeamHealth) + ':';
   290     GetTeamStatString:= s;
   332     GetTeamStatString:= s;
   291 end;
   333 end;
   292 
   334