Explorar el Código

[Android]added tex_Restore*, font_RestoreFromFile, rtarget_Restore, emitter2d_RestoreAll and video_Restore functions; [Android]implemented restoring of resources for all demos

git-svn-id: http://zengl.googlecode.com/svn/branches/0.3.x@1921 6573c10b-8653-0410-9706-d32479e959fb
dr.andru hace 13 años
padre
commit
24e8eeff32

+ 9 - 0
demos/Android/01 - Initialization/jni/demo01.lpr

@@ -40,6 +40,12 @@ begin
   //
 end;
 
+procedure Restore;
+begin
+  // RU: Восстановление ресурсов нужно реализовывать тут.
+  // EN: Restoring of resources should be implemented here.
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   // RU: Для загрузки/создания каких-то своих настроек/профилей/etc. можно получить путь к домашенему каталогу пользователя, или к исполняемому файлу(не работает для GNU/Linux).
@@ -62,6 +68,9 @@ begin
   // RU: Регистрируем процедуру, которая будет принимать разницу времени между кадрами.
   // EN: Register the procedure, that will get delta time between the frames.
   zgl_Reg( SYS_UPDATE, @Update );
+  // RU: Очень важная для Android функция, которая вызывается при возврате фокуса приложению если необходимо восстановить ресурсы.
+  // EN: Very important function for Android, which will be called every time when application gets the focus and resources need to restore.
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   // RU: Указываем первоначальные настройки.
   // EN: Set screen options.

+ 45 - 4
demos/Android/02 - Resources/jni/demo02.lpr

@@ -47,7 +47,7 @@ var
   fntMain  : zglPFont;
   //
   texLogo  : zglPTexture;
-  texTest  : zglPTexture;
+  texTest  : array[ 0..3 ] of zglPTexture;
   //
   sndClick : zglPSound;
   sndMusic : zglPSound;
@@ -69,7 +69,7 @@ begin
   // RU: Более детальное рассмотрение параметров функций загрузки ресурсов есть в соответствующих примерах, тут же показана лишь основная суть.
   // EN: Description with more details about parameters of functions can be found in other demos, here is only main idea shown.
 
-  //snd_Init();
+  snd_Init();
 
   // RU: Основное отличие приложений Android от других заключается в том, что все ресурсы хранятся зачастую хранятся внутри apk-файла(обычный zip-архив).
   //     Поэтому перед загрузкой любых ресурсов необходимо сначала "открыть" этот apk-файл, а потом "закрыть".
@@ -99,7 +99,7 @@ begin
   //     Just for holding loading screen resources will be loaded multiple times, and texture will be post-processed with delay.
   zgl_Reg( TEX_CURRENT_EFFECT, @TextureCalcEffect );
   for i := 0 to 3 do
-      texTest  := tex_LoadFromFile( dirRes + 'back01.jpg', TEX_NO_COLORKEY, TEX_DEFAULT_2D or TEX_CUSTOM_EFFECT );
+    texTest[ i ]  := tex_LoadFromFile( dirRes + 'back01.jpg', TEX_NO_COLORKEY, TEX_DEFAULT_2D or TEX_CUSTOM_EFFECT );
   file_CloseArchive();
   res_EndQueue();
 end;
@@ -115,15 +115,56 @@ begin
       exit;
     end;
 
-  ssprite2d_Draw( texTest, 0, 0, 800, 600, 0 );
+  ssprite2d_Draw( texTest[ 0 ], 0, 0, 800, 600, 0 );
   text_Draw( fntMain, 0, 0, 'FPS: ' + u_IntToStr( zgl_Get( RENDER_FPS ) ) );
   text_Draw( fntMain, 0, 16, 'VRAM Used: ' + u_FloatToStr( zgl_Get( RENDER_VRAM_USED ) / 1024 / 1024 ) + 'Mb' );
 end;
 
+procedure Activate( active : Boolean );
+begin
+  // RU: Из-за проблемы в OpenAL на платформе Android(в фоном режиме приложение продолжает грузить CPU), звуковую подсистему
+  //     необходимо останавливать и перезапускать, но только при потере/получении фокуса приложением.
+  // EN: Because of problem inside OpenAL on Android(application continue load CPU in background), sound susbsytem should be
+  //     stopped and reloaded when application loses/gets the focus.
+
+  if active Then
+    begin
+      // RU: Перезапускаем звуковую подсистему.
+      // EN: Reload sound subsystem.
+      snd_Init();
+
+      file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+      sndClick := snd_LoadFromFile( dirRes + 'click.wav' );
+      file_CloseArchive();
+    end else
+      snd_Free();
+end;
+
+procedure Restore;
+  var
+    i : Integer;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+  tex_RestoreFromFile( texLogo, dirRes + 'zengl.png' );
+
+  file_CloseArchive();
+
+  res_BeginQueue( 0 );
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+  for i := 0 to 3 do
+    tex_RestoreFromFile( texTest[ i ], dirRes + 'back01.jpg' );
+  file_CloseArchive();
+  res_EndQueue();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ACTIVATE, @Activate );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );
 end;

+ 8 - 0
demos/Android/03 - Input/jni/demo03.lpr

@@ -103,12 +103,20 @@ begin
   key_ClearState();
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+  file_CloseArchive();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   timer_Add( @Timer, 16 );
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );
 end;

+ 9 - 0
demos/Android/04 - Screen Settings/jni/demo04.lpr

@@ -94,12 +94,21 @@ begin
   touch_ClearState();
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+  tex_RestoreFromFile( texBack, dirRes + 'back03.jpg' );
+  file_CloseArchive();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   timer_Add( @Timer, 16 );
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );
 end;

+ 11 - 0
demos/Android/06 - Text/jni/demo06.lpr

@@ -51,6 +51,9 @@ procedure Draw;
 begin
   batch2d_Begin();
 
+  // RU: ZenGL работает исключительно с кодировкой UTF-8, поэтому весь текст должен быть в UTF-8.
+  // EN: ZenGL works only with UTF-8 encoding, so all text should be encoded with UTF-8.
+
   text_Draw( fntMain, 400, 25, 'String with center alignment', TEXT_HALIGN_CENTER );
 
   text_DrawEx( fntMain, 400, 65, 2, 0, 'Scaling', 255, $FFFFFF, TEXT_HALIGN_CENTER );
@@ -96,12 +99,20 @@ begin
   batch2d_End();
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+  file_CloseArchive();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   randomize();
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );
 end;

+ 18 - 0
demos/Android/07 - Sprites/jni/demo07.lpr

@@ -239,6 +239,23 @@ begin
     end;
 end;
 
+procedure Restore;
+  var
+    i : Integer;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  tex_RestoreFromFile( texLogo, dirRes + 'zengl.png' );
+  tex_RestoreFromFile( texBack, dirRes + 'back01.jpg' );
+  tex_RestoreFromFile( texGround, dirRes + 'ground.png' );
+  tex_RestoreFromFile( texTuxWalk, dirRes + 'tux_walking.png' );
+  tex_RestoreFromFile( texTuxStand, dirRes + 'tux_stand.png' );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+
+  file_CloseArchive();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   randomize();
@@ -247,6 +264,7 @@ begin
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );
 end;

+ 13 - 0
demos/Android/08 - Sprite Engine/jni/demo08.lpr

@@ -196,6 +196,18 @@ begin
   touch_ClearState();
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  tex_RestoreFromFile( texLogo, dirRes + 'zengl.png' );
+  tex_RestoreFromFile( texMiku, dirRes + 'miku.png' );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+
+  file_CloseArchive();
+end;
+
 procedure Quit;
 begin
   // RU: Очищаем память от созданных спрайтов.
@@ -213,6 +225,7 @@ begin
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
   zgl_Reg( SYS_EXIT, @Quit );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );

+ 13 - 0
demos/Android/09 - Sprite Engine(Classes)/jni/demo09.lpr

@@ -201,6 +201,18 @@ begin
   touch_ClearState();
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  tex_RestoreFromFile( texLogo, dirRes + 'zengl.png' );
+  tex_RestoreFromFile( texMiku, dirRes + 'miku.png' );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+
+  file_CloseArchive();
+end;
+
 procedure Quit;
 begin
   // RU: Очищаем память от созданных спрайтов.
@@ -217,6 +229,7 @@ begin
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
   zgl_Reg( SYS_EXIT, @Quit );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );

+ 12 - 0
demos/Android/10 - Tiles/jni/demo10.lpr

@@ -76,12 +76,24 @@ begin
   text_Draw( fntMain, 180, 30, 'This is a tarrible example of tile map, but main idea should be clear :)' );
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+
+  tex_RestoreFromFile( texTiles, dirRes + 'tiles.png' );
+
+  file_CloseArchive();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   randomize();
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FALSE, FALSE );
 end;

+ 12 - 0
demos/Android/11 - Grid/jni/demo11.lpr

@@ -90,6 +90,17 @@ begin
       end;
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  tex_RestoreFromFile( texBack, dirRes + 'back04.jpg' );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+
+  file_CloseArchive();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   randomize();
@@ -98,6 +109,7 @@ begin
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FALSE, FALSE );
 end;

+ 15 - 0
demos/Android/12 - Render into Texture/jni/demo12.lpr

@@ -77,12 +77,27 @@ begin
   text_Draw( fntMain, 0, 0, 'FPS: ' + u_IntToStr( zgl_Get( RENDER_FPS ) ) );
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  tex_RestoreFromFile( texTux, dirRes + 'tux_stand.png' );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+
+  rtarget_Restore( rtFull );
+  rtarget_Restore( rtDefault );
+
+  file_CloseArchive();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   randomize();
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );
 end;

+ 16 - 0
demos/Android/13 - Particles/jni/demo13.lpr

@@ -116,6 +116,21 @@ begin
   pengine2d_Proc( dt );
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  tex_RestoreFromFile( texBack, dirRes + 'back02.png' );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+
+  // RU: Использовать данную функцию возможно только если все эмиттеры были загружены посредством emitter2d_LoadFromFile и текстуры не были подгружены вручную.
+  // EN: You can use this method only if emitters were loaded via emitter2d_LoadFromFile without manual loading of textures.
+  emitter2d_RestoreAll();
+
+  file_CloseArchive();
+end;
+
 procedure Quit;
 begin
   // RU: Очищаем память от созданных эмиттеров.
@@ -133,6 +148,7 @@ begin
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
   zgl_Reg( SYS_UPDATE, @Update );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
   zgl_Reg( SYS_EXIT, @Quit );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );

+ 26 - 0
demos/Android/14 - Sound/jni/demo14.lpr

@@ -144,6 +144,31 @@ begin
   touch_ClearState();
 end;
 
+procedure Activate( active : Boolean );
+begin
+  if active Then
+    begin
+      snd_Init();
+
+      file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+      sound := snd_LoadFromFile( dirRes + 'click.wav', 2 );
+      file_CloseArchive();
+    end else
+      snd_Free();
+end;
+
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+
+  tex_RestoreFromFile( icon[ 0 ], dirRes + 'audio-stop.png' );
+  tex_RestoreFromFile( icon[ 1 ], dirRes + 'audio-play.png' );
+
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+
+  file_CloseArchive();
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   randomize();
@@ -152,6 +177,7 @@ begin
 
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( SCREEN_WIDTH, SCREEN_HEIGHT, REFRESH_MAXIMUM, TRUE, TRUE );
 end;

+ 10 - 0
demos/Android/15 - Video/jni/demo15.lpr

@@ -88,6 +88,15 @@ begin
     video_Update( video, dt, TRUE );
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+  file_CloseArchive();
+
+  video_Restore( video );
+end;
+
 procedure Java_zengl_android_ZenGL_Main( var env; var thiz ); cdecl;
 begin
   randomize();
@@ -97,6 +106,7 @@ begin
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
   zgl_Reg( SYS_UPDATE, @Update );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );
 end;

+ 8 - 0
demos/Android/16 - Physics/jni/demo16.lpr

@@ -201,6 +201,13 @@ begin
   cpSpaceStep( space, 1 / ( 1000 / dt ) );
 end;
 
+procedure Restore;
+begin
+  file_OpenArchive( PAnsiChar( zgl_Get( DIRECTORY_APPLICATION ) ) );
+  font_RestoreFromFile( fntMain, dirRes + 'font.zfi' );
+  file_CloseArchive();
+end;
+
 procedure Quit;
 begin
   // RU: Очистка объектов и "мира".
@@ -218,6 +225,7 @@ begin
   zgl_Reg( SYS_LOAD, @Init );
   zgl_Reg( SYS_DRAW, @Draw );
   zgl_Reg( SYS_UPDATE, @Update );
+  zgl_Reg( SYS_ANDROID_RESTORE, @Restore );
   zgl_Reg( SYS_EXIT, @Quit );
 
   scr_SetOptions( 800, 600, REFRESH_MAXIMUM, TRUE, TRUE );

+ 47 - 0
demos/GCC/10 - Tiles/Makefile

@@ -0,0 +1,47 @@
+# Get current platform
+ifeq ($(shell uname -m), x86_64)
+  ARCH  = x86_64
+else
+  ARCH  = i386
+endif
+
+# Get current OS
+ifeq ($(shell uname), Linux)
+  OS    = linux
+else ifeq ($(shell uname), Darwin)
+  OS    = darwin
+endif
+
+# Variables
+GCC     = gcc
+MINGW32 = i486-mingw32-gcc
+MINGW64 = x86_64-w64-mingw32-gcc
+FLAGS   = -O3 -std=c99 -Wall
+INCLUDE = -I../../../headers
+LIBS    = -ldl
+OUTPUT  = ../../../bin/
+TMP     = ../tmp/
+UNIT    = demo10.c
+TARGET  = demo10
+TARGETW = demo10.exe
+
+# Targets
+all: clean
+	$(GCC) $(UNIT) $(INCLUDE) $(LIBS) -o$(OUTPUT)$(ARCH)-$(OS)/$(TARGET) $(FLAGS)
+	strip $(OUTPUT)$(ARCH)-$(OS)/$(TARGET) --strip-unneeded -R .comment -R .note
+
+linux32: clean
+	$(GCC) $(UNIT) $(INCLUDE) $(LIBS) -o$(OUTPUT)i386-linux/$(TARGET) $(FLAGS) -m32
+	strip $(OUTPUT)i386-linux/$(TARGET) --strip-unneeded -R .comment -R .note
+
+win32: clean
+	$(MINGW32) $(UNIT) $(INCLUDE) -o$(OUTPUT)i386-win32/$(TARGETW) $(FLAGS)
+	strip $(OUTPUT)i386-win32/$(TARGETW) --strip-unneeded -R .comment -R .note
+
+win64: clean
+	$(MINGW64) $(UNIT) $(INCLUDE) -o$(OUTPUT)x86_64-win64/$(TARGETW) $(FLAGS)
+	strip $(OUTPUT)x86_64-win64/$(TARGETW) --strip-unneeded -R .comment -R .note
+
+clean:
+	rm -f *.*~
+	rm -f $(TMP)*.*

+ 102 - 0
demos/GCC/10 - Tiles/demo10.c

@@ -0,0 +1,102 @@
+#define ZGL_IMPORT
+
+#include <memory.h>
+#include <math.h>
+#include "zglHeader.h"
+
+zglPFont    fntMain;
+zglTTiles2D map;
+zglPTexture texTiles;
+
+char resource[256];
+
+char* GetResource( char* FileName )
+{
+#ifndef __MACOSX__
+  sprintf_s( resource, "../data/%s", FileName );
+  return resource;
+#else
+  return FileName;
+#endif
+}
+
+void Init()
+{
+  fntMain = font_LoadFromFile( GetResource( "font.zfi" ) );
+
+  texTiles = tex_LoadFromFile( GetResource( "tiles.png" ), TEX_NO_COLORKEY, TEX_DEFAULT_2D );
+  tex_SetFrameSize( &texTiles, 32, 32 );
+
+  // RU: Инициализация тайлов размером 32x32. Параметр Count указывает на количество тайлов по X и Y. Массив Tiles содержит кадры для каждого тайла.
+  // EN: Initialization of tiles with size 32x32. Parameter Count set amount of tiles on X and Y. Array Tiles contains frames for every tile.
+  map.Size.W  = 32;
+  map.Size.H  = 32;
+  map.Count.X = 25;
+  map.Count.Y = 19;
+  map.Tiles = (int**)malloc( sizeof( int* ) * map.Count.X );
+  // RU: Заполняем карту "травой", 19 кадр.
+  // EN: Fill the map by "grass", 19 frame.
+  for ( int i = 0; i < map.Count.X; i++ )
+  {
+    map.Tiles[ i ] = (int*)malloc( sizeof( int ) * map.Count.Y );
+    for ( int j = 0; j < map.Count.Y; j++ )
+      map.Tiles[ i ][ j ] = 19;
+  }
+
+  // RU: Загружаем карту из бинарного файла.
+  // EN: Load map from binary file.
+  zglTFile f;
+  file_Open( &f, GetResource( "ground.map" ), FOM_OPENR );
+  for ( int i = 0; i < map.Count.X; i++ )
+    file_Read( f, &map.Tiles[ i ][ 0 ], map.Count.Y * sizeof( int ) );
+  file_Close( &f );
+}
+
+void Draw()
+{
+  // RU: Рендерим тайлы в координатах 0,0.
+  // EN: Render tiles in coordinates 0,0.
+  tiles2d_Draw( texTiles, 0, 0, &map, 255, FX_BLEND );
+
+  char text[64];
+  sprintf_s( text, "FPS: %i", (int)zgl_Get( RENDER_FPS ) );
+  text_Draw( fntMain, 0, 0, text, 0 );
+
+  text_Draw( fntMain, 180, 30, "This is a tarrible example of tile map, but main idea should be clear :)", 0 );
+}
+
+void Timer()
+{
+  if ( key_Press( K_ESCAPE ) ) zgl_Exit();
+
+  key_ClearState();
+}
+
+void Quit()
+{
+  for ( int i = 0; i < map.Count.X; i++ )
+    free( map.Tiles[ i ] );
+  free( map.Tiles );
+}
+
+int main()
+{
+  if ( !zglLoad( libZenGL ) ) return 0;
+
+  timer_Add( (void*)&Timer, 16, FALSE, NULL );
+
+  zgl_Reg( SYS_LOAD, (void*)&Init );
+  zgl_Reg( SYS_DRAW, (void*)&Draw );
+  zgl_Reg( SYS_EXIT, (void*)&Quit );
+
+  wnd_SetCaption( "10 - Tiles" );
+
+  wnd_ShowCursor( TRUE );
+
+  scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FALSE, FALSE );
+
+  zgl_Init( 0, 0 );
+
+  zglFree();
+  return 0;
+}

+ 47 - 0
demos/GCC/13 - Particles/Makefile

@@ -0,0 +1,47 @@
+# Get current platform
+ifeq ($(shell uname -m), x86_64)
+  ARCH  = x86_64
+else
+  ARCH  = i386
+endif
+
+# Get current OS
+ifeq ($(shell uname), Linux)
+  OS    = linux
+else ifeq ($(shell uname), Darwin)
+  OS    = darwin
+endif
+
+# Variables
+GCC     = gcc
+MINGW32 = i486-mingw32-gcc
+MINGW64 = x86_64-w64-mingw32-gcc
+FLAGS   = -O3 -std=c99 -Wall
+INCLUDE = -I../../../headers
+LIBS    = -ldl
+OUTPUT  = ../../../bin/
+TMP     = ../tmp/
+UNIT    = demo13.c
+TARGET  = demo13
+TARGETW = demo13.exe
+
+# Targets
+all: clean
+	$(GCC) $(UNIT) $(INCLUDE) $(LIBS) -o$(OUTPUT)$(ARCH)-$(OS)/$(TARGET) $(FLAGS)
+	strip $(OUTPUT)$(ARCH)-$(OS)/$(TARGET) --strip-unneeded -R .comment -R .note
+
+linux32: clean
+	$(GCC) $(UNIT) $(INCLUDE) $(LIBS) -o$(OUTPUT)i386-linux/$(TARGET) $(FLAGS) -m32
+	strip $(OUTPUT)i386-linux/$(TARGET) --strip-unneeded -R .comment -R .note
+
+win32: clean
+	$(MINGW32) $(UNIT) $(INCLUDE) -o$(OUTPUT)i386-win32/$(TARGETW) $(FLAGS)
+	strip $(OUTPUT)i386-win32/$(TARGETW) --strip-unneeded -R .comment -R .note
+
+win64: clean
+	$(MINGW64) $(UNIT) $(INCLUDE) -o$(OUTPUT)x86_64-win64/$(TARGETW) $(FLAGS)
+	strip $(OUTPUT)x86_64-win64/$(TARGETW) --strip-unneeded -R .comment -R .note
+
+clean:
+	rm -f *.*~
+	rm -f $(TMP)*.*

+ 135 - 0
demos/GCC/13 - Particles/demo13.c

@@ -0,0 +1,135 @@
+#define ZGL_IMPORT
+
+#include <memory.h>
+#include <math.h>
+#include "zglHeader.h"
+
+zglPFont      fntMain;
+zglPTexture   texBack;
+bool          debug;
+zglTPEngine2D particles;
+zglPEmitter2D emitterFire[3];
+zglPEmitter2D emitterDiamond;
+zglPEmitter2D emitterRain;
+
+char resource[256];
+
+char* GetResource( char* FileName )
+{
+#ifndef __MACOSX__
+  sprintf_s( resource, "../data/%s", FileName );
+  return resource;
+#else
+  return FileName;
+#endif
+}
+
+void Init()
+{
+  texBack = tex_LoadFromFile( GetResource( "back02.png" ), TEX_NO_COLORKEY, TEX_DEFAULT_2D );
+
+  fntMain = font_LoadFromFile( GetResource( "font.zfi" ) );
+
+  // EN: Load three types of fire emitters.
+  // RU: Загрузка трёх разных видов эмиттеров огня.
+  emitterFire[ 0 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire00.zei" ) );
+  emitterFire[ 1 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire01.zei" ) );
+  emitterFire[ 2 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire02.zei" ) );
+
+  // EN: Set own particels engine.
+  // RU: Установка собственного движка эмиттеров.
+  pengine2d_Set( &particles );
+
+  // EN: Add 6 fire emitters to particles engine. Second parameter of function returns pointer to instance of new emitter, which can be processed manually.
+  //     This instance will be  NULL after the death, so check everything.
+  // RU: Добавляем в движок 6 эмиттеров огня. Второй параметр функции позволяет получить указатель на конкретный экземпляр эмиттера, который можно будет обрабатывать вручную.
+  //     Данный экземпляр после смерти будет содержать NULL, поэтому используйте проверку.
+  pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 642, 190 );
+  pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 40, 368 );
+  pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 246, 368 );
+  pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 532, 244 );
+  pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 318, 422 );
+  pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 583, 420 );
+  pengine2d_AddEmitter( emitterFire[ 2 ], NULL, 740, 525 );
+
+  emitterDiamond = emitter2d_LoadFromFile( GetResource( "emitter_diamond.zei" ) );
+  pengine2d_AddEmitter( emitterDiamond, NULL, 0, 0 );
+
+  emitterRain = emitter2d_LoadFromFile( GetResource( "emitter_rain.zei" ) );
+  pengine2d_AddEmitter( emitterRain, NULL, 0, 0 );
+}
+
+void Draw()
+{
+  batch2d_Begin();
+
+  ssprite2d_Draw( texBack, 0, 0, 800, 600, 0, 255, FX_BLEND );
+
+  // EN: Rendering of all emitters in current particles engine.
+  // RU: Рендеринг всех эмиттеров в текущем движке частиц.
+  pengine2d_Draw();
+
+  if ( debug )
+    for ( int i = 0; i < particles.Count.Emitters; i++ )
+      pr2d_Rect( particles.List[ i ]->BBox.MinX, particles.List[ i ]->BBox.MinY,
+                  particles.List[ i ]->BBox.MaxX - particles.List[ i ]->BBox.MinX,
+                  particles.List[ i ]->BBox.MaxY - particles.List[ i ]->BBox.MinY, 0xFF0000, 255, 0 );
+
+  char text[64];
+  sprintf_s( text, "FPS: %i", (int)zgl_Get( RENDER_FPS ) );
+  text_Draw( fntMain, 0, 0, text, 0 );
+
+  sprintf_s( text, "Particles: %i", particles.Count.Particles );
+  text_Draw( fntMain, 0, 20, text, 0 );
+
+  sprintf_s( text, "Debug(F1): %s", debug ? "TRUE" : "FALSE" );
+  text_Draw( fntMain, 0, 40, text, 0 );
+
+  batch2d_End();
+}
+
+void Timer()
+{
+  if ( key_Press( K_ESCAPE ) ) zgl_Exit();
+  if ( key_Press( K_F1 ) ) debug = !debug;
+
+  key_ClearState();
+}
+
+void Update( double dt )
+{
+  // EN: Process all emitters in current particles engine.
+  // RU: Обработка всех эмиттеров в текущем движке частиц.
+  pengine2d_Proc( dt );
+}
+
+void Quit()
+{
+  // RU: Очищаем память от созданных эмиттеров.
+  // EN: Free allocated memory for emitters.
+  pengine2d_Set( &particles );
+  pengine2d_ClearAll();
+}
+
+int main()
+{
+  if ( !zglLoad( libZenGL ) ) return 0;
+
+  timer_Add( (void*)&Timer, 16, FALSE, NULL );
+
+  zgl_Reg( SYS_LOAD, (void*)&Init );
+  zgl_Reg( SYS_DRAW, (void*)&Draw );
+  zgl_Reg( SYS_UPDATE, (void*)&Update );
+  zgl_Reg( SYS_EXIT, (void*)&Quit );
+
+  wnd_SetCaption( "13 - Particles" );
+
+  wnd_ShowCursor( TRUE );
+
+  scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FALSE, FALSE );
+
+  zgl_Init( 0, 0 );
+
+  zglFree();
+  return 0;
+}

+ 47 - 0
demos/GCC/15 - Video/Makefile

@@ -0,0 +1,47 @@
+# Get current platform
+ifeq ($(shell uname -m), x86_64)
+  ARCH  = x86_64
+else
+  ARCH  = i386
+endif
+
+# Get current OS
+ifeq ($(shell uname), Linux)
+  OS    = linux
+else ifeq ($(shell uname), Darwin)
+  OS    = darwin
+endif
+
+# Variables
+GCC     = gcc
+MINGW32 = i486-mingw32-gcc
+MINGW64 = x86_64-w64-mingw32-gcc
+FLAGS   = -O3 -std=c99 -Wall
+INCLUDE = -I../../../headers
+LIBS    = -ldl
+OUTPUT  = ../../../bin/
+TMP     = ../tmp/
+UNIT    = demo15.c
+TARGET  = demo15
+TARGETW = demo15.exe
+
+# Targets
+all: clean
+	$(GCC) $(UNIT) $(INCLUDE) $(LIBS) -o$(OUTPUT)$(ARCH)-$(OS)/$(TARGET) $(FLAGS)
+	strip $(OUTPUT)$(ARCH)-$(OS)/$(TARGET) --strip-unneeded -R .comment -R .note
+
+linux32: clean
+	$(GCC) $(UNIT) $(INCLUDE) $(LIBS) -o$(OUTPUT)i386-linux/$(TARGET) $(FLAGS) -m32
+	strip $(OUTPUT)i386-linux/$(TARGET) --strip-unneeded -R .comment -R .note
+
+win32: clean
+	$(MINGW32) $(UNIT) $(INCLUDE) -o$(OUTPUT)i386-win32/$(TARGETW) $(FLAGS)
+	strip $(OUTPUT)i386-win32/$(TARGETW) --strip-unneeded -R .comment -R .note
+
+win64: clean
+	$(MINGW64) $(UNIT) $(INCLUDE) -o$(OUTPUT)x86_64-win64/$(TARGETW) $(FLAGS)
+	strip $(OUTPUT)x86_64-win64/$(TARGETW) --strip-unneeded -R .comment -R .note
+
+clean:
+	rm -f *.*~
+	rm -f $(TMP)*.*

+ 112 - 0
demos/GCC/15 - Video/demo15.c

@@ -0,0 +1,112 @@
+#define ZGL_IMPORT
+
+#include <memory.h>
+#include <math.h>
+#include "zglHeader.h"
+
+#define SCREEN_WIDTH  800
+#define SCREEN_HEIGHT 600
+
+zglPFont        fntMain;
+zglPVideoStream video;
+bool            videoSeek;
+
+char resource[256];
+
+char* GetResource( char* FileName )
+{
+#ifndef __MACOSX__
+  sprintf_s( resource, "../data/%s", FileName );
+  return resource;
+#else
+  return FileName;
+#endif
+}
+
+void Init()
+{
+  fntMain = font_LoadFromFile( GetResource( "font.zfi" ) );
+
+  // EN: Open the video file.
+  // RU: Открыть видео файл.
+  video = video_OpenFile( GetResource( "video.ogv" ) );
+}
+
+void Draw()
+{
+  if ( video )
+  {
+    // EN: Rendering the current video frame in the center of screen using parameters of it from video.Info.
+    // RU: Рендеринг текущего кадра видео в центре экрана используя параметры из video.Info.
+    ssprite2d_Draw( video->Texture, ( 800 - video->Info.Width ) / 2.f, ( 600 - video->Info.Height ) / 2.f, video->Info.Width, video->Info.Height, 0, 255, FX_BLEND );
+
+    // EN: Rendering of progress bar.
+    // RU: Рендеринг полосы прогресса.
+    pr2d_Rect( 0, 600 - 100, 800, 20, 0x00FF00, 255, 0 );
+    pr2d_Rect( 0, 600 - 100, ( 800.f / (float)video->Info.Duration ) * (float)video->Time, 20, 0x00FF00, 155, PR2D_FILL );
+
+    char text[64];
+    sprintf_s( text, "FPS: %i", (int)zgl_Get( RENDER_FPS ) );
+    text_Draw( fntMain, 0, 0, text, 0 );
+
+    sprintf_s( text, "Frame: %i", video->Frame );
+    text_Draw( fntMain, 0, 20, text, 0 );
+
+    sprintf_s( text, "Duration: %3.2f", video->Info.Duration / 1000.f );
+    text_Draw( fntMain, 100, 0, text, 0 );
+
+    sprintf_s( text, "Frames: %i", video->Info.Frames );
+    text_Draw( fntMain, 100, 20, text, 0 );
+
+    sprintf_s( text, "Time: %3.2f", video->Time / 1000.f );
+    text_Draw( fntMain, 230, 0, text, 0 );
+  }
+}
+
+void Timer()
+{
+  if ( key_Press( K_ESCAPE ) ) zgl_Exit();
+
+  // EN: If left mouse button is down on progress bar, then seek the video.
+  // RU: Если зажата левая кнопка мыши над полосой прогресса - перемещаться по видео.
+  if ( mouse_Down( M_BLEFT ) && ( mouse_Y() > 500 ) && ( mouse_Y() < 520 ) )
+  {
+    videoSeek = TRUE;
+    video_Seek( &video, ( mouse_X() / 800.f ) * video->Info.Duration );
+  }
+  else
+    videoSeek = FALSE;
+
+  key_ClearState();
+  mouse_ClearState();
+}
+
+void Update( double dt )
+{
+  if ( !videoSeek )
+    video_Update( &video, dt, TRUE );
+}
+
+int main()
+{
+  if ( !zglLoad( libZenGL ) ) return 0;
+
+  srand( 0xDeaDBeeF );
+
+  timer_Add( (void*)&Timer, 16, FALSE, NULL );
+
+  zgl_Reg( SYS_LOAD, (void*)&Init );
+  zgl_Reg( SYS_DRAW, (void*)&Draw );
+  zgl_Reg( SYS_UPDATE, (void*)&Update );
+
+  wnd_SetCaption( "15 - Video" );
+
+  wnd_ShowCursor( TRUE );
+
+  scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FALSE, FALSE );
+
+  zgl_Init( 0, 0 );
+
+  zglFree();
+  return 0;
+}

+ 55 - 55
demos/Visual Studio 2010/13 - Particles/demo13.cpp

@@ -5,11 +5,11 @@
 #include "zglHeader.h"
 
 zglPFont		fntMain;
-zglPTexture		texBack;
-bool			debug;
-zglTPEngine2D	particles;
-zglPEmitter2D	emitterFire[3];
-zglPEmitter2D	emitterDiamond;
+zglPTexture		texBack;
+bool			debug;
+zglTPEngine2D	particles;
+zglPEmitter2D	emitterFire[3];
+zglPEmitter2D	emitterDiamond;
 zglPEmitter2D	emitterRain;
 
 char resource[256];
@@ -26,51 +26,51 @@ void Init()
 
 	fntMain = font_LoadFromFile( GetResource( "font.zfi" ) );
 
-	// EN: Load three types of fire emitters.
-	// RU: Загрузка трёх разных видов эмиттеров огня.
-	emitterFire[ 0 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire00.zei" ) );
-	emitterFire[ 1 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire01.zei" ) );
-	emitterFire[ 2 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire02.zei" ) );
-
-	// EN: Set own particels engine.
-	// RU: Установка собственного движка эмиттеров.
-	pengine2d_Set( &particles );
-
-	// EN: Add 6 fire emitters to particles engine. Second parameter of function returns pointer to instance of new emitter, which can be processed manually.
-	//     This instance will be  NULL after the death, so check everything.
-	// RU: Добавляем в движок 6 эмиттеров огня. Второй параметр функции позволяет получить указатель на конкретный экземпляр эмиттера, который можно будет обрабатывать вручную.
-	//     Данный экземпляр после смерти будет содержать NULL, поэтому используйте проверку.
-	pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 642, 190 );
-	pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 40, 368 );
-	pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 246, 368 );
-	pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 532, 244 );
-	pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 318, 422 );
-	pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 583, 420 );
-	pengine2d_AddEmitter( emitterFire[ 2 ], NULL, 740, 525 );
-
-	emitterDiamond = emitter2d_LoadFromFile( GetResource( "emitter_diamond.zei" ) );
-	pengine2d_AddEmitter( emitterDiamond, NULL );
-
-	emitterRain = emitter2d_LoadFromFile( GetResource( "emitter_rain.zei" ) );
+	// EN: Load three types of fire emitters.
+	// RU: Загрузка трёх разных видов эмиттеров огня.
+	emitterFire[ 0 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire00.zei" ) );
+	emitterFire[ 1 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire01.zei" ) );
+	emitterFire[ 2 ] = emitter2d_LoadFromFile( GetResource( "emitter_fire02.zei" ) );
+
+	// EN: Set own particels engine.
+	// RU: Установка собственного движка эмиттеров.
+	pengine2d_Set( &particles );
+
+	// EN: Add 6 fire emitters to particles engine. Second parameter of function returns pointer to instance of new emitter, which can be processed manually.
+	//     This instance will be  NULL after the death, so check everything.
+	// RU: Добавляем в движок 6 эмиттеров огня. Второй параметр функции позволяет получить указатель на конкретный экземпляр эмиттера, который можно будет обрабатывать вручную.
+	//     Данный экземпляр после смерти будет содержать NULL, поэтому используйте проверку.
+	pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 642, 190 );
+	pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 40, 368 );
+	pengine2d_AddEmitter( emitterFire[ 0 ], NULL, 246, 368 );
+	pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 532, 244 );
+	pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 318, 422 );
+	pengine2d_AddEmitter( emitterFire[ 1 ], NULL, 583, 420 );
+	pengine2d_AddEmitter( emitterFire[ 2 ], NULL, 740, 525 );
+
+	emitterDiamond = emitter2d_LoadFromFile( GetResource( "emitter_diamond.zei" ) );
+	pengine2d_AddEmitter( emitterDiamond, NULL );
+
+	emitterRain = emitter2d_LoadFromFile( GetResource( "emitter_rain.zei" ) );
 	pengine2d_AddEmitter( emitterRain, NULL );
 }
 
 void Draw()
 {
-	batch2d_Begin();
-
-	ssprite2d_Draw( texBack, 0, 0, 800, 600, 0 );
-
-	// EN: Rendering of all emitters in current particles engine.
-	// RU: Рендеринг всех эмиттеров в текущем движке частиц.
-	pengine2d_Draw();
-
-	if ( debug )
-		for ( int i = 0; i < particles.Count.Emitters; i++ )
-			pr2d_Rect( particles.List[ i ]->BBox.MinX, particles.List[ i ]->BBox.MinY,
-						particles.List[ i ]->BBox.MaxX - particles.List[ i ]->BBox.MinX,
-						particles.List[ i ]->BBox.MaxY - particles.List[ i ]->BBox.MinY, 0xFF0000, 255 );
-
+	batch2d_Begin();
+
+	ssprite2d_Draw( texBack, 0, 0, 800, 600, 0 );
+
+	// EN: Rendering of all emitters in current particles engine.
+	// RU: Рендеринг всех эмиттеров в текущем движке частиц.
+	pengine2d_Draw();
+
+	if ( debug )
+		for ( int i = 0; i < particles.Count.Emitters; i++ )
+			pr2d_Rect( particles.List[ i ]->BBox.MinX, particles.List[ i ]->BBox.MinY,
+						particles.List[ i ]->BBox.MaxX - particles.List[ i ]->BBox.MinX,
+						particles.List[ i ]->BBox.MaxY - particles.List[ i ]->BBox.MinY, 0xFF0000, 255 );
+
 	char text[64];
 	sprintf_s( text, "FPS: %i", zgl_Get( RENDER_FPS ) );
 	text_Draw( fntMain, 0, 0, text );
@@ -79,31 +79,31 @@ void Draw()
 	text_Draw( fntMain, 0, 20, text );
 
 	sprintf_s( text, "Debug(F1): %s", debug ? "TRUE" : "FALSE" );
-	text_Draw( fntMain, 0, 40, text );
-
+	text_Draw( fntMain, 0, 40, text );
+
 	batch2d_End();
 }
 
 void Timer()
 {
-	if ( key_Press( K_ESCAPE ) ) zgl_Exit();
-	if ( key_Press( K_F1 ) ) debug = !debug;
-
+	if ( key_Press( K_ESCAPE ) ) zgl_Exit();
+	if ( key_Press( K_F1 ) ) debug = !debug;
+
 	key_ClearState();
 }
 
 void Update( double dt )
 {
-	// EN: Process all emitters in current particles engine.
-	// RU: Обработка всех эмиттеров в текущем движке частиц.
+	// EN: Process all emitters in current particles engine.
+	// RU: Обработка всех эмиттеров в текущем движке частиц.
 	pengine2d_Proc( dt );
 }
 
 void Quit()
 {
-	// RU: Очищаем память от созданных эмиттеров.
-	// EN: Free allocated memory for emitters.
-	pengine2d_Set( &particles );
+	// RU: Очищаем память от созданных эмиттеров.
+	// EN: Free allocated memory for emitters.
+	pengine2d_Set( &particles );
 	pengine2d_ClearAll();
 }
 

+ 2 - 2
headers/zglHeader.h

@@ -3,7 +3,7 @@
 /*--------------------------------*/
 /*                                */
 /* version:  0.3.4                */
-/* date:     2012.09.19           */
+/* date:     2012.09.23           */
 /* license:  GNU LGPL version 3   */
 /* homepage: http://zengl.org     */
 /*                                */
@@ -1142,7 +1142,7 @@ typedef struct zglTPEngine2D
 
   zglPEmitter2D *List;
   zglPPEmitter2D *ListU;
-} *zglPPEngine2D;
+} zglTPEngine2D, *zglPPEngine2D;
 
 ZGLEXTERN void ( *pengine2d_Set )( zglPPEngine2D PEngine );
 ZGLEXTERN zglPPEngine2D ( *pengine2d_Get )();

+ 1 - 1
headers/zglHeader.pas

@@ -3,7 +3,7 @@
 {--------------------------------}
 {                                }
 { version:  0.3.4                }
-{ date:     2012.09.19           }
+{ date:     2012.09.23           }
 { license:  GNU LGPL version 3   }
 { homepage: http://zengl.org     }
 {                                }

+ 4 - 0
src/zgl_application.pas

@@ -1608,6 +1608,7 @@ begin
 
   if appInitialized Then
     begin
+      oglVRAMUsed := 0;
       gl_ResetState();
       if Assigned( app_PRestore ) Then
         app_PRestore();
@@ -1780,6 +1781,9 @@ end;
 
 procedure Java_zengl_android_ZenGL_zglNativeInputText( env : PJNIEnv; thiz : jobject; text : jstring );
 begin
+  appEnv    := env;
+  appObject := thiz;
+
   key_InputText( appEnv^.GetStringUTFChars( appEnv, text, nil ) );
 end;
 

+ 42 - 0
src/zgl_font.pas

@@ -73,6 +73,9 @@ procedure font_Del( var Font : zglPFont );
 
 function font_LoadFromFile( const FileName : UTF8String ) : zglPFont;
 function font_LoadFromMemory( const Memory : zglTMemory ) : zglPFont;
+{$IFDEF ANDROID}
+procedure font_RestoreFromFile( var Font : zglPFont; const FileName : UTF8String );
+{$ENDIF}
 
 procedure font_Load( var fnt : zglPFont; var fntMem : zglTMemory );
 
@@ -194,6 +197,45 @@ begin
     log_Add( 'Unable to load font: From Memory' );
 end;
 
+{$IFDEF ANDROID}
+procedure font_RestoreFromFile( var Font : zglPFont; const FileName : UTF8String );
+  var
+    fntMem : zglTMemory;
+    i, j   : Integer;
+    dir    : UTF8String;
+    name   : UTF8String;
+    tmp    : UTF8String;
+    res    : zglTFontResource;
+begin
+  if resUseThreaded Then
+    begin
+      res.FileName := FileName;
+      res.Font     := Font;
+      res_AddToQueue( RES_FONT_RESTORE, TRUE, @res );
+      exit;
+    end;
+
+  if not file_Exists( FileName ) Then
+    begin
+      log_Add( 'Cannot read "' + FileName + '"' );
+      exit;
+    end;
+
+  dir  := file_GetDirectory( FileName );
+  name := file_GetName( FileName );
+  for i := 0 to Font.Count.Pages - 1 do
+    for j := managerTexture.Count.Formats - 1 downto 0 do
+      begin
+        tmp := dir + name + '-page' + u_IntToStr( i ) + '.' + u_StrDown( managerTexture.Formats[ j ].Extension );
+        if file_Exists( tmp ) Then
+          begin
+            tex_RestoreFromFile( Font.Pages[ i ], tmp, TEX_NO_COLORKEY, TEX_DEFAULT_2D );
+            break;
+          end;
+      end;
+end;
+{$ENDIF}
+
 procedure font_Load( var fnt : zglPFont; var fntMem : zglTMemory );
   var
     i     : Integer;

+ 1 - 1
src/zgl_main.pas

@@ -46,7 +46,7 @@ uses
 
 const
   cs_ZenGL    = 'ZenGL 0.3.4';
-  cs_Date     = '2012.09.19';
+  cs_Date     = '2012.09.23';
   cv_major    = 0;
   cv_minor    = 3;
   cv_revision = 4;

+ 34 - 0
src/zgl_particles_2d.pas

@@ -248,6 +248,9 @@ procedure emitter2d_Del( var Emitter : zglPEmitter2D );
 function  emitter2d_Load( const FileName : UTF8String ) : zglPEmitter2D;
 function  emitter2d_LoadFromFile( const FileName : UTF8String ) : zglPEmitter2D;
 function  emitter2d_LoadFromMemory( const Memory : zglTMemory ) : zglPEmitter2D;
+{$IFDEF ANDROID}
+procedure emitter2d_RestoreAll;
+{$ENDIF}
 procedure emitter2d_SaveToFile( Emitter : zglPEmitter2D; const FileName : UTF8String );
 procedure emitter2d_Init( Emitter : zglPEmitter2D );
 procedure emitter2d_Free( var Emitter : zglPEmitter2D );
@@ -845,6 +848,37 @@ begin
       Result := emitter2d_Load( '' );
 end;
 
+{$IFDEF ANDROID}
+procedure emitter2d_RestoreAll;
+  var
+    i, j          : Integer;
+    restored      : array of zglPTexture;
+    restoredCount : Integer;
+    restore       : Boolean;
+begin
+  SetLength( restored, managerEmitter2D.Count );
+  FillChar( restored[ 0 ], SizeOf( zglPTexture ) * managerEmitter2D.Count, 0 );
+  restoredCount := 0;
+
+  for i := 0 to managerEmitter2D.Count - 1 do
+    begin
+      restore := TRUE;
+      for j := 0 to restoredCount - 1 do
+        if managerEmitter2D.List[ i ]._private.texHash = managerEmitter2D.List[ j ]._private.texHash Then
+          begin
+            restore := FALSE;
+            break;
+          end;
+
+      if restore Then
+        begin
+          tex_RestoreFromFile( managerEmitter2D.List[ i ].ParParams.Texture, managerEmitter2D.List[ i ]._private.texFile );
+          INC( restoredCount );
+        end;
+    end;
+end;
+{$ENDIF}
+
 procedure emitter2d_SaveToFile( Emitter : zglPEmitter2D; const FileName : UTF8String );
   var
     c : LongWord;

+ 28 - 0
src/zgl_render_target.pas

@@ -33,6 +33,7 @@ uses
   {$IFDEF MACOSX}
   MacOSAll,
   {$ENDIF}
+  zgl_types,
   {$IFNDEF USE_GLES}
   zgl_opengl,
   zgl_opengl_all,
@@ -79,6 +80,9 @@ function  rtarget_Add( Surface : zglPTexture; Flags : Byte ) : zglPRenderTarget;
 procedure rtarget_Del( var Target : zglPRenderTarget );
 procedure rtarget_Set( Target : zglPRenderTarget );
 procedure rtarget_DrawIn( Target : zglPRenderTarget; RenderCallback : zglTRenderCallback; Data : Pointer );
+{$IFDEF ANDROID}
+procedure rtarget_Restore( var Target : zglPRenderTarget );
+{$ENDIF}
 
 var
   managerRTarget : zglTRenderTargetManager;
@@ -723,4 +727,28 @@ begin
       end;
 end;
 
+{$IFDEF ANDROID}
+procedure rtarget_Restore( var Target : zglPRenderTarget );
+  var
+    rt    : zglPRenderTarget;
+    pData : PByteArray;
+begin
+  zgl_GetMem( pData, Round( Target.Surface.Width / Target.Surface.U ) * Round( Target.Surface.Height / Target.Surface.V ) * 4 );
+  tex_CreateGL( Target.Surface^, pData );
+  zgl_FreeMem( pData );
+
+  rt := rtarget_Add( Target.Surface, Target.Flags );
+  FreeMem( Target.Handle );
+  Target.Handle := rt.Handle;
+
+  if Assigned( rt.prev ) Then
+    rt.prev.next := rt.next;
+  if Assigned( rt.next ) Then
+    rt.next.prev := rt.prev;
+  FreeMem( rt );
+
+  DEC( managerRTarget.Count );
+end;
+{$ENDIF}
+
 end.

+ 35 - 9
src/zgl_resources.pas

@@ -45,8 +45,14 @@ const
   RES_TEXTURE_FRAMESIZE = $000002;
   RES_TEXTURE_MASK      = $000003;
   RES_TEXTURE_DELETE    = $000004;
+  {$IFDEF ANDROID}
+  RES_TEXTURE_RESTORE   = $000009;
+  {$ENDIF}
   RES_FONT              = $000010;
   RES_FONT_DELETE       = $000011;
+  {$IFDEF ANDROID}
+  RES_FONT_RESTORE      = $000019;
+  {$ENDIF}
   RES_SOUND             = $000020;
   RES_SOUND_DELETE      = $000021;
   RES_ZIP_OPEN          = $000030;
@@ -176,10 +182,10 @@ begin
     Item.next.prev := Item.prev;
 
   case Item.Type_ of
-    RES_TEXTURE:
+    RES_TEXTURE {$IFDEF ANDROID}, RES_TEXTURE_RESTORE {$ENDIF}:
       if Assigned( Item.Resource ) Then
         zglPTextureResource( Item.Resource ).FileName := '';
-    RES_FONT:
+    RES_FONT {$IFDEF ANDROID}, RES_FONT_RESTORE {$ENDIF}:
       if Assigned( Item.Resource ) Then
         zglPFontResource( Item.Resource ).FileName := '';
     {$IFDEF USE_SOUND}
@@ -247,12 +253,17 @@ begin
           begin
             if ( item.Ready ) and Assigned( item.Resource ) Then
               case item.Type_ of
-                RES_TEXTURE:
+                RES_TEXTURE {$IFDEF ANDROID}, RES_TEXTURE_RESTORE {$ENDIF}:
                   with zglPTextureResource( item.Resource )^ do
                     begin
                       tex_CreateGL( Texture^, pData );
                       FreeMem( pData );
                       if item.IsFromFile Then
+                      {$IFDEF ANDROID}
+                        if item.Type_ = RES_TEXTURE_RESTORE Then
+                          log_Add( 'Texture restored: "' + FileName + '"' )
+                        else
+                      {$ENDIF}
                         log_Add( 'Texture loaded: "' + FileName + '"' );
 
                       FileName := '';
@@ -273,7 +284,7 @@ begin
                       DEC( resQueueSize[ id ] );
                       break;
                     end;
-                RES_FONT:
+                RES_FONT {$IFDEF ANDROID}, RES_FONT_RESTORE {$ENDIF}:
                   with zglPFontResource( item.Resource )^ do
                     if item.Prepared Then
                       begin
@@ -305,7 +316,7 @@ begin
                       thread_EventSet( resQueueState[ id ] );
                       break;
                     end;
-                RES_FONT:
+                RES_FONT {$IFDEF ANDROID}, RES_FONT_RESTORE {$ENDIF}:
                   if item.Ready Then
                     with zglPFontResource( item.Resource )^ do
                       begin
@@ -371,7 +382,7 @@ begin
   zgl_GetMem( Pointer( item^ ), SizeOf( zglTResourceItem ) );
 
   case Type_ of
-    RES_TEXTURE:
+    RES_TEXTURE {$IFDEF ANDROID}, RES_TEXTURE_RESTORE {$ENDIF}:
       begin
         zgl_GetMem( Pointer( tex ), SizeOf( zglTTextureResource ) );
         with zglPTextureResource( Resource )^ do
@@ -410,7 +421,7 @@ begin
     RES_TEXTURE_DELETE:
       begin
       end;
-    RES_FONT:
+    RES_FONT {$IFDEF ANDROID}, RES_FONT_RESTORE {$ENDIF}:
       begin
         zgl_GetMem( Pointer( fnt ), SizeOf( zglTFontResource ) );
         with zglPFontResource( Resource )^ do
@@ -495,7 +506,7 @@ begin
         begin
           if ( not item.Ready ) and Assigned( item.Resource ) Then
             case item.Type_ of
-              RES_TEXTURE:
+              RES_TEXTURE {$IFDEF ANDROID}, RES_TEXTURE_RESTORE {$ENDIF}:
                 with item^, zglPTextureResource( Resource )^ do
                   begin
                     if IsFromFile Then
@@ -512,6 +523,11 @@ begin
 
                     if not Assigned( pData ) Then
                       begin
+                        {$IFDEF ANDROID}
+                        if item.Type_ = RES_TEXTURE_RESTORE Then
+                          log_Add( 'Unable to restore texture: "' + FileName + '"' )
+                        else
+                        {$ENDIF}
                         log_Add( 'Unable to load texture: "' + FileName + '"' );
 
                         // FIXME: Temporary solution, change in future
@@ -586,7 +602,7 @@ begin
 
                       Ready := TRUE;
                     end;
-              RES_FONT:
+              RES_FONT {$IFDEF ANDROID}, RES_FONT_RESTORE {$ENDIF}:
                 with item^, zglPFontResource( Resource )^ do
                   begin
                     if not Prepared Then
@@ -621,6 +637,11 @@ begin
                                       if file_Exists( tmp ) Then
                                         begin
                                           managerTexture.Formats[ j ].FileLoader( tmp, pData[ i ], Width[ i ], Height[ i ], Format[ i ] );
+                                          {$IFDEF ANDROID}
+                                          if item.Type_ = RES_FONT_RESTORE Then
+                                            log_Add( 'Texture restored: "' + tmp + '"'  )
+                                          else
+                                          {$ENDIF}
                                           log_Add( 'Texture loaded: "' + tmp + '"'  );
                                           break;
                                         end;
@@ -630,6 +651,11 @@ begin
                             Ready := TRUE;
                           end else
                             begin
+                              {$IFDEF ANDROID}
+                              if item.Type_ = RES_FONT_RESTORE Then
+                                log_Add( 'Unable to restore font: "' + FileName + '"' )
+                              else
+                              {$ENDIF}
                               log_Add( 'Unable to load font: "' + FileName + '"' );
 
                               FileName := '';

+ 115 - 2
src/zgl_textures.pas

@@ -107,6 +107,10 @@ function  tex_Create( var Data : PByteArray; Width, Height : Word; Format : Word
 function  tex_CreateZero( Width, Height : Word; Color : LongWord = $000000; Flags : LongWord = TEX_DEFAULT_2D ) : zglPTexture;
 function  tex_LoadFromFile( const FileName : UTF8String; TransparentColor : LongWord = TEX_NO_COLORKEY; Flags : LongWord = TEX_DEFAULT_2D ) : zglPTexture;
 function  tex_LoadFromMemory( const Memory : zglTMemory; const Extension : UTF8String; TransparentColor : LongWord = TEX_NO_COLORKEY; Flags : LongWord = TEX_DEFAULT_2D ) : zglPTexture;
+{$IFDEF ANDROID}
+procedure tex_RestoreFromFile( var Texture : zglPTexture; const FileName : UTF8String; TransparentColor : LongWord = TEX_NO_COLORKEY; Flags : LongWord = TEX_DEFAULT_2D );
+procedure tex_RestoreFromMemory( var Texture : zglPTexture; const Memory : zglTMemory; const Extension : UTF8String; TransparentColor : LongWord = TEX_NO_COLORKEY; Flags : LongWord = TEX_DEFAULT_2D );
+{$ENDIF}
 procedure tex_SetFrameSize( var Texture : zglPTexture; FrameWidth, FrameHeight : Word );
 procedure tex_SetMask( var Texture : zglPTexture; Mask : zglPTexture );
 procedure tex_CalcTexCoords( var Texture : zglTTexture; FramesX : Integer = 1; FramesY : Integer = 1 );
@@ -345,7 +349,7 @@ begin
       exit;
     end;
 
-  if Format = TEX_FORMAT_RGBA Then
+  if format = TEX_FORMAT_RGBA Then
     begin
       if Flags and TEX_CALCULATE_ALPHA > 0 Then
         begin
@@ -395,7 +399,7 @@ begin
       exit;
     end;
 
-  if Format = TEX_FORMAT_RGBA Then
+  if format = TEX_FORMAT_RGBA Then
     begin
       if Flags and TEX_CALCULATE_ALPHA > 0 Then
         begin
@@ -409,6 +413,115 @@ begin
   FreeMem( pData );
 end;
 
+{$IFDEF ANDROID}
+procedure tex_RestoreFromFile( var Texture : zglPTexture; const FileName : UTF8String; TransparentColor : LongWord = TEX_NO_COLORKEY; Flags : LongWord = TEX_DEFAULT_2D );
+  var
+    i      : Integer;
+    ext    : UTF8String;
+    pData  : PByteArray;
+    w, h   : Word;
+    format : Word;
+    res    : zglTTextureResource;
+begin
+  pData  := nil;
+
+  if ( not resUseThreaded ) and ( not file_Exists( FileName ) ) Then
+    begin
+      Texture.ID := managerZeroTexture.ID;
+      log_Add( 'Cannot read "' + FileName + '"' );
+      exit;
+    end;
+
+  ext := u_StrUp( file_GetExtension( FileName ) );
+  for i := managerTexture.Count.Formats - 1 downto 0 do
+    if ext = managerTexture.Formats[ i ].Extension Then
+      if resUseThreaded Then
+        begin
+          res.FileName         := FileName;
+          res.Texture          := Texture;
+          res.FileLoader       := managerTexture.Formats[ i ].FileLoader;
+          res.TransparentColor := TransparentColor;
+          res.Flags            := Flags;
+          res_AddToQueue( RES_TEXTURE_RESTORE, TRUE, @res );
+          exit;
+        end else
+          managerTexture.Formats[ i ].FileLoader( FileName, pData, w, h, format );
+
+  if not Assigned( pData ) Then
+    begin
+      Texture.ID := managerZeroTexture.ID;
+      log_Add( 'Unable to restore texture: "' + FileName + '"' );
+      exit;
+    end;
+
+  if format = TEX_FORMAT_RGBA Then
+    begin
+      if Flags and TEX_CALCULATE_ALPHA > 0 Then
+        begin
+          tex_CalcTransparent( pData, TransparentColor, w, h );
+          tex_CalcAlpha( pData, w, h );
+        end else
+          tex_CalcTransparent( pData, TransparentColor, w, h );
+    end;
+  Texture.Flags := Flags;
+  tex_CalcFlags( Texture^, pData );
+  tex_CreateGL( Texture^, pData );
+
+  log_Add( 'Texture restored: "' + FileName + '"' );
+
+  FreeMem( pData );
+end;
+
+procedure tex_RestoreFromMemory( var Texture : zglPTexture; const Memory : zglTMemory; const Extension : UTF8String; TransparentColor : LongWord = TEX_NO_COLORKEY; Flags : LongWord = TEX_DEFAULT_2D );
+  var
+    i      : Integer;
+    ext    : UTF8String;
+    pData  : PByteArray;
+    w, h   : Word;
+    format : Word;
+    res    : zglTTextureResource;
+begin
+  pData  := nil;
+
+  ext := u_StrUp( Extension );
+  for i := managerTexture.Count.Formats - 1 downto 0 do
+    if ext = managerTexture.Formats[ i ].Extension Then
+      if resUseThreaded Then
+        begin
+          res.Memory           := Memory;
+          res.Texture          := Texture;
+          res.MemLoader        := managerTexture.Formats[ i ].MemLoader;
+          res.TransparentColor := TransparentColor;
+          res.Flags            := Flags;
+          res_AddToQueue( RES_TEXTURE_RESTORE, FALSE, @res );
+          exit;
+        end else
+          managerTexture.Formats[ i ].MemLoader( Memory, pData, w, h, format );
+
+  if not Assigned( pData ) Then
+    begin
+      Texture.ID := managerZeroTexture.ID;
+      log_Add( 'Unable to restore texture: From Memory' );
+      exit;
+    end;
+
+  if format = TEX_FORMAT_RGBA Then
+    begin
+      if Flags and TEX_CALCULATE_ALPHA > 0 Then
+        begin
+          tex_CalcTransparent( pData, TransparentColor, w, h );
+          tex_CalcAlpha( pData, w, h );
+        end else
+          tex_CalcTransparent( pData, TransparentColor, w, h );
+    end;
+  Texture.Flags := Flags;
+  tex_CalcFlags( Texture^, pData );
+  tex_CreateGL( Texture^, pData );
+
+  FreeMem( pData );
+end;
+{$ENDIF}
+
 procedure tex_SetFrameSize( var Texture : zglPTexture; FrameWidth, FrameHeight : Word );
   var
     res : zglTTextureFrameSizeResource;

+ 20 - 0
src/zgl_video.pas

@@ -87,6 +87,9 @@ function  video_OpenFile( const FileName : UTF8String ) : zglPVideoStream;
 function  video_OpenMemory( const Memory : zglTMemory; const Extension : UTF8String ) : zglPVideoStream;
 procedure video_Update( var Stream : zglPVideoStream; Milliseconds : Double; Loop : Boolean = FALSE );
 procedure video_Seek( var Stream : zglPVideoStream; Milliseconds : Double );
+{$IFDEF ANDROID}
+procedure video_Restore( var Stream : zglPVideoStream );
+{$ENDIF}
 
 var
   managerVideo : zglTVideoManager;
@@ -252,4 +255,21 @@ begin
     end;
 end;
 
+{$IFDEF ANDROID}
+procedure video_Restore( var Stream : zglPVideoStream );
+  var
+    pData : PByteArray;
+    time  : Double;
+begin
+  GetMem( pData, Round( Stream.Texture.Width / Stream.Texture.U ) * Round( Stream.Texture.Height / Stream.Texture.V ) * 4 );
+  FillChar( pData, Round( Stream.Texture.Width / Stream.Texture.U ) * Round( Stream.Texture.Height / Stream.Texture.V ) * 4, 255 );
+  tex_CreateGL( Stream.Texture^, pData );
+  FreeMem( pData );
+
+  time := Stream.Time;
+  video_Seek( Stream, 0 );
+  video_Seek( Stream, time );
+end;
+{$ENDIF}
+
 end.